@SuppressWarnings("unchecked") public boolean sendRequest( final FilterChainContext ctx, final Request request, final HttpRequestPacket requestPacket) throws IOException { boolean isWriteComplete = true; if (Utils.requestHasEntityBody(request)) { final HttpTxContext context = HttpTxContext.get(ctx); BodyHandler handler = bodyHandlerFactory.getBodyHandler(request); if (requestPacket.getHeaders().contains(Header.Expect) && requestPacket.getHeaders().getValue(1).equalsIgnoreCase("100-Continue")) { // We have to set the content-length now as the headers will be flushed // before the FileBodyHandler is invoked. If we don't do it here, and // the user didn't explicitly set the length, then the transfer-encoding // will be chunked and zero-copy file transfer will not occur. final File f = request.getFile(); if (f != null) { requestPacket.setContentLengthLong(f.length()); } handler = new ExpectHandler(handler); } context.setBodyHandler(handler); if (logger.isDebugEnabled()) { logger.debug("REQUEST: {}", requestPacket); } isWriteComplete = handler.doHandle(ctx, request, requestPacket); } else { HttpContent content = HttpContent.builder(requestPacket).last(true).build(); if (logger.isDebugEnabled()) { logger.debug("REQUEST: {}", requestPacket); } ctx.write(content, ctx.getTransportContext().getCompletionHandler()); } return isWriteComplete; }
private boolean sendAsGrizzlyRequest( final RequestInfoHolder requestInfoHolder, final FilterChainContext ctx) throws IOException { HttpTxContext httpTxContext = requestInfoHolder.getHttpTxContext(); if (httpTxContext == null) { httpTxContext = HttpTxContext.create(requestInfoHolder); } if (checkProxyAuthFailure(ctx, httpTxContext)) { return true; } final Request request = httpTxContext.getRequest(); final URI uri = request.isUseRawUrl() ? request.getRawURI() : request.getURI(); boolean secure = Utils.isSecure(uri); // If the request is secure, check to see if an error occurred during // the handshake. We have to do this here, as the error would occur // out of the scope of a HttpTxContext so there would be // no good way to communicate the problem to the caller. if (secure && checkHandshakeError(ctx, httpTxContext)) { return true; } if (isUpgradeRequest(httpTxContext.getHandler()) && isWSRequest(httpTxContext.getRequestUrl())) { httpTxContext.setWSRequest(true); convertToUpgradeRequest(httpTxContext); } HttpRequestPacket requestPacket = requestCache.poll(); if (requestPacket == null) { requestPacket = new HttpRequestPacketImpl(); } requestPacket.setMethod(request.getMethod()); requestPacket.setProtocol(Protocol.HTTP_1_1); // Special handling for CONNECT. if (Method.CONNECT.matchesMethod(request.getMethod())) { final int port = uri.getPort(); requestPacket.setRequestURI(uri.getHost() + ':' + (port == -1 ? 443 : port)); } else { requestPacket.setRequestURI(uri.getPath()); } if (Utils.requestHasEntityBody(request)) { final long contentLength = request.getContentLength(); if (contentLength >= 0) { requestPacket.setContentLengthLong(contentLength); requestPacket.setChunked(false); } else { requestPacket.setChunked(true); } } if (httpTxContext.isWSRequest()) { try { final URI wsURI = new URI(httpTxContext.getWsRequestURI()); httpTxContext.setProtocolHandler(Version.RFC6455.createHandler(true)); httpTxContext.setHandshake(httpTxContext.getProtocolHandler().createHandShake(wsURI)); requestPacket = (HttpRequestPacket) httpTxContext.getHandshake().composeHeaders().getHttpHeader(); } catch (URISyntaxException e) { throw new IllegalArgumentException("Invalid WS URI: " + httpTxContext.getWsRequestURI()); } } requestPacket.setSecure(secure); addQueryString(request, requestPacket); addHostHeader(request, uri, requestPacket); addGeneralHeaders(request, requestPacket); addCookies(request, requestPacket); initTransferCompletionHandler(request, httpTxContext.getHandler()); final HttpRequestPacket requestPacketLocal = requestPacket; FilterChainContext sendingCtx = ctx; if (secure) { // Check to see if the ProtocolNegotiator has given // us a different FilterChain to use. If so, we need // use a different FilterChainContext when invoking sendRequest(). sendingCtx = checkAndHandleFilterChainUpdate(ctx, sendingCtx); } final Connection c = ctx.getConnection(); if (!Utils.isSpdyConnection(c)) { HttpContext.newInstance(ctx, c, c, c); } else { SpdySession session = SpdySession.get(c); final Lock lock = session.getNewClientStreamLock(); try { lock.lock(); SpdyStream stream = session.openStream( requestPacketLocal, session.getNextLocalStreamId(), 0, 0, 0, false, !requestPacketLocal.isExpectContent()); HttpContext.newInstance(ctx, stream, stream, stream); } finally { lock.unlock(); } } HttpTxContext.set(ctx, httpTxContext); return sendRequest(sendingCtx, request, requestPacketLocal); }