private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) throws Exception { // Handle a bad request. if (!req.getDecoderResult().isSuccess()) { sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST)); req.release(); return; } // Allow only GET methods. if (req.getMethod() != GET) { sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN)); req.release(); return; } // Handshake WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory( getWebSocketLocation(req), null, false, Integer.MAX_VALUE); handshaker = wsFactory.newHandshaker(req); if (handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel()); } else { handshaker.handshake(ctx.channel(), req); } req.release(); }
@Override protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { FullHttpRequest req = (FullHttpRequest) msg; String upgrade = req.headers().get(HttpHeaders.Names.UPGRADE); if (HttpHeaders.Values.WEBSOCKET.equalsIgnoreCase(upgrade)) { WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(req.getUri(), null, false); WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(req); if (handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel()); } else { ChannelFuture future = handshaker.handshake(ctx.channel(), req); future.addListener( f -> { this.configurator.switchToWebSockets(ctx.pipeline()); }); } } else { ReferenceCountUtil.retain(msg); this.configurator.switchToPlainHttp(ctx.pipeline()); ChannelHandlerContext agg = ctx.pipeline().context(HttpObjectAggregator.class); agg.fireChannelRead(msg); } }
private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception { // Allow only GET methods. if (req.getMethod() != GET) { sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN)); return; } // Handshake WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(this.getWebSocketLocation(req), null, false); this.handshaker = wsFactory.newHandshaker(ctx, req); if (this.handshaker == null) { wsFactory.sendUnsupportedWebSocketVersionResponse(ctx); } else { this.handshaker.performOpeningHandshake(ctx, req); } }
private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) { // Handle a bad request. if (!req.getDecoderResult().isSuccess()) { sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, BAD_REQUEST)); return; } // Allow only GET methods. if (req.getMethod() != GET) { sendHttpResponse(ctx, req, new DefaultFullHttpResponse(HTTP_1_1, FORBIDDEN)); return; } // Send the demo page and favicon.ico if ("/".equals(req.getUri())) { ByteBuf content = WebSocketServerIndexPage.getContent(getWebSocketLocation(req)); FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, OK, content); res.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8"); HttpHeaders.setContentLength(res, content.readableBytes()); sendHttpResponse(ctx, req, res); return; } if ("/favicon.ico".equals(req.getUri())) { FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, NOT_FOUND); sendHttpResponse(ctx, req, res); return; } // Handshake WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(getWebSocketLocation(req), null, true); handshaker = wsFactory.newHandshaker(req); if (handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); } else { handshaker.handshake(ctx.channel(), req); } }
private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) { if (!req.getDecoderResult().isSuccess() || (!"websocket".equals(req.headers().get("Upgrade")))) { sendHttpResponse( ctx, req, new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST)); return; } WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory("ws://localhost:7397/websocket", null, false); handshaker = wsFactory.newHandshaker(req); if (handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel()); } else { handshaker.handshake(ctx.channel(), req); } }
private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest request) { // Handle a bad request. if (!request.getDecoderResult().isSuccess()) { sendHttpResponse( ctx, request, new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.BAD_REQUEST)); return; } if (RouterHits.checkIfMappingExit(request)) { // Do Router Mapping First RouterHits.execute(ctx, request); return; } if ("/websocket".equals(request.getUri())) { // Handshake WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(getWebSocketLocation(request), null, true); handshaker = wsFactory.newHandshaker(request); if (handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); } else { handshaker.handshake(ctx.channel(), request); channels.add(ctx.channel()); } return; } final String uri = request.getUri(); // System.out.println("uri: " + uri); final String path = sanitizeUri("www", uri); // System.out.println("path: " + path); if (path == null) { sendHttpResponse( ctx, request, new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.FORBIDDEN)); return; } File file = new File(path); if (file.isHidden() || !file.exists()) { sendHttpResponse( ctx, request, new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.NOT_FOUND)); return; } if (file.isDirectory()) { if (uri.endsWith("/")) { File checkIndexFile = new File(file.getAbsolutePath() + File.separator + "index.html"); System.out.println(checkIndexFile.exists()); if (checkIndexFile.exists()) { file = checkIndexFile; } else { sendListing(ctx, file); return; } } else { sendRedirect(ctx, uri + '/'); } } if (!file.isFile()) { sendHttpResponse( ctx, request, new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.FORBIDDEN)); return; } // Cache Validation String ifModifiedSince = request.headers().get(IF_MODIFIED_SINCE); if (ifModifiedSince != null && !ifModifiedSince.isEmpty()) { SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT, Locale.US); Date ifModifiedSinceDate = null; try { ifModifiedSinceDate = dateFormatter.parse(ifModifiedSince); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } // Only compare up to the second because the datetime format we send to the client // does not have milliseconds long ifModifiedSinceDateSeconds = ifModifiedSinceDate.getTime() / 1000; long fileLastModifiedSeconds = file.lastModified() / 1000; if (ifModifiedSinceDateSeconds == fileLastModifiedSeconds) { sendNotModified(ctx); return; } } RandomAccessFile raf; try { raf = new RandomAccessFile(file, "r"); } catch (FileNotFoundException ignore) { sendHttpResponse( ctx, request, new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.NOT_FOUND)); return; } long fileLength = 0; try { fileLength = raf.length(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK); HttpHeaders.setContentLength(response, fileLength); setContentTypeHeader(response, file); setDateAndCacheHeaders(response, file); if (HttpHeaders.isKeepAlive(request)) { response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE); } // Write the initial line and the header. ctx.write(response); // Write the content. ChannelFuture sendFileFuture = null; ChannelFuture lastContentFuture; if (ctx.pipeline().get(SslHandler.class) == null) { sendFileFuture = ctx.write( new DefaultFileRegion(raf.getChannel(), 0, fileLength), ctx.newProgressivePromise()); // Write the end marker. lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT); } else { try { sendFileFuture = ctx.writeAndFlush( new HttpChunkedInput(new ChunkedFile(raf, 0, fileLength, 8192)), ctx.newProgressivePromise()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // HttpChunkedInput will write the end marker (LastHttpContent) for us. lastContentFuture = sendFileFuture; } sendFileFuture.addListener( new ChannelProgressiveFutureListener() { @Override public void operationProgressed( ChannelProgressiveFuture future, long progress, long total) { if (total < 0) { // total unknown System.err.println(future.channel() + " Transfer progress: " + progress); } else { System.err.println( future.channel() + " Transfer progress: " + progress + " / " + total); } } @Override public void operationComplete(ChannelProgressiveFuture future) { System.err.println(future.channel() + " Transfer complete."); } }); // Decide whether to close the connection or not. if (!HttpHeaders.isKeepAlive(request)) { // Close the connection when the whole content is written out. lastContentFuture.addListener(ChannelFutureListener.CLOSE); } // // Send the demo page and favicon.ico // if ("/".equals(req.getUri()) && req.getMethod() == GET) { // ByteBuf content = WebSocketServerIndexPage.getContent(getWebSocketLocation(req)); // FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, OK, content); // // res.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8"); // HttpHeaders.setContentLength(res, content.readableBytes()); // // sendHttpResponse(ctx, req, res); // return; // } // // if ("/favicon.ico".equals(req.getUri())) { // FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, NOT_FOUND); // sendHttpResponse(ctx, req, res); // return; // } sendHttpResponse( ctx, request, new DefaultFullHttpResponse(HTTP_1_1, HttpResponseStatus.FORBIDDEN)); return; }
private ChannelFuture handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest request) { if (request.method() == HttpMethod.OPTIONS) { return HttpHelpers.sendPreflightApproval(ctx); } HttpRequestInfo CurrRequest = new HttpRequestInfo(); try { CurrRequest.init(Info, request, SVID.makeSVID()); } catch (URISyntaxException e1) { return HttpHelpers.sendError(CurrRequest, ApiErrors.HTTP_DECODE_ERROR); } URI uri = CurrRequest.RequestURI; l.debug(new SVLog("Agent HTTP request", CurrRequest)); if (!request.decoderResult().isSuccess()) { return HttpHelpers.sendError(CurrRequest, ApiErrors.HTTP_DECODE_ERROR); } if (!authenticate(request, (InetSocketAddress) ctx.channel().remoteAddress())) { return HttpHelpers.sendError(CurrRequest, ApiErrors.BAD_AUTH); } String uriPath = uri.getPath(); if (uriPath.equals(WEBSOCKET_PATH)) { String websockUrl = request.headers().get(HttpHeaderNames.HOST) + WEBSOCKET_PATH; WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(websockUrl, null, false); Handshaker = wsFactory.newHandshaker(request); if (Handshaker == null) { return WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); } else { WebsocketConnected = true; return Handshaker.handshake(ctx.channel(), request); } } if (uriPath.startsWith("/api/")) { // Invoking an API directly over HTTP String messageType = uriPath.substring(5); String messageBody = null; if (request.method() == HttpMethod.POST && request.content() != null) { messageBody = request.content().toString(StandardCharsets.UTF_8); } ByteBuf reply = null; try { reply = Dispatcher.dispatch(messageType, messageBody); } catch (JsonProcessingException e) { return HttpHelpers.sendError(CurrRequest, ApiErrors.JSON_ERROR, e.getMessage()); } catch (SQLException e) { return HttpHelpers.sendError(CurrRequest, ApiErrors.DB_ERROR, e.getMessage()); } catch (JsonApiException e) { return HttpHelpers.sendErrorJson(CurrRequest, e.Error, e.HttpStatus); } catch (Exception e) { return HttpHelpers.sendError(CurrRequest, ApiErrors.INTERNAL_SERVER_ERROR, e.getMessage()); } HttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, reply); if (reply != null) { HttpHelpers.setContentTypeHeader(response, "application/json"); HttpUtil.setContentLength(response, reply.readableBytes()); } response.headers().set(HttpHeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN, "*"); return ctx.writeAndFlush(response); } return HttpHelpers.sendError(CurrRequest, ApiErrors.NOT_FOUND); }
public static ChannelFuture handshake( final ChannelHandlerContext ctx, final HttpRequest request, final String websocketPath, final ChannelHandler handler) { final String connHead = request.getHttpHeaders().getHeaderString(HttpHeaders.Names.CONNECTION); final String upHead = request.getHttpHeaders().getHeaderString(HttpHeaders.Names.UPGRADE); final String sockHead = request.getHttpHeaders().getHeaderString(HttpHeaders.Names.SEC_WEBSOCKET_VERSION); final String keyHead = request.getHttpHeaders().getHeaderString(HttpHeaders.Names.SEC_WEBSOCKET_KEY); try { DefaultHttpRequest req = new DefaultHttpRequest( HttpVersion.HTTP_1_0, HttpMethod.GET, request.getUri().getAbsolutePath().toString()); req.setHeader(HttpHeaders.Names.SEC_WEBSOCKET_VERSION, sockHead); req.setHeader(HttpHeaders.Names.SEC_WEBSOCKET_KEY, keyHead); final Channel channel = ctx.channel(); final String location = getWebSocketLocation(channel.pipeline(), request, websocketPath); final WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(location, null, false); final WebSocketServerHandshaker handshaker = wsFactory.newHandshaker(req); if (handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(channel); return null; } else if (!connHead.toLowerCase().contains(HttpHeaders.Values.UPGRADE.toLowerCase()) || !upHead.toLowerCase().contains(HttpHeaders.Values.WEBSOCKET.toLowerCase())) { // Not a valid socket open request logger.info("Invalid request: " + request.getUri()); return null; } else { // We need to remove the RESTEasy stuff otherwise the Netty logic to write the handshake to // the channel // will never make it back to the client channel.pipeline().remove("resteasyEncoder"); channel.pipeline().remove("resteasyDecoder"); final ChannelFuture handshakeFuture = handshaker.handshake(channel, req); handshakeFuture.addListener( new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (!future.isSuccess()) { ctx.fireExceptionCaught(future.cause()); } else { final ChannelPipeline pipeline = future.channel().pipeline(); pipeline.replace(pipeline.last(), "customSocketHandler", handler); pipeline.addBefore( "customSocketHandler", "socketHandler", new WebSocketProtocolHandler()); } } }); WebSocketProtocolHandler.setHandshaker(ctx, handshaker); return handshakeFuture; // channel.pipeline().addBefore("timeout", "WS403Responder", // WebSocketProtocolHandler.forbiddenHttpRequestResponder()); } } catch (Exception e) { logger.error("Error trying to upgrade the channel to a socket", e); } return null; }
private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) throws SuspendExecution { // Handle a bad request. if (!req.getDecoderResult().isSuccess()) { sendHttpResponse( ctx, req, new DefaultFullHttpResponse(req.getProtocolVersion(), BAD_REQUEST), false); return; } final String uri = req.getUri(); final Context actorCtx = selector.get(ctx, req); assert actorCtx != null; final ReentrantLock lock = actorCtx.getLock(); assert lock != null; lock.lock(); try { final ActorRef<? extends WebMessage> userActorRef = actorCtx.getRef(); ActorImpl internalActor = (ActorImpl) actorCtx.getAttachments().get(ACTOR_KEY); if (userActorRef != null) { if (actorCtx.handlesWithWebSocket(uri)) { if (internalActor == null || !(internalActor instanceof WebSocketActorAdapter)) { //noinspection unchecked webSocketActor = new WebSocketActorAdapter(ctx, (ActorRef<? super WebMessage>) userActorRef); addActorToContextAndUnlock(actorCtx, webSocketActor, lock); } // Handshake final WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(uri, null, true); handshaker = wsFactory.newHandshaker(req); if (handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); } else { @SuppressWarnings("unchecked") final ActorRef<WebMessage> userActorRef0 = (ActorRef<WebMessage>) webSocketActor.userActor; handshaker .handshake(ctx.channel(), req) .addListener( new GenericFutureListener<ChannelFuture>() { @Override public void operationComplete(ChannelFuture future) throws Exception { FiberUtil.runInFiber( new SuspendableRunnable() { @Override public void run() throws SuspendExecution, InterruptedException { userActorRef0.send( new WebSocketOpened(WebActorHandler.this.webSocketActor.ref())); } }); } }); } return; } else if (actorCtx.handlesWithHttp(uri)) { if (internalActor == null || !(internalActor instanceof HttpActorAdapter)) { //noinspection unchecked internalActor = new HttpActorAdapter( (ActorRef<HttpRequest>) userActorRef, actorCtx, httpResponseEncoderName); addActorToContextAndUnlock(actorCtx, internalActor, lock); } //noinspection unchecked ((HttpActorAdapter) internalActor).service(ctx, req); return; } } } finally { if (lock.isHeldByCurrentStrand() && lock.isLocked()) lock.unlock(); } sendHttpResponse( ctx, req, new DefaultFullHttpResponse(req.getProtocolVersion(), NOT_FOUND), false); }