List icon Conteúdo

Rede

Este guia mostra como trabalhar com a funcionalidade relacionada com a rede, como proxy, eventos de rede, autenticação, TLS, autenticação de certificado de cliente, etc.

A funcionalidade relacionada com a rede pode ser acessada através da instância Network que pode ser obtida da seguinte forma:

Java
Kotlin

var network = profile.network();

val network = profile.network()

Cabeçalho Accept-Language

O JxBrowser permite configurar o valor do cabeçalho HTTP Accept-Language através do método Network.acceptLanguage(String).

Por exemplo, o valor “fr, en-gb;q=0.8, en;q=0.7” significaria: “Prefiro francês, mas aceito inglês britânico e outros tipos de inglês”:

Java
Kotlin

network.acceptLanguage("fr, en-gb;q=0.8, en;q=0.7");

network.acceptLanguage("fr, en-gb;q=0.8, en;q=0.7")

Servidores Whitelist

Whitelist de Autorização do Servidor HTTP

Você pode configurar a lista branca de autorização do servidor HTTP que representa uma string com uma lista de URLs separados por vírgula/semicoluna. Por exemplo:

Java
Kotlin

network.httpAuthPreferences().serverWhitelist("*google.com,*example.com,*baz");

network.httpAuthPreferences()
    .serverWhitelist("*google.com,*example.com,*baz")

Whitelist de Delegados de Rede HTTP

Para configurar a lista branca de delegados de rede HTTP, você pode utilizar a abordagem descrita abaixo:

Java
Kotlin

network.httpAuthPreferences().delegateWhitelist("*google.com,*example.com,*baz");

network.httpAuthPreferences()
    .delegateWhitelist("*google.com,*example.com,*baz")

TLS

Verificação do Certificado

Por padrão, o Chromium verifica todos os certificados SSL obtidos de um servidor Web durante o carregamento da página Web. O JxBrowser permite modificar este comportamento padrão e assumir o controle do processo de verificação.

Para lidar com a verificação de certificados, utilize a chamada de retorno VerifyCertificateCallback. Antes de esta chamada de retorno ser invocada, o Chromium verifica o certificado SSL e fornece os resultados da verificação à chamada de retorno. Com os resultados da verificação, a chamada de retorno recebe o próprio certificado SSL. É possível verificar o certificado SSL fornecido e notificar o motor com os resultados da verificação.

Por exemplo:

Java
Kotlin

network.set(VerifyCertificateCallback.class, (params) -> {
    // Certificado SSL a verificar.
    var certificate = params.certificate();
    // Os resultados da verificação efetuada pelo verificador padrão.
    var verificationErrors = params.verificationErrors();
    // Devem ser utilizados os resultados da verificação padrão.
    return VerifyCertificateCallback.Response.defaultAction();
});

network.register(VerifyCertificateCallback { params ->
    // Certificado SSL a verificar.
    val certificate = params.certificate()
    // Os resultados da verificação efetuada pelo verificador padrão.
    val verificationErrors = params.verificationErrors()
    // Devem ser utilizados os resultados da verificação padrão.
    VerifyCertificateCallback.Response.defaultAction()
})

Autenticação do Certificado do Cliente

O JxBrowser suporta a autenticação utilizando certificados de cliente HTTPS. Para mais informações, consulte o guia Autenticação.

Esquemas

A biblioteca fornece uma API que permite registrar os esquemas personalizados e interceptar requests URL com os esquemas padrão, como HTTP ou HTTPS.

Em ambos os casos, os requests de URL com o esquema correspondente serão interceptados e os dados de resposta serão fornecidos como se fossem enviados por um servidor Web. Utilizando esta funcionalidade, é possível emular a resposta de um servidor remoto e utilizar uma espécie de servidor Web local.

Registrar um Esquema Personalizado

Para registrar um esquema personalizado utilize o método EngineOptions.Builder.addScheme() durante a configuração do Engine. Isso é necessário porque o Chromium registra todos os esquemas durante o inicialização e não permite a modificação de esquemas depois de ter sido inicializado.

O código a seguir demonstra como registrar um esquema personalizado e associar a chamada de retorno InterceptUrlRequestCallback que será invocada sempre que o navegador carregar um recurso por um URL com o esquema fornecido:

Java
Kotlin

InterceptUrlRequestCallback interceptor = params -> {
    var options = UrlRequestJob.Options.newBuilder(HttpStatus.OK)
        .addHttpHeader(HttpHeader.of("Content-Type", "text/plain"))
        .build();
    var job = params.newUrlRequestJob(options);
    job.write("Hello!".getBytes());
    job.complete();
    return InterceptUrlRequestCallback.Response.intercept(job);
};
var options = EngineOptions.newBuilder(renderingMode)
    .addScheme(Scheme.of("jxb"), interceptor)
    .build();
var engine = Engine.newInstance(options);

val interceptor = InterceptUrlRequestCallback { params ->
    val options = UrlRequestJobOptions(
        status = HttpStatus.OK,
        headers = listOf(HttpHeader("Content-Type", "text/plain"))
    )
    val job = params.newUrlRequestJob(options).apply {
        write("Hello!".toByteArray())
        complete()
    }
    InterceptUrlRequestCallback.Response.intercept(job)
}
val engine = Engine(renderingMode) {
    schemes.add(Scheme("jxb"), interceptor)
}

Agora, se você carregar jxb://anyhost/anypage.html, os requests de URL serão interceptados e a chamada de retorno associada será invocada. Você obterá o seguinte resultado:

Esquema personalizado

Interceptação de Requests HTTP/HTTPS

A mesma abordagem com o registro de um esquema personalizado pode ser utilizada para interceptar os esquemas padrão, como HTTP ou HTTPS. Neste caso, é necessário adicionar o esquema correspondente, como indicado abaixo:

Java
Kotlin

InterceptUrlRequestCallback interceptor = params -> {
    var jobOptions = UrlRequestJob.Options.newBuilder(HttpStatus.OK)
        .addHttpHeader(HttpHeader.of("Content-Type", "text/plain"))
        .build();
    var job = params.newUrlRequestJob(jobOptions);
    ...
    return InterceptUrlRequestCallback.Response.intercept(job);
};
var options = EngineOptions.newBuilder(renderingMode)
    .addScheme(Scheme.HTTPS, interceptor)
    .build();

val interceptor = InterceptUrlRequestCallback { params ->
    val options = UrlRequestJobOptions(
        status = HttpStatus.OK,
        headers = listOf(HttpHeader("Content-Type", "text/plain"))
    )
    val job = params.newUrlRequestJob(options)
    ...
    InterceptUrlRequestCallback.Response.intercept(job)
}
val engine = Engine(renderingMode) {
    schemes.add(Scheme.HTTPS, interceptor)
}

Eventos de Rede e Chamadas de Retorno

A API Network define um conjunto de eventos e chamadas de retorno que seguem o ciclo de vida de um request Web. Você pode utilizar estes eventos para observar e analisar o tráfego. As chamadas de retorno lhe permitirão interceptar, bloquear ou modificar requests.

O ciclo de vida dos eventos de requests bem sucedidos é o seguinte: Fluxo de eventos de rede

Antes do Request de URL

A chamada de retorno BeforeUrlRequestCallback é invocada quando uma solicitação HTTP está prestes a ocorrer. Você pode utilizar esta chamada de retorno para redirecionar o request para outra localização. Por exemplo:

Java
Kotlin

network.set(BeforeUrlRequestCallback.class, (params) ->
    BeforeUrlRequestCallback.Response.redirect("<new-url>"));

network.register(BeforeUrlRequestCallback {
    BeforeUrlRequestCallback.Response.redirect("<new-url>")
})

Antes do Upload de Dados

A chamada de retorno BeforeSendUploadDataCallback é invocada antes dos dados de upload serem enviados para um servidor Web. Aqui você pode sobrescrever os dados de upload. Por exemplo:

Java
Kotlin

network.set(BeforeSendUploadDataCallback.class, (params) ->
    BeforeSendUploadDataCallback.Response.override(TextData.of("<text-data>")));

network.register(BeforeSendUploadDataCallback {
    val newData = TextData("<text-data>")
    BeforeSendUploadDataCallback.Response.override(newData)
})

Esta chamada de retorno não será chamada se o request não tiver os dados de upload.

São suportados os seguintes tipos de UploadData:

  • BytesData representa uma sequência de bytes, o tipo de conteúdo é configurável.
  • TextData os dados do tipo de conteúdo text/plain.
  • FormData os dados do tipo de conteúdo application/x-www-form-urlencoded.
  • MultipartFormData os dados do tipo de conteúdo multipart/form-data.

Antes de Iniciar a Transação

A chamada de retorno BeforeStartTransactionCallback é invocada antes do início da transação de rede. Nesta chamada de retorno, você pode adicionar ou substituir os cabeçalhos HTTP antes de serem enviados. Por exemplo:

Java
Kotlin

network.set(BeforeStartTransactionCallback.class, (params) -> {
    var httpHeaders = new ArrayList<>(params.httpHeaders());
    httpHeaders.add(HttpHeader.of("<header-name>", "<header-value>"));
    return BeforeStartTransactionCallback.Response.override(httpHeaders);
});

network.register(BeforeStartTransactionCallback { params ->
    val customHeader = HttpHeader("<header-name>", "<header-value>")
    val httpHeaders = params.httpHeaders() + customHeader
    BeforeStartTransactionCallback.Response.override(httpHeaders)
})

Esta chamada de retorno não capta os seguintes cabeçalhos. Esta lista está sujeita a alterações e pode não estar completa:

  • Authorization
  • Cache-Control
  • Connection
  • Content-Length
  • Host
  • If-Modified-Since
  • If-None-Match
  • If-Range
  • Partial-Data
  • Pragma
  • Proxy-Authorization
  • Proxy-Connection
  • Transfer-Encoding

Receber Cabeçalhos

A chamada de retorno ReceiveHeadersCallback é invocada para requests HTTP quando os cabeçalhos são recebidos. Aqui você pode adicionar, modificar ou remover os cabeçalhos HTTP recebidos através da rede. Por exemplo:

Java
Kotlin

network.set(ReceiveHeadersCallback.class, (params) -> {
    var httpHeaders = new ArrayList<>(params.httpHeaders());
    httpHeaders.add(HttpHeader.of("<header-name>", "<header-value>"));
    return ReceiveHeadersCallback.Response.override(httpHeaders);
});

network.register(ReceiveHeadersCallback { params ->
    val customHeader = HttpHeader("<header-name>", "<header-value>")
    val httpHeaders = params.httpHeaders() + customHeader
    ReceiveHeadersCallback.Response.override(httpHeaders)
})

Código de Resposta de Redirecionamento Recebido

O evento RedirectResponseCodeReceived é disparado quando um código de resposta de redirecionamento 3xx é recebido para o request. Neste evento, você pode obter os detalhes sobre o redirecionamento, como o novo URL e o código de resposta. Por exemplo:

Java
Kotlin

network.on(RedirectResponseCodeReceived.class, (event) -> {
    var newUrl = event.newUrl();
    var responseCode = event.responseCode();
});

network.subscribe<RedirectResponseCodeReceived> { event ->
    val newUrl = event.newUrl()
    val responseCode = event.responseCode()
}

Resposta Iniciada

O evento ResponseStarted é disparado quando o primeiro byte do corpo da resposta do URL é recebido. Para os pedidos HTTP, isto significa que a linha de estado e os cabeçalhos de resposta estão disponíveis. Neste evento, é possível acessar o request correspondente e o código de resposta. Por exemplo:

Java
Kotlin

network.on(ResponseStarted.class, (event) -> {
    var urlRequest = event.urlRequest();
    var responseCode = event.responseCode();
});

network.subscribe<ResponseStarted> { event ->
    val urlRequest = event.urlRequest()
    val responseCode = event.responseCode()
}

Request Concluído

O evento RequestCompleted é disparado quando o request de URL foi concluído com sucesso ou falhou. Neste evento, é possível verificar se o request foi iniciado, obter os detalhes do estado do request e acessar o código de resposta. Por exemplo:

Java
Kotlin

network.on(RequestCompleted.class, (event) -> {
    var urlRequest = event.urlRequest();
    // Os detalhes do estado do request de URL.
    var urlRequestStatus = event.status();
    // O código de resposta HTTP.
    var responseCode = event.responseCode();
});

network.subscribe<RequestCompleted> { event ->
    val urlRequest = event.urlRequest()
    // Os detalhes do estado do request de URL.
    val urlRequestStatus = event.status()
    // O código de resposta HTTP.
    val responseCode = event.responseCode()
}

Request Destruído

O evento RequestDestroyed é disparado quando o request é destruído e não pode mais ser utilizado. Para acessar os detalhes do request destruído, utilize o seguinte código:

Java
Kotlin

network.on(RequestDestroyed.class, (event) -> {
    var urlRequest = event.urlRequest();
});

network.subscribe<RequestDestroyed> { event ->
    val urlRequest = event.urlRequest()
}

Bytes de Resposta Recebidos

O evento ResponseBytesReceived é disparado quando uma parte do corpo da resposta HTTP é recebida através da rede. Ele permite acessar os bytes do corpo da resposta HTTP:

Java
Kotlin

network.on(ResponseBytesReceived.class, event -> {
    var data = event.data();
});

network.subscribe<ResponseBytesReceived> { event ->
    val data = event.data()
}

As partes do corpo da resposta podem ser apresentadas numa ordem aleatória. Tenha isso em mente ao restaurar a resposta completa usando este evento.

Estado da Conexão

O Chromium monitora o estado da conexão à Internet. Quando a conexão é interrompida e depois restaurada, o Chromium detecta a alteração e volta a carregar a página Web atualmente carregada. Você pode obter as notificações correspondentes utilizando a seguinte API:

Java
Kotlin

network.on(NetworkChanged.class, e -> {
    // Se o tipo de conexão for TYPE_NONE, não existe qualquer conexão.
    if (e.connectionType() == ConnectionType.TYPE_NONE) {
        // A conexão de rede foi interrompida. Estamos offline.
    } else {
        // A conexão de rede foi restabelecida.
    }
});

network.subscribe<NetworkChanged> { event ->
    // Se o tipo de conexão for TYPE_NONE, não existe qualquer conexão.
    if (event.connectionType() == ConnectionType.TYPE_NONE) {
        // A conexão de rede foi interrompida. Estamos offline.
    } else {
        // A conexão de rede foi restabelecida.
    }
}