Ajuda com teste do HTTP 1.1
Estou fazendo um driver para o HTTP 1.1, para sanar alguns problemas de performance que estou tendo com o TotalCross.
Peguei minha antiga biblioteca de abstração do HttpStream
, a tc-http-conn
e estou convertendo-a para usar HTTP 1.1. Meu foco maior era conseguir aproveitar conexões TCP entre diversas requisições HTTP, já que agora eu posso enviar o Connection: keep-alive
. Para conseguir isso, precisei reimplementar o protocolo HTTP, já que o que o TotalCross fornecia através do HttpStream
não era prático (para mim) adaptar.
Então, implementei uma parte do protocolo HTTP 1.1 num branch, tc-http-conn/develop
para tal fim (o original tc-http-conn/http-request
já foi colabado). A ideia principal é:
- você começa com um
ConnPool
, que vai gerenciar suas conexões - você cria um
HttpRequest
, normalmente através de umHttpRequestBuilder
- você envia o
HttpRequest
para oConnPool
junto com uma função que trate a resposta (Consumer<HttpResponse>
) - quando você cansar de enviar requisições, você manda tratar as requisições
- voltar ao passo 2 ou terminar
Por exemplo:
public static void t() throws IOException, SQLException {
Url url = new Url("http://httpbin.org/deflate");
Url url2 = new Url("http://httpbin.org/gzip");
Url url3 = new Url("http://www.google.com/search?q=teste");
HttpRequestBuilder builder = new HttpRequestBuilder();
builder.setUrl(url);
builder.setMethod(HttpMethod.GET);
builder.addHeader("Accept", "application/json");
System.out.println("teste:\n\n\n\n" + builder.build().serialize());
ConnPool connPool = new ConnPool();
connPool.sendRequest(builder.build(), M::printResponse);
builder.setUrl(url2);
connPool.sendRequest(builder.build(), M::printResponse);
builder.setUrl(url3);
connPool.sendRequest(builder.build(), M::printResponse);
if (connPool.hasUntreatedResponse()) {
connPool.treatNextResponse();
}
}
private static void printResponse(HttpResponse response) {
try {
System.out.println("codigo " + response.getStatusCode());
new Stream<>(response.getResponseHeaders()).map(Pair::toString).forEach(System.out::println);
IOUtils.copyLarge(response.getResponseBody(), System.out);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Seria muito interessante aumentar o escopo dos meus testes, assim como também é interessante para clientes do TotalCross ter acesso às facilidades desse protocolo.
Atualmente, não me preocupei (ainda) com o envio de dados, nem com a otimização doExpect: 100-continue
, apesar de estar nos meus intuitos colaborar com isso. Com alguma adaptação, é possível transformar a requisição em um web-socket, mas não cheguei a testar se é possível.
A biblioteca não foi feita para ser thread-safe, então não recomendo usá-la com múltiplas threads no mesmo ConnPool
(ConnPool
s distintos devem estar isolados uns dos outros e ser seguro, entretanto).
Para fazer o deploy
no TotalCross, essa biblioteca depende fortemente do totalcross-functional-toolbox
, que por sua vez depende do default-functional-toolbox-is-serializable
. Se estiver usando o tc-compiler-help
, basta por a seguinte condição para compilar essas bibliotecas:
.setMustCompile((p) -> {
if (p.matches("^.*softsite.*$") && !p.matches("^.*tc-compiler-help.*$")) {
return true;
}
return false;
})
A propósito, o
totalcross-functional-toolbox
é usado para dar suporte à Java 8Stream
, vide #184 (closed).