private void writeResponse(Channel channel, HttpRequest request, String message, String client) { String contentType = "text/plain"; if (client != null && (client.equals("web") || client.equals("bluej"))) { // convert to HTML message = message.replaceAll("\n", "<br>\n"); contentType = "text/html"; } // Convert the response content to a ChannelBuffer. ByteBuf buf = copiedBuffer(message, CharsetUtil.UTF_8); // Decide whether to close the connection or not. boolean close = HttpHeaders.Values.CLOSE.equalsIgnoreCase(request.headers().get(CONNECTION)) || request.getProtocolVersion().equals(HttpVersion.HTTP_1_0) && !HttpHeaders.Values.KEEP_ALIVE.equalsIgnoreCase( request.headers().get(CONNECTION)); // Build the response object. FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf); response.headers().set(CONTENT_TYPE, contentType + "; charset=UTF-8"); if (!close) { // There's no need to add 'Content-Length' header // if this is the last response. response.headers().set(CONTENT_LENGTH, buf.readableBytes()); } // Write the response. ChannelFuture future = channel.writeAndFlush(response); // Close the connection after the write operation is done if necessary. if (close) { future.addListener(ChannelFutureListener.CLOSE); } }
/** * Flush the response contents to the output channel * * @param channel Channel to be used */ private void writeResponse(Channel channel) { // Convert the response content to a ChannelBuffer. ByteBuf buf = copiedBuffer(responseContent.toString(), CharsetUtil.UTF_8); responseContent.setLength(0); // Decide whether to close the connection or not. boolean close = HttpHeaders.Values.CLOSE.equalsIgnoreCase(request.headers().get(CONNECTION)) || request.getProtocolVersion().equals(HttpVersion.HTTP_1_0) && !HttpHeaders.Values.KEEP_ALIVE.equalsIgnoreCase( request.headers().get(CONNECTION)); // Build the response object. FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf); response.headers().set(CONTENT_TYPE, "application/json; charset=UTF-8"); if (!close) { // There's no need to add 'Content-Length' header // if this is the last response. response.headers().set(CONTENT_LENGTH, buf.readableBytes()); } try { // Write the response. ChannelFuture future = channel.writeAndFlush(response); // Close the connection after the write operation is done if necessary. if (close) { future.addListener(ChannelFutureListener.CLOSE); } } catch (Exception e) { logger.error("{}", e); } }
/** * build PLAY request * * @return */ private HttpRequest buildPlayRequest(String uri) { HttpRequest request = new DefaultFullHttpRequest(RtspVersions.RTSP_1_0, RtspMethods.PLAY, uri); request.headers().set(RtspHeaderNames.CSEQ, "4"); request.headers().set(RtspHeaderNames.SESSION, "1234567"); request.headers().add(RtspHeaderNames.RANGE, "npt=10-15"); return request; }
private HttpRequest buildAnnounceRequest(String uri) { HttpRequest request = new DefaultFullHttpRequest(RtspVersions.RTSP_1_0, RtspMethods.ANNOUNCE, uri); request.headers().set(RtspHeaderNames.CSEQ, "1"); request.headers().set(RtspHeaderNames.SESSION, "1234567"); request.headers().add(RtspHeaderNames.CONTENT_TYPE, "application/sdp"); request.headers().add(RtspHeaderNames.CONTENT_LENGTH, "123"); // request.setContent(null); return request; }
public FileChunk get() throws IOException { if (useLocalFile) { startTime = System.currentTimeMillis(); finishTime = System.currentTimeMillis(); state = TajoProtos.FetcherState.FETCH_FINISHED; return fileChunk; } this.startTime = System.currentTimeMillis(); this.state = TajoProtos.FetcherState.FETCH_FETCHING; ChannelFuture future = null; try { future = bootstrap .clone() .connect(new InetSocketAddress(host, port)) .addListener(ChannelFutureListener.CLOSE_ON_FAILURE); // Wait until the connection attempt succeeds or fails. Channel channel = future.awaitUninterruptibly().channel(); if (!future.isSuccess()) { state = TajoProtos.FetcherState.FETCH_FAILED; throw new IOException(future.cause()); } String query = uri.getPath() + (uri.getRawQuery() != null ? "?" + uri.getRawQuery() : ""); // Prepare the HTTP request. HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, query); request.headers().set(HttpHeaders.Names.HOST, host); request.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE); request.headers().set(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP); LOG.info("Status: " + getState() + ", URI:" + uri); // Send the HTTP request. channel.writeAndFlush(request); // Wait for the server to close the connection. throw exception if failed channel.closeFuture().syncUninterruptibly(); fileChunk.setLength(fileChunk.getFile().length()); return fileChunk; } finally { if (future != null && future.channel().isOpen()) { // Close the channel to exit. future.channel().close().awaitUninterruptibly(); } this.finishTime = System.currentTimeMillis(); LOG.info( "Fetcher finished:" + (finishTime - startTime) + " ms, " + getState() + ", URI:" + uri); } }
/** * build PAUSE request * * @return */ private HttpRequest buildPauseRequest(String uri) { HttpRequest request = new DefaultFullHttpRequest(RtspVersions.RTSP_1_0, RtspMethods.PAUSE, uri); request.headers().set(RtspHeaderNames.CSEQ, "5"); request.headers().set(RtspHeaderNames.SESSION, "1234567"); return request; }
/** * build SETUP request * * @return */ private HttpRequest buildSetupRequest(String uri) { HttpRequest request = new DefaultFullHttpRequest(RtspVersions.RTSP_1_0, RtspMethods.SETUP, uri); request.headers().set(RtspHeaderNames.CSEQ, "3"); request.headers().add(RtspHeaderNames.TRANSPORT, "RTP/AVP;unicast;client_port=4588-4589"); return request; }
/** * build TEARDOWN request * * @return */ private HttpRequest buildTeardownRequest(String uri) { HttpRequest request = new DefaultFullHttpRequest(RtspVersions.RTSP_1_0, RtspMethods.TEARDOWN, uri); request.headers().set(RtspHeaderNames.CSEQ, "6"); request.headers().set(RtspHeaderNames.SESSION, "1234567"); return request; }
private void writeResponse(Channel channel) { // Convert the response content to a ChannelBuffer. ByteBuf buf = copiedBuffer(responseContent.toString(), CharsetUtil.UTF_8); responseContent.setLength(0); // Decide whether to close the connection or not. boolean close = request.headers().contains(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE, true) || request.protocolVersion().equals(HttpVersion.HTTP_1_0) && !request .headers() .contains(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE, true); // Build the response object. FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf); response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8"); if (!close) { // There's no need to add 'Content-Length' header // if this is the last response. response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, buf.readableBytes()); } Set<Cookie> cookies; String value = request.headers().getAndConvert(HttpHeaderNames.COOKIE); if (value == null) { cookies = Collections.emptySet(); } else { cookies = ServerCookieDecoder.STRICT.decode(value); } if (!cookies.isEmpty()) { // Reset the cookies if necessary. for (Cookie cookie : cookies) { response .headers() .add(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.STRICT.encode(cookie)); } } // Write the response. ChannelFuture future = channel.writeAndFlush(response); // Close the connection after the write operation is done if necessary. if (close) { future.addListener(ChannelFutureListener.CLOSE); } }
public static MultivaluedMap<String, String> extractRequestHeaders(HttpRequest request) { Headers<String> requestHeaders = new Headers<String>(); for (Map.Entry<String, String> header : request.headers()) { requestHeaders.add(header.getKey(), header.getValue()); } return requestHeaders; }
boolean isKeepAlive() { String connHeader = req.headers().get("Connection"); if (isOlderHttpVersion()) { return ((connHeader != null) && "keep-alive".equalsIgnoreCase(connHeader)); } else { return ((connHeader == null) || !"close".equalsIgnoreCase(connHeader)); } }
@Override public MultiMap headers() { synchronized (getLock()) { if (headers == null) { headers = new HeadersAdaptor(request.headers()); } return headers; } }
public static void newHttpClientBootstrap(String url, ChannelHandler handler) throws Exception { URI uri = new URI(url); String scheme = uri.getScheme() == null ? "http" : uri.getScheme(); String host = uri.getHost() == null ? "127.0.0.1" : uri.getHost(); int port = uri.getPort(); if (port == -1) { if ("http".equalsIgnoreCase(scheme)) { port = 80; } else if ("https".equalsIgnoreCase(scheme)) { port = 443; } } if (!"http".equalsIgnoreCase(scheme) && !"https".equalsIgnoreCase(scheme)) { System.err.println("Only HTTP(S) is supported."); return; } // Configure SSL context if necessary. final boolean ssl = "https".equalsIgnoreCase(scheme); final SslContext sslCtx; if (ssl) { sslCtx = SslContext.newClientContext(InsecureTrustManagerFactory.INSTANCE); } else { sslCtx = null; } // Configure the client. EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group) .channel(NioSocketChannel.class) .handler(new HttpDownloadertInitializer(sslCtx, handler)); // Make the connection attempt. Channel ch = b.connect(host, port).sync().channel(); // Prepare the HTTP request. HttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, uri.getRawPath()); HttpHeaders headers = request.headers(); headers.set(HttpHeaders.Names.HOST, host); headers.set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.CLOSE); headers.set(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP); // Set some example cookies. headers.set( HttpHeaders.Names.COOKIE, ClientCookieEncoder.encode(new DefaultCookie("my-cookie", "foo"))); ch.writeAndFlush(request); // Wait for the server to close the connection. ch.closeFuture().sync(); Thread.sleep(1000); } finally { // Shut down executor threads to exit. group.shutdownGracefully(); } }
@Test public void ifNoneMatchHeader() throws Exception { final SockJsConfig config = config(); final String path = config.prefix() + "/iframe.html"; final HttpRequest httpRequest = createHttpRequest(path); httpRequest.headers().set(HttpHeaders.Names.IF_NONE_MATCH, "*"); final FullHttpResponse response = Iframe.response(config, httpRequest); assertThat( response.headers().get(HttpHeaders.Names.SET_COOKIE), equalTo("JSESSIONID=dummy; path=/")); assertThat(response.getStatus().code(), is(HttpResponseStatus.NOT_MODIFIED.code())); }
int getContentLength() { String ce = req.headers().get("Content-Length"); if (ce != null) { try { return Integer.parseInt(ce); } catch (NumberFormatException nfe) { return -1; } } return -1; }
@Override protected void channelRead0(ChannelHandlerContext ctx, FullHttpMessage msg) throws Exception { // 1 // Request header 처리 if (msg instanceof HttpRequest) { // 2 this.request = (HttpRequest) msg; // 3 if (HttpHeaders.is100ContinueExpected(request)) { send100Continue(ctx); } HttpHeaders headers = request.headers(); // 4 if (!headers.isEmpty()) { for (Map.Entry<String, String> h : headers) { String key = h.getKey(); if (usingHeader.contains(key)) { // 5 reqData.put(key, h.getValue()); // 6 } } } reqData.put("REQUEST_URI", request.getUri()); // 7 reqData.put("REQUEST_METHOD", request.getMethod().name()); // 8 } if (msg instanceof HttpContent) { // 9 HttpContent httpContent = (HttpContent) msg; // 10 ByteBuf content = httpContent.content(); // 11 if (msg instanceof LastHttpContent) { // 12 System.out.println("LastHttpContent message received!!" + request.getUri()); LastHttpContent trailer = (LastHttpContent) msg; readPostData(); // 13 ApiRequest service = ServiceDispatcher.dispatch(reqData); // 14 try { service.executeService(); // 15 apiResult = service.getApiResult(); // 16 } finally { reqData.clear(); } if (!writeResponse(trailer, ctx)) { // 17 ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE); } reset(); } } }
private Map<String, List<Cookie>> readCookie(final HttpRequest httpRequest) { final Map<String, List<Cookie>> cookiesDownload = new HashMap<>(); final String cookieString = httpRequest.headers().get(HttpHeaders.Names.COOKIE); if (cookieString != null) { for (Cookie cookie : ServerCookieDecoder.STRICT.decode(cookieString)) { if (cookiesDownload.containsKey(cookie.name())) { cookiesDownload.get(cookie.name()).add(cookie); } else { cookiesDownload.put(cookie.name(), new ArrayList<>(Arrays.asList(cookie))); } } } return cookiesDownload; }
@Override protected ChannelFuture doOnPut(ChannelHandlerContext context, HttpRequest request) { NettyTransferService<HttpProtocolInfo>.NettyMoverChannel file = null; Exception exception = null; try { checkContentHeader(request.headers().names(), Collections.singletonList(CONTENT_LENGTH)); file = open(request, true); if (file.getIoMode() != IoMode.WRITE) { throw new HttpException(METHOD_NOT_ALLOWED.code(), "Resource is not open for writing"); } if (is100ContinueExpected(request)) { context .writeAndFlush(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE)) .addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); } _writeChannel = file; file = null; return null; } catch (HttpException e) { exception = e; return context.writeAndFlush( createErrorResponse(HttpResponseStatus.valueOf(e.getErrorCode()), e.getMessage())); } catch (URISyntaxException e) { exception = e; return context.writeAndFlush( createErrorResponse(BAD_REQUEST, "URI is not valid: " + e.getMessage())); } catch (IllegalArgumentException e) { exception = e; return context.writeAndFlush(createErrorResponse(BAD_REQUEST, e.getMessage())); } catch (RuntimeException e) { exception = e; return context.writeAndFlush(createErrorResponse(INTERNAL_SERVER_ERROR, e.getMessage())); } finally { if (file != null) { file.release(exception); _files.remove(file); } } }
@Override protected void doOnTerminate( ChannelHandlerContext ctx, ChannelFuture last, final ChannelPromise promise) { if (request.method() == Method.WS) { return; } ByteBuffer byteBuffer = body.flip().byteBuffer(); if (request.checkHeader()) { HttpRequest req = new DefaultFullHttpRequest( request.getNettyRequest().getProtocolVersion(), request.getNettyRequest().getMethod(), request.getNettyRequest().getUri(), byteBuffer != null ? Unpooled.wrappedBuffer(byteBuffer) : Unpooled.EMPTY_BUFFER); req.headers().add(request.headers().delegate()); if (byteBuffer != null) { HttpHeaders.setContentLength(req, body.limit()); } ctx.writeAndFlush(req) .addListener( new ChannelFutureListener() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (future.isSuccess()) { promise.trySuccess(); } else { promise.tryFailure(future.cause()); } } }); } else { ctx.write( new DefaultHttpContent( byteBuffer != null ? Unpooled.wrappedBuffer(byteBuffer) : Unpooled.EMPTY_BUFFER)); } body.reset(); }
private FullHttpResponse handleStaticResource(String path, HttpRequest request) throws IOException { URL url = getSecureUrlForPath(RESOURCE_BASE + path); if (url == null) { // log at debug only since this is typically just exploit bot spam logger.debug("unexpected path: {}", path); return new DefaultFullHttpResponse(HTTP_1_1, NOT_FOUND); } Date expires = getExpiresForPath(path); if (request.headers().contains(HttpHeaderNames.IF_MODIFIED_SINCE) && expires == null) { // all static resources without explicit expires are versioned and can be safely // cached forever return new DefaultFullHttpResponse(HTTP_1_1, NOT_MODIFIED); } ByteBuf content = Unpooled.copiedBuffer(Resources.toByteArray(url)); FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, content); if (expires != null) { response.headers().add(HttpHeaderNames.EXPIRES, expires); } else { response.headers().add(HttpHeaderNames.LAST_MODIFIED, new Date(0)); response .headers() .add(HttpHeaderNames.EXPIRES, new Date(System.currentTimeMillis() + TEN_YEARS)); } int extensionStartIndex = path.lastIndexOf('.'); checkState( extensionStartIndex != -1, "found path under %s with no extension: %s", RESOURCE_BASE, path); String extension = path.substring(extensionStartIndex + 1); MediaType mediaType = mediaTypes.get(extension); checkNotNull( mediaType, "found extension under %s with no media type: %s", RESOURCE_BASE, extension); response.headers().add(HttpHeaderNames.CONTENT_TYPE, mediaType); response.headers().add(HttpHeaderNames.CONTENT_LENGTH, Resources.toByteArray(url).length); return response; }
@Override protected void messageReceived(ChannelHandlerContext ctx, Object msg) { if (msg instanceof HttpRequest) { HttpRequest request = _request = (HttpRequest) msg; HttpMethod method = request.method(); HttpHeaders headers = request.headers(); QueryStringDecoder query = new QueryStringDecoder(request.uri()); if (HttpHeaderUtil.is100ContinueExpected(request)) ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE)); // if (headers != null) for (Map.Entry<CharSequence, CharSequence> h : headers) {} if (method.equals(HttpMethod.GET)) RamdRequest.build(query.path(), query.parameters()); } if (msg instanceof HttpContent) { ByteBuf bb = ((HttpContent) msg).content(); if (bb.isReadable()) {} _buf.append("Done."); writeResponse((HttpContent) msg, ctx); } }
@Override public boolean preCall(HttpRequest request, HttpResponder responder, HandlerInfo handlerInfo) { HTTPMonitoringEvent httpMonitoringEvent = new HTTPMonitoringEvent(); httpMonitoringEvent.setTimestamp(System.currentTimeMillis()); httpMonitoringEvent.setStartNanoTime(System.nanoTime()); if (serviceClass == null) { Method method = handlerInfo.getMethod(); Class<?> serviceClass = method.getDeclaringClass(); this.serviceClass = serviceClass.getName(); serviceName = serviceClass.getSimpleName(); serviceMethod = method.getName(); if (serviceClass.isAnnotationPresent(Path.class)) { Path path = serviceClass.getAnnotation(Path.class); servicePath = path.value(); } } httpMonitoringEvent.setServiceClass(serviceClass); httpMonitoringEvent.setServiceName(serviceName); httpMonitoringEvent.setServiceMethod(serviceMethod); httpMonitoringEvent.setRequestUri(request.getUri()); httpMonitoringEvent.setServiceContext(servicePath); HttpHeaders httpHeaders = request.headers(); httpMonitoringEvent.setHttpMethod(request.getMethod().name()); httpMonitoringEvent.setContentType(httpHeaders.get(HttpHeaders.Names.CONTENT_TYPE)); String contentLength = httpHeaders.get(HttpHeaders.Names.CONTENT_LENGTH); if (contentLength != null) { httpMonitoringEvent.setRequestSizeBytes(Long.parseLong(contentLength)); } httpMonitoringEvent.setReferrer(httpHeaders.get(HttpHeaders.Names.REFERER)); handlerInfo.setAttribute(MONITORING_EVENT, httpMonitoringEvent); return true; }
public void messageReceived(ChannelHandlerContext ctx, Object o) throws Exception { if (o instanceof HttpRequest) { // DefaultHttpRequest ) { queue.add((HttpRequest) o); } else if (o instanceof LastHttpContent) { HttpRequest req = queue.remove(); req.getMethod(); req.getUri(); req.headers(); LastHttpContent content = (LastHttpContent) o; ByteBuf buf = content.content(); if (buf.readableBytes() > 0) { Gson gson = GsonFactory.createBuilder().create(); Reader in = new InputStreamReader(new ByteBufInputStream(buf), "utf-8"); Object v = gson.fromJson(in, Class.forName("com.logbook.logbook.resources.logs.LogEntryDTO")); System.out.println("v = " + v); } System.out.println( req.getMethod() + " " + req.getUri() + " -- " + buf.readableBytes() + " bytes"); HttpResponse r = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); r.headers().add("Content-Length", "0"); ctx.write(r); } else { System.out.println("o = " + o + " : " + o.getClass()); } }
private void prepareHeaders() { HttpHeaders headers = request.headers(); headers.remove(TRANSFER_ENCODING); if (!headers.contains(HOST)) { request.headers().set(HOST, conn.hostHeader()); } if (chunked) { HttpHeaders.setTransferEncodingChunked(request); } if (client.getOptions().isTryUseCompression() && request.headers().get(ACCEPT_ENCODING) == null) { // if compression should be used but nothing is specified by the user support deflate and // gzip. request.headers().set(ACCEPT_ENCODING, DEFLATE_GZIP); } if (!client.getOptions().isKeepAlive() && client.getOptions().getProtocolVersion() == io.vertx.core.http.HttpVersion.HTTP_1_1) { request.headers().set(CONNECTION, CLOSE); } else if (client.getOptions().isKeepAlive() && client.getOptions().getProtocolVersion() == io.vertx.core.http.HttpVersion.HTTP_1_0) { request.headers().set(CONNECTION, KEEP_ALIVE); } }
boolean isChunked() { String te = req.headers().get("Transfer-Encoding"); return ((te != null) && !te.equals("identity")); }
private boolean contentLengthSet() { return headers != null && request.headers().contains(CONTENT_LENGTH); }
/** * Call the appropriate handler for handling the httprequest. 404 if path is not found. 405 if * path is found but httpMethod does not match what's configured. * * @param request instance of {@code HttpRequest} * @param responder instance of {@code HttpResponder} to handle the request. * @return HttpMethodInfo object, null if urlRewriter rewrite returns false, also when method * cannot be invoked. * @throws HandlerException If URL rewriting fails */ public HttpMethodInfoBuilder getDestinationMethod(HttpRequest request, HttpResponder responder) throws HandlerException { if (urlRewriter != null) { try { request.setUri(URI.create(request.getUri()).normalize().toString()); if (!urlRewriter.rewrite(request, responder)) { return null; } } catch (Throwable t) { log.error("Exception thrown during rewriting of uri {}", request.getUri(), t); throw new HandlerException( HttpResponseStatus.INTERNAL_SERVER_ERROR, String.format("Caught exception processing request. Reason: %s", t.getMessage())); } } String acceptHeaderStr = request.headers().get(HttpHeaders.Names.ACCEPT); List<String> acceptHeader = (acceptHeaderStr != null) ? Arrays.asList(acceptHeaderStr.split("\\s*,\\s*")) .stream() .map(mediaType -> mediaType.split("\\s*;\\s*")[0]) .collect(Collectors.toList()) : null; String contentTypeHeaderStr = request.headers().get(HttpHeaders.Names.CONTENT_TYPE); // Trim specified charset since UTF-8 is assumed String contentTypeHeader = (contentTypeHeaderStr != null) ? contentTypeHeaderStr.split("\\s*;\\s*")[0] : null; try { String path = URI.create(request.getUri()).normalize().getPath(); List<PatternPathRouterWithGroups.RoutableDestination<HttpResourceModel>> routableDestinations = patternRouter.getDestinations(path); List<PatternPathRouterWithGroups.RoutableDestination<HttpResourceModel>> matchedDestinations = getMatchedDestination(routableDestinations, request.getMethod(), path); if (!matchedDestinations.isEmpty()) { PatternPathRouterWithGroups.RoutableDestination<HttpResourceModel> matchedDestination = matchedDestinations .stream() .filter( matchedDestination1 -> { return matchedDestination1 .getDestination() .matchConsumeMediaType(contentTypeHeader) && matchedDestination1 .getDestination() .matchProduceMediaType(acceptHeader); }) .findFirst() .get(); HttpResourceModel httpResourceModel = matchedDestination.getDestination(); // Call preCall method of handler interceptors. boolean terminated = false; ServiceMethodInfo serviceMethodInfo = new ServiceMethodInfo( httpResourceModel.getMethod().getDeclaringClass().getName(), httpResourceModel.getMethod()); for (Interceptor interceptor : interceptors) { if (!interceptor.preCall(request, responder, serviceMethodInfo)) { // Terminate further request processing if preCall returns false. terminated = true; break; } } // Call httpresource handle method, return the HttpMethodInfo Object. if (!terminated) { // Wrap responder to make post hook calls. responder = new WrappedHttpResponder(responder, interceptors, request, serviceMethodInfo); return HttpMethodInfoBuilder.getInstance() .httpResourceModel(httpResourceModel) .httpRequest(request) .httpResponder(responder) .requestInfo( matchedDestination.getGroupNameValues(), contentTypeHeader, acceptHeader); } } else if (!routableDestinations.isEmpty()) { // Found a matching resource but could not find the right HttpMethod so return 405 throw new HandlerException(HttpResponseStatus.METHOD_NOT_ALLOWED, request.getUri()); } else { throw new HandlerException( HttpResponseStatus.NOT_FOUND, String.format("Problem accessing: %s. Reason: Not Found", request.getUri())); } } catch (NoSuchElementException ex) { throw new HandlerException( HttpResponseStatus.UNSUPPORTED_MEDIA_TYPE, String.format("Problem accessing: %s. Reason: Unsupported Media Type", request.getUri()), ex); } return null; }
void handleStaticFileRequest(ChannelHandlerContext ctx, HttpRequest req, String path) throws Exception { log.debug("handling static file request for {}", path); path = sanitizePath(path); if (path == null) { sendError(ctx, FORBIDDEN); return; } File file = new File(path); if (file.isHidden() || !file.exists()) { log.warn("{} does not exist or is hidden", file.toString()); sendError(ctx, NOT_FOUND); return; } if (!file.isFile()) { sendError(ctx, FORBIDDEN); return; } // Cache Validation String ifModifiedSince = req.headers().get(HttpHeaders.Names.IF_MODIFIED_SINCE); if (ifModifiedSince != null && !ifModifiedSince.equals("")) { SimpleDateFormat dateFormatter = new SimpleDateFormat(HTTP_DATE_FORMAT); Date ifModifiedSinceDate = dateFormatter.parse(ifModifiedSince); // 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) { sendError(ctx, NOT_FOUND); return; } long fileLength = raf.length(); HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK); HttpHeaders.setContentLength(response, fileLength); setContentTypeHeader(response, file); setDateAndCacheHeaders(response, file); if (HttpHeaders.isKeepAlive(req)) { response.headers().set(Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE); } // Write the initial line and the header. ctx.write(response); // Write the content. ChannelFuture sendFileFuture; 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 { sendFileFuture = ctx.writeAndFlush(new ChunkedFile(raf, 0, fileLength, 8192), ctx.newProgressivePromise()); // 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(req)) { // Close the connection when the whole content is written out. lastContentFuture.addListener(ChannelFutureListener.CLOSE); } }
@Override public void invoke( ServiceInvocationContext ctx, Executor blockingTaskExecutor, Promise<Object> promise) throws Exception { final HttpRequest req = ctx.originalRequest(); if (req.method() != HttpMethod.GET) { respond( ctx, promise, HttpResponseStatus.METHOD_NOT_ALLOWED, 0, ERROR_MIME_TYPE, Unpooled.wrappedBuffer(CONTENT_METHOD_NOT_ALLOWED)); return; } final String path = normalizePath(ctx.mappedPath()); if (path == null) { respond( ctx, promise, HttpResponseStatus.NOT_FOUND, 0, ERROR_MIME_TYPE, Unpooled.wrappedBuffer(CONTENT_NOT_FOUND)); return; } Entry entry = getEntry(path); long lastModifiedMillis; if ((lastModifiedMillis = entry.lastModifiedMillis()) == 0) { boolean found = false; if (path.charAt(path.length() - 1) == '/') { // Try index.html if it was a directory access. entry = getEntry(path + "index.html"); if ((lastModifiedMillis = entry.lastModifiedMillis()) != 0) { found = true; } } if (!found) { respond( ctx, promise, HttpResponseStatus.NOT_FOUND, 0, ERROR_MIME_TYPE, Unpooled.wrappedBuffer(CONTENT_NOT_FOUND)); return; } } long ifModifiedSinceMillis = Long.MIN_VALUE; try { ifModifiedSinceMillis = req.headers().getTimeMillis(HttpHeaderNames.IF_MODIFIED_SINCE, Long.MIN_VALUE); } catch (Exception e) { // Ignore the ParseException, which is raised on malformed date. //noinspection ConstantConditions if (!(e instanceof ParseException)) { throw e; } } // HTTP-date does not have subsecond-precision; add 999ms to it. if (ifModifiedSinceMillis > Long.MAX_VALUE - 999) { ifModifiedSinceMillis = Long.MAX_VALUE; } else { ifModifiedSinceMillis += 999; } if (lastModifiedMillis < ifModifiedSinceMillis) { respond( ctx, promise, HttpResponseStatus.NOT_MODIFIED, lastModifiedMillis, entry.mimeType(), Unpooled.EMPTY_BUFFER); return; } respond( ctx, promise, HttpResponseStatus.OK, lastModifiedMillis, entry.mimeType(), entry.readContent(ctx.alloc())); }
@Override public void messageReceived(ChannelHandlerContext ctx, HttpObject msg) throws Exception { if (msg instanceof HttpRequest) { HttpRequest request = this.request = (HttpRequest) msg; URI uri = new URI(request.uri()); if (!uri.getPath().startsWith("/form")) { // Write Menu writeMenu(ctx); return; } responseContent.setLength(0); responseContent.append("WELCOME TO THE WILD WILD WEB SERVER\r\n"); responseContent.append("===================================\r\n"); responseContent.append("VERSION: " + request.protocolVersion().text() + "\r\n"); responseContent.append("REQUEST_URI: " + request.uri() + "\r\n\r\n"); responseContent.append("\r\n\r\n"); // new getMethod for (Entry<CharSequence, CharSequence> entry : request.headers()) { responseContent.append("HEADER: " + entry.getKey() + '=' + entry.getValue() + "\r\n"); } responseContent.append("\r\n\r\n"); // new getMethod Set<Cookie> cookies; String value = request.headers().getAndConvert(HttpHeaderNames.COOKIE); if (value == null) { cookies = Collections.emptySet(); } else { cookies = ServerCookieDecoder.STRICT.decode(value); } for (Cookie cookie : cookies) { responseContent.append("COOKIE: " + cookie + "\r\n"); } responseContent.append("\r\n\r\n"); QueryStringDecoder decoderQuery = new QueryStringDecoder(request.uri()); Map<String, List<String>> uriAttributes = decoderQuery.parameters(); for (Entry<String, List<String>> attr : uriAttributes.entrySet()) { for (String attrVal : attr.getValue()) { responseContent.append("URI: " + attr.getKey() + '=' + attrVal + "\r\n"); } } responseContent.append("\r\n\r\n"); // if GET Method: should not try to create a HttpPostRequestDecoder if (request.method().equals(HttpMethod.GET)) { // GET Method: should not try to create a HttpPostRequestDecoder // So stop here responseContent.append("\r\n\r\nEND OF GET CONTENT\r\n"); // Not now: LastHttpContent will be sent writeResponse(ctx.channel()); return; } try { decoder = new HttpPostRequestDecoder(factory, request); } catch (ErrorDataDecoderException e1) { e1.printStackTrace(); responseContent.append(e1.getMessage()); writeResponse(ctx.channel()); ctx.channel().close(); return; } readingChunks = HttpHeaderUtil.isTransferEncodingChunked(request); responseContent.append("Is Chunked: " + readingChunks + "\r\n"); responseContent.append("IsMultipart: " + decoder.isMultipart() + "\r\n"); if (readingChunks) { // Chunk version responseContent.append("Chunks: "); readingChunks = true; } } // check if the decoder was constructed before // if not it handles the form get if (decoder != null) { if (msg instanceof HttpContent) { // New chunk is received HttpContent chunk = (HttpContent) msg; try { decoder.offer(chunk); } catch (ErrorDataDecoderException e1) { e1.printStackTrace(); responseContent.append(e1.getMessage()); writeResponse(ctx.channel()); ctx.channel().close(); return; } responseContent.append('o'); // example of reading chunk by chunk (minimize memory usage due to // Factory) readHttpDataChunkByChunk(); // example of reading only if at the end if (chunk instanceof LastHttpContent) { writeResponse(ctx.channel()); readingChunks = false; reset(); } } } else { writeResponse(ctx.channel()); } }