use of io.netty.handler.codec.http.HttpVersion in project vert.x by eclipse.
the class HttpServerImpl method listen.
public synchronized HttpServer listen(int port, String host, Handler<AsyncResult<HttpServer>> listenHandler) {
if (requestStream.handler() == null && wsStream.handler() == null) {
throw new IllegalStateException("Set request or websocket handler first");
}
if (listening) {
throw new IllegalStateException("Already listening");
}
listenContext = vertx.getOrCreateContext();
listening = true;
serverOrigin = (options.isSsl() ? "https" : "http") + "://" + host + ":" + port;
List<HttpVersion> applicationProtocols = options.getAlpnVersions();
if (listenContext.isWorkerContext()) {
applicationProtocols = applicationProtocols.stream().filter(v -> v != HttpVersion.HTTP_2).collect(Collectors.toList());
}
sslHelper.setApplicationProtocols(applicationProtocols);
synchronized (vertx.sharedHttpServers()) {
// Will be updated on bind for a wildcard port
this.actualPort = port;
id = new ServerID(port, host);
HttpServerImpl shared = vertx.sharedHttpServers().get(id);
if (shared == null || port == 0) {
serverChannelGroup = new DefaultChannelGroup("vertx-acceptor-channels", GlobalEventExecutor.INSTANCE);
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(vertx.getAcceptorEventLoopGroup(), availableWorkers);
bootstrap.channel(NioServerSocketChannel.class);
applyConnectionOptions(bootstrap);
sslHelper.validate(vertx);
bootstrap.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
if (requestStream.isPaused() || wsStream.isPaused()) {
ch.close();
return;
}
ChannelPipeline pipeline = ch.pipeline();
if (sslHelper.isSSL()) {
pipeline.addLast("ssl", sslHelper.createSslHandler(vertx));
if (options.isUseAlpn()) {
pipeline.addLast("alpn", new ApplicationProtocolNegotiationHandler("http/1.1") {
@Override
protected void configurePipeline(ChannelHandlerContext ctx, String protocol) throws Exception {
if (protocol.equals("http/1.1")) {
configureHttp1(pipeline);
} else {
handleHttp2(ch);
}
}
});
} else {
configureHttp1(pipeline);
}
} else {
if (DISABLE_HC2) {
configureHttp1(pipeline);
} else {
pipeline.addLast(new Http1xOrHttp2Handler());
}
}
}
});
addHandlers(this, listenContext);
try {
bindFuture = AsyncResolveConnectHelper.doBind(vertx, port, host, bootstrap);
bindFuture.addListener(res -> {
if (res.failed()) {
vertx.sharedHttpServers().remove(id);
} else {
Channel serverChannel = res.result();
HttpServerImpl.this.actualPort = ((InetSocketAddress) serverChannel.localAddress()).getPort();
serverChannelGroup.add(serverChannel);
metrics = vertx.metricsSPI().createMetrics(this, new SocketAddressImpl(port, host), options);
}
});
} catch (final Throwable t) {
// Make sure we send the exception back through the handler (if any)
if (listenHandler != null) {
vertx.runOnContext(v -> listenHandler.handle(Future.failedFuture(t)));
} else {
// No handler - log so user can see failure
log.error(t);
}
listening = false;
return this;
}
vertx.sharedHttpServers().put(id, this);
actualServer = this;
} else {
// Server already exists with that host/port - we will use that
actualServer = shared;
this.actualPort = shared.actualPort;
addHandlers(actualServer, listenContext);
metrics = vertx.metricsSPI().createMetrics(this, new SocketAddressImpl(port, host), options);
}
actualServer.bindFuture.addListener(future -> {
if (listenHandler != null) {
final AsyncResult<HttpServer> res;
if (future.succeeded()) {
res = Future.succeededFuture(HttpServerImpl.this);
} else {
res = Future.failedFuture(future.cause());
listening = false;
}
listenContext.runOnContext((v) -> listenHandler.handle(res));
} else if (future.failed()) {
listening = false;
log.error(future.cause());
}
});
}
return this;
}
use of io.netty.handler.codec.http.HttpVersion in project xipki by xipki.
the class HttpOcspServlet method servicePost.
private FullHttpResponse servicePost(FullHttpRequest request, ServletURI servletUri, SSLSession sslSession, SslReverseProxyMode sslReverseProxyMode) throws Exception {
HttpVersion version = request.protocolVersion();
ResponderAndPath responderAndPath = server.getResponderForPath(servletUri.getPath());
if (responderAndPath == null) {
return createErrorResponse(version, HttpResponseStatus.NOT_FOUND);
}
try {
// accept only "application/ocsp-request" as content type
String reqContentType = request.headers().get("Content-Type");
if (!CT_REQUEST.equalsIgnoreCase(reqContentType)) {
return createErrorResponse(version, HttpResponseStatus.UNSUPPORTED_MEDIA_TYPE);
}
Responder responder = responderAndPath.getResponder();
int contentLen = request.content().readableBytes();
// request too long
if (contentLen > responder.getMaxRequestSize()) {
return createErrorResponse(version, HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE);
}
OcspRespWithCacheInfo ocspRespWithCacheInfo = server.answer(responder, readContent(request), false);
if (ocspRespWithCacheInfo == null || ocspRespWithCacheInfo.getResponse() == null) {
LOG.error("processRequest returned null, this should not happen");
return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
}
byte[] encodedOcspResp = ocspRespWithCacheInfo.getResponse();
return createOKResponse(version, CT_RESPONSE, encodedOcspResp);
} catch (Throwable th) {
if (th instanceof EOFException) {
LogUtil.warn(LOG, th, "Connection reset by peer");
} else {
LOG.error("Throwable thrown, this should not happen!", th);
}
return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
}
// end external try
}
use of io.netty.handler.codec.http.HttpVersion in project xipki by xipki.
the class HttpOcspServlet method serviceGet.
// method servicePost
private FullHttpResponse serviceGet(FullHttpRequest request, ServletURI servletUri, SSLSession sslSession, SslReverseProxyMode sslReverseProxyMode) throws Exception {
HttpVersion version = request.protocolVersion();
ResponderAndPath responderAndPath = server.getResponderForPath(servletUri.getPath());
if (responderAndPath == null) {
return createErrorResponse(version, HttpResponseStatus.NOT_FOUND);
}
String path = servletUri.getPath();
String servletPath = responderAndPath.getServletPath();
Responder responder = responderAndPath.getResponder();
if (!responder.supportsHttpGet()) {
return createErrorResponse(version, HttpResponseStatus.METHOD_NOT_ALLOWED);
}
String b64OcspReq;
int offset = servletPath.length();
// GET URI contains the request and must be much longer than 10.
if (path.length() - offset > 10) {
if (path.charAt(offset) == '/') {
offset++;
}
b64OcspReq = servletUri.getPath().substring(offset);
} else {
return createErrorResponse(version, HttpResponseStatus.BAD_REQUEST);
}
try {
// POST, we support GET for longer requests anyway.
if (b64OcspReq.length() > responder.getMaxRequestSize()) {
return createErrorResponse(version, HttpResponseStatus.REQUEST_ENTITY_TOO_LARGE);
}
OcspRespWithCacheInfo ocspRespWithCacheInfo = server.answer(responder, Base64.decode(b64OcspReq), true);
if (ocspRespWithCacheInfo == null || ocspRespWithCacheInfo.getResponse() == null) {
return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
}
byte[] encodedOcspResp = ocspRespWithCacheInfo.getResponse();
FullHttpResponse response = createOKResponse(version, CT_RESPONSE, encodedOcspResp);
OcspRespWithCacheInfo.ResponseCacheInfo cacheInfo = ocspRespWithCacheInfo.getCacheInfo();
if (cacheInfo != null) {
encodedOcspResp = ocspRespWithCacheInfo.getResponse();
HttpHeaders headers = response.headers();
// RFC 5019 6.2: Date: The date and time at which the OCSP server generated
// the HTTP response.
headers.add("Date", new Date());
// RFC 5019 6.2: Last-Modified: date and time at which the OCSP responder
// last modified the response.
headers.add("Last-Modified", new Date(cacheInfo.getThisUpdate()));
// This is overridden by max-age on HTTP/1.1 compatible components
if (cacheInfo.getNextUpdate() != null) {
headers.add("Expires", new Date(cacheInfo.getNextUpdate()));
}
// RFC 5019 6.2: This profile RECOMMENDS that the ETag value be the ASCII
// HEX representation of the SHA1 hash of the OCSPResponse structure.
headers.add("ETag", StringUtil.concat("\\", HashAlgo.SHA1.hexHash(encodedOcspResp), "\\"));
// Max age must be in seconds in the cache-control header
long maxAge;
if (responder.getCacheMaxAge() != null) {
maxAge = responder.getCacheMaxAge().longValue();
} else {
maxAge = DFLT_CACHE_MAX_AGE;
}
if (cacheInfo.getNextUpdate() != null) {
maxAge = Math.min(maxAge, (cacheInfo.getNextUpdate() - cacheInfo.getThisUpdate()) / 1000);
}
headers.add("Cache-Control", StringUtil.concat("max-age=", Long.toString(maxAge), ",public,no-transform,must-revalidate"));
}
return response;
} catch (Throwable th) {
if (th instanceof EOFException) {
LogUtil.warn(LOG, th, "Connection reset by peer");
} else {
LOG.error("Throwable thrown, this should not happen!", th);
}
return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
}
// end external try
}
use of io.netty.handler.codec.http.HttpVersion in project xipki by xipki.
the class HealthCheckServlet method service0.
private FullHttpResponse service0(FullHttpRequest request, ServletURI servletUri, SSLSession sslSession) {
HttpVersion version = request.protocolVersion();
HttpMethod method = request.method();
if (method != HttpMethod.GET) {
return createErrorResponse(version, HttpResponseStatus.METHOD_NOT_ALLOWED);
}
try {
if (server == null) {
LOG.error("server in servlet not configured");
return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
}
ResponderAndPath responderAndPath = server.getResponderForPath(servletUri.getPath());
if (responderAndPath == null) {
return createErrorResponse(version, HttpResponseStatus.NOT_FOUND);
}
HealthCheckResult healthResult = server.healthCheck(responderAndPath.getResponder());
HttpResponseStatus status = healthResult.isHealthy() ? HttpResponseStatus.OK : HttpResponseStatus.INTERNAL_SERVER_ERROR;
byte[] respBytes = healthResult.toJsonMessage(true).getBytes();
return createResponse(version, status, HealthCheckServlet.CT_RESPONSE, respBytes);
} catch (Throwable th) {
if (th instanceof EOFException) {
LogUtil.warn(LOG, th, "connection reset by peer");
} else {
LOG.error("Throwable thrown, this should not happen", th);
}
return createErrorResponse(version, HttpResponseStatus.INTERNAL_SERVER_ERROR);
}
}
use of io.netty.handler.codec.http.HttpVersion in project netty by netty.
the class SpdyHttpDecoder method createHttpResponse.
private static FullHttpResponse createHttpResponse(SpdyHeadersFrame responseFrame, ByteBufAllocator alloc, boolean validateHeaders) throws Exception {
// Create the first line of the response from the name/value pairs
SpdyHeaders headers = responseFrame.headers();
HttpResponseStatus status = HttpResponseStatus.parseLine(headers.get(STATUS));
HttpVersion version = HttpVersion.valueOf(headers.getAsString(VERSION));
headers.remove(STATUS);
headers.remove(VERSION);
boolean release = true;
ByteBuf buffer = alloc.buffer();
try {
FullHttpResponse res = new DefaultFullHttpResponse(version, status, buffer, validateHeaders);
for (Map.Entry<CharSequence, CharSequence> e : responseFrame.headers()) {
res.headers().add(e.getKey(), e.getValue());
}
// The Connection and Keep-Alive headers are no longer valid
HttpUtil.setKeepAlive(res, true);
// Transfer-Encoding header is not valid
res.headers().remove(HttpHeaderNames.TRANSFER_ENCODING);
res.headers().remove(HttpHeaderNames.TRAILER);
release = false;
return res;
} finally {
if (release) {
buffer.release();
}
}
}
Aggregations