use of io.netty.handler.codec.http2.DefaultHttp2Headers in project vert.x by eclipse.
the class Http2ServerTest method testURI.
@Test
public void testURI() throws Exception {
server.requestHandler(req -> {
assertEquals("/some/path", req.path());
assertEquals("foo=foo_value&bar=bar_value_1&bar=bar_value_2", req.query());
assertEquals("/some/path?foo=foo_value&bar=bar_value_1&bar=bar_value_2", req.uri());
assertEquals("http://whatever.com/some/path?foo=foo_value&bar=bar_value_1&bar=bar_value_2", req.absoluteURI());
assertEquals("/some/path?foo=foo_value&bar=bar_value_1&bar=bar_value_2", req.getHeader(":path"));
assertEquals("whatever.com", req.host());
MultiMap params = req.params();
Set<String> names = params.names();
assertEquals(2, names.size());
assertTrue(names.contains("foo"));
assertTrue(names.contains("bar"));
assertEquals("foo_value", params.get("foo"));
assertEquals(Collections.singletonList("foo_value"), params.getAll("foo"));
assertEquals("bar_value_2", params.get("bar"));
assertEquals(Arrays.asList("bar_value_1", "bar_value_2"), params.getAll("bar"));
testComplete();
});
startServer();
TestClient client = new TestClient();
ChannelFuture fut = client.connect(DEFAULT_HTTPS_PORT, DEFAULT_HTTPS_HOST, request -> {
int id = request.nextStreamId();
Http2Headers headers = new DefaultHttp2Headers().method("GET").scheme("http").authority("whatever.com").path("/some/path?foo=foo_value&bar=bar_value_1&bar=bar_value_2");
request.encoder.writeHeaders(request.context, id, headers, 0, true, request.context.newPromise());
request.context.flush();
});
fut.sync();
await();
}
use of io.netty.handler.codec.http2.DefaultHttp2Headers in project jersey by jersey.
the class NettyHttp2ResponseWriter method writeResponseStatusAndHeaders.
@Override
public OutputStream writeResponseStatusAndHeaders(long contentLength, ContainerResponse responseContext) throws ContainerException {
String reasonPhrase = responseContext.getStatusInfo().getReasonPhrase();
int statusCode = responseContext.getStatus();
HttpResponseStatus status = reasonPhrase == null ? HttpResponseStatus.valueOf(statusCode) : new HttpResponseStatus(statusCode, reasonPhrase);
DefaultHttp2Headers response = new DefaultHttp2Headers();
response.status(Integer.toString(responseContext.getStatus()));
for (final Map.Entry<String, List<String>> e : responseContext.getStringHeaders().entrySet()) {
response.add(e.getKey().toLowerCase(), e.getValue());
}
response.set(HttpHeaderNames.CONTENT_LENGTH, Long.toString(contentLength));
ctx.writeAndFlush(new DefaultHttp2HeadersFrame(response));
if (!headersFrame.headers().method().equals(HttpMethod.HEAD.asciiName()) && (contentLength > 0 || contentLength == -1)) {
return new OutputStream() {
@Override
public void write(int b) throws IOException {
write(new byte[] { (byte) b });
}
@Override
public void write(byte[] b) throws IOException {
write(b, 0, b.length);
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
ByteBuf buffer = ctx.alloc().buffer(len);
buffer.writeBytes(b, off, len);
ctx.writeAndFlush(new DefaultHttp2DataFrame(buffer, false));
}
@Override
public void flush() throws IOException {
ctx.flush();
}
@Override
public void close() throws IOException {
ctx.write(new DefaultHttp2DataFrame(true)).addListener(NettyResponseWriter.FLUSH_FUTURE);
}
};
} else {
ctx.writeAndFlush(new DefaultHttp2DataFrame(true));
return null;
}
}
use of io.netty.handler.codec.http2.DefaultHttp2Headers in project vert.x by eclipse.
the class Http2ClientTest method testConnectionDecodeError.
@Test
public void testConnectionDecodeError() throws Exception {
waitFor(3);
ServerBootstrap bootstrap = createH2Server((dec, enc) -> new Http2EventAdapter() {
@Override
public void onHeadersRead(ChannelHandlerContext ctx, int streamId, Http2Headers headers, int streamDependency, short weight, boolean exclusive, int padding, boolean endStream) throws Http2Exception {
enc.writeHeaders(ctx, streamId, new DefaultHttp2Headers().status("200"), 0, false, ctx.newPromise());
enc.frameWriter().writeRstStream(ctx, 10, 0, ctx.newPromise());
ctx.flush();
}
});
ChannelFuture s = bootstrap.bind(DEFAULT_HTTPS_HOST, DEFAULT_HTTPS_PORT).sync();
try {
Context ctx = vertx.getOrCreateContext();
ctx.runOnContext(v -> {
client.get(DEFAULT_HTTPS_PORT, DEFAULT_HTTPS_HOST, "/somepath", resp -> {
resp.exceptionHandler(err -> {
assertOnIOContext(ctx);
if (err instanceof Http2Exception) {
complete();
}
});
}).connectionHandler(conn -> {
conn.exceptionHandler(err -> {
assertSame(ctx, Vertx.currentContext());
if (err instanceof Http2Exception) {
complete();
}
});
}).exceptionHandler(err -> {
assertOnIOContext(ctx);
if (err instanceof Http2Exception) {
complete();
}
}).sendHead();
});
await();
} finally {
s.channel().close().sync();
}
}
use of io.netty.handler.codec.http2.DefaultHttp2Headers in project vert.x by eclipse.
the class Http2ServerConnection method sendPush.
synchronized void sendPush(int streamId, String host, HttpMethod method, MultiMap headers, String path, Handler<AsyncResult<HttpServerResponse>> completionHandler) {
Http2Headers headers_ = new DefaultHttp2Headers();
if (method == HttpMethod.OTHER) {
throw new IllegalArgumentException("Cannot push HttpMethod.OTHER");
} else {
headers_.method(method.name());
}
headers_.path(path);
headers_.scheme(isSsl() ? "https" : "http");
if (host != null) {
headers_.authority(host);
}
if (headers != null) {
headers.forEach(header -> headers_.add(header.getKey(), header.getValue()));
}
handler.writePushPromise(streamId, headers_, new Handler<AsyncResult<Integer>>() {
@Override
public void handle(AsyncResult<Integer> ar) {
if (ar.succeeded()) {
synchronized (Http2ServerConnection.this) {
int promisedStreamId = ar.result();
String contentEncoding = HttpUtils.determineContentEncoding(headers_);
Http2Stream promisedStream = handler.connection().stream(promisedStreamId);
boolean writable = handler.encoder().flowController().isWritable(promisedStream);
Push push = new Push(promisedStream, contentEncoding, method, path, writable, completionHandler);
streams.put(promisedStreamId, push);
if (maxConcurrentStreams == null || concurrentStreams < maxConcurrentStreams) {
concurrentStreams++;
context.executeFromIO(push::complete);
} else {
pendingPushes.add(push);
}
}
} else {
context.executeFromIO(() -> {
completionHandler.handle(Future.failedFuture(ar.cause()));
});
}
}
});
}
use of io.netty.handler.codec.http2.DefaultHttp2Headers in project rest.li by linkedin.
the class NettyRequestAdapter method toHttp2Headers.
/**
* Extracts fields from a {@link Request} and construct a {@link Http2Headers} instance.
*
* @param request StreamRequest to extract fields from
* @return a new instance of Http2Headers
* @throws Exception
*/
static <R extends Request> Http2Headers toHttp2Headers(R request) throws Exception {
URI uri = request.getURI();
URL url = new URL(uri.toString());
String method = request.getMethod();
String authority = url.getAuthority();
String path = url.getFile();
String scheme = uri.getScheme();
// RFC 2616, section 5.1.2:
// Note that the absolute path cannot be empty; if none is present in the original URI,
// it MUST be given as "/" (the server root).
path = path.isEmpty() ? "/" : path;
final Http2Headers headers = new DefaultHttp2Headers().method(method).authority(authority).path(path).scheme(scheme);
for (Map.Entry<String, String> entry : request.getHeaders().entrySet()) {
// Ignores HTTP/2 blacklisted headers
if (HEADER_BLACKLIST.contains(entry.getKey().toLowerCase())) {
continue;
}
// RFC 7540, section 8.1.2:
// ... header field names MUST be converted to lowercase prior to their
// encoding in HTTP/2. A request or response containing uppercase
// header field names MUST be treated as malformed (Section 8.1.2.6).
String name = entry.getKey().toLowerCase();
String value = entry.getValue();
headers.set(name, value);
}
// Split up cookies to allow for better header compression
headers.set(HttpHeaderNames.COOKIE, request.getCookies());
return headers;
}
Aggregations