/** * Returns {@code true} if the specified message contains an expect header specifying an expectation that is not * supported. Note that this method returns {@code false} if the expect header is not valid for the message * (e.g., the message is a response, or the version on the message is HTTP/1.0). * * @param message the message * @return {@code true} if and only if an expectation is present that is not supported */ static boolean isUnsupportedExpectation(HttpMessage message) { if (!isExpectHeaderValid(message)) { return false; } final String expectValue = message.headers().get(HttpHeaderNames.EXPECT); return expectValue != null && !HttpHeaderValues.CONTINUE.toString().equalsIgnoreCase(expectValue); }
/** * Returns {@code true} if and only if the connection can remain open and * thus 'kept alive'. This methods respects the value of the. * {@code "Connection"} header first and then the return value of * {@link HttpVersion#isKeepAliveDefault()}. */ public static boolean isKeepAlive(HttpMessage message) { CharSequence connection = message.headers().get(HttpHeaderNames.CONNECTION); if (connection != null && HttpHeaderValues.CLOSE.contentEqualsIgnoreCase(connection)) { return false; } if (message.protocolVersion().isKeepAliveDefault()) { return !HttpHeaderValues.CLOSE.contentEqualsIgnoreCase(connection); } else { return HttpHeaderValues.KEEP_ALIVE.contentEqualsIgnoreCase(connection); } }
@Override public void setDecoderResult(DecoderResult result) { message.setDecoderResult(result); }
/** * Sets the value of the {@code "Connection"} header depending on the * protocol version of the specified message. This getMethod sets or removes * the {@code "Connection"} header depending on what the default keep alive * mode of the message's protocol version is, as specified by * {@link HttpVersion#isKeepAliveDefault()}. * <ul> * <li>If the connection is kept alive by default: * <ul> * <li>set to {@code "close"} if {@code keepAlive} is {@code false}.</li> * <li>remove otherwise.</li> * </ul></li> * <li>If the connection is closed by default: * <ul> * <li>set to {@code "keep-alive"} if {@code keepAlive} is {@code true}.</li> * <li>remove otherwise.</li> * </ul></li> * </ul> * @see #setKeepAlive(HttpHeaders, HttpVersion, boolean) */ public static void setKeepAlive(HttpMessage message, boolean keepAlive) { setKeepAlive(message.headers(), message.protocolVersion(), keepAlive); }
private static void appendCommon(StringBuilder buf, HttpMessage msg) { buf.append(StringUtil.simpleClassName(msg)); buf.append("(decodeResult: "); buf.append(msg.decoderResult()); buf.append(", version: "); buf.append(msg.protocolVersion()); buf.append(')'); buf.append(StringUtil.NEWLINE); }
ctx.write(msg, promise); return; new SimpleChannelPromiseAggregator(promise, ctx.channel(), ctx.executor()); try { Http2ConnectionEncoder encoder = encoder(); currentStreamId = getStreamId(httpMsg.headers()); writeHeaders(ctx, encoder, currentStreamId, httpMsg.headers(), http2Headers, endStream, promiseAggregator); endStream = isLastContent && trailers.isEmpty(); release = false; encoder.writeData(ctx, currentStreamId, content, 0, endStream, promiseAggregator.newPromise()); if (!trailers.isEmpty()) { } finally { if (release) { ReferenceCountUtil.release(msg);
@Override protected void decode(ChannelHandlerContext ctx, HttpObject msg, List<Object> out) throws Exception { if (msg instanceof HttpResponse && ((HttpResponse) msg).status().code() == 100) { out.add(ReferenceCountUtil.retain(msg)); return; out.add(ReferenceCountUtil.retain(msg)); return; cleanup(); final HttpMessage message = (HttpMessage) msg; final HttpHeaders headers = message.headers(); String contentEncoding = headers.get(HttpHeaderNames.CONTENT_ENCODING); if (contentEncoding != null) { contentEncoding = contentEncoding.trim(); if (HttpHeaderValues.IDENTITY.contentEquals(targetContentEncoding)) { " is not a HttpRequest or HttpResponse"); copy.headers().set(message.headers()); copy.setDecoderResult(message.decoderResult()); out.add(copy); } else {
@Override protected void channelRead0(ChannelHandlerContext ctx, HttpMessage msg) throws Exception { // If this handler is hit then no upgrade has been attempted and the client is just talking HTTP. if (LOGGER.isWarnEnabled()) { LOGGER.warn("Directly talking: {} (no upgrade was attempted) from {}", msg.protocolVersion(), NetUtil.toSocketAddressString(ch.remoteAddress())); } ChannelPipeline pipeline = ctx.pipeline(); ChannelHandlerContext thisCtx = pipeline.context(this); // 不需要了 pipeline.addAfter(bizGroup, thisCtx.name(), "Http1ChannelHandler", new Http1ServerChannelHandler(serverHandler)); pipeline.replace(this, "HttpObjectAggregator", new HttpObjectAggregator(maxHttpContentLength)); // HttpServerUpgradeHandler -> HttpServerCodec -> HttpObjectAggregator -> Http1ChannelHandler, ctx.fireChannelRead(ReferenceCountUtil.retain(msg)); } });
/** * Returns the content length of the specified web socket message. If the * specified message is not a web socket message, {@code -1} is returned. */ private static int getWebSocketContentLength(HttpMessage message) { // WebSocket messages have constant content-lengths. HttpHeaders h = message.headers(); if (message instanceof HttpRequest) { HttpRequest req = (HttpRequest) message; if (HttpMethod.GET.equals(req.method()) && h.contains(HttpHeaderNames.SEC_WEBSOCKET_KEY1) && h.contains(HttpHeaderNames.SEC_WEBSOCKET_KEY2)) { return 8; } } else if (message instanceof HttpResponse) { HttpResponse res = (HttpResponse) message; if (res.status().code() == 101 && h.contains(HttpHeaderNames.SEC_WEBSOCKET_ORIGIN) && h.contains(HttpHeaderNames.SEC_WEBSOCKET_LOCATION)) { return 16; } } // Not a web socket message return -1; }
if (null != status && HttpResponseStatus.CONTINUE.codeAsText().contentEquals(status)) { final FullHttpMessage fullMsg = newFullMessage(id, headers, ctx.alloc()); out.add(fullMsg); return; out.add(last); } else { FullHttpMessage full = newFullMessage(id, headers, ctx.alloc()); out.add(full); if (!HttpUtil.isContentLengthSet(req)) { req.headers().add(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED);
@Override public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { LOGGER.info("[Client ({})] => [Server ({})] : {}", connectionInfo.getClientAddr(), connectionInfo.getServerAddr(), msg); if (msg instanceof FullHttpRequest) { HttpMessage httpMessage = (HttpRequest) msg; httpMessage.headers().add(ExtensionHeaderNames.SCHEME.text(), "https"); } else if (msg instanceof HttpObject) { throw new IllegalStateException("Cannot handle message: " + msg.getClass()); } ctx.writeAndFlush(msg, promise); } }
@Override public void channelRead(ChannelHandlerContext ctx, Object e) { if (e instanceof HttpMessage) { HttpMessage m = (HttpMessage) e; // for test there is no Content-Encoding header so just hard // coding value // for verification m.headers().set("X-Original-Content-Encoding", "<original encoding>"); } ctx.fireChannelRead(e); } }
m.headers().set(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED); m.headers().remove(HttpHeaderNames.CONTENT_LENGTH); } else { List<String> encodings = m.headers().getAll(HttpHeaderNames.TRANSFER_ENCODING); if (encodings.isEmpty()) { return; while (valuesIt.hasNext()) { CharSequence value = valuesIt.next(); if (HttpHeaderValues.CHUNKED.contentEqualsIgnoreCase(value)) { valuesIt.remove(); m.headers().remove(HttpHeaderNames.TRANSFER_ENCODING); } else { m.headers().set(HttpHeaderNames.TRANSFER_ENCODING, values);
@Override protected void encode(ChannelHandlerContext ctx, HttpMessage msg, List<Object> out) throws Exception { Integer id = ids.poll(); if (id != null && id.intValue() != NO_ID && !msg.headers().contains(SpdyHttpHeaders.Names.STREAM_ID)) { msg.headers().setInt(Names.STREAM_ID, id); } out.add(ReferenceCountUtil.retain(msg)); }
private static void setTransferEncoding(HttpMessage out) { final io.netty.handler.codec.http.HttpHeaders outHeaders = out.headers(); final long contentLength = HttpUtil.getContentLength(out, -1L); if (contentLength < 0) { // Use chunked encoding. outHeaders.set(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED); outHeaders.remove(HttpHeaderNames.CONTENT_LENGTH); } }
@Override protected void decode(ChannelHandlerContext ctx, Object msg, List<Object> out) throws Exception { if (msg instanceof HttpMessage) { boolean contains = ((HttpMessage) msg).headers().contains(SpdyHttpHeaders.Names.STREAM_ID); if (!contains) { ids.add(NO_ID); } else { ids.add(((HttpMessage) msg).headers().getInt(Names.STREAM_ID)); } } else if (msg instanceof SpdyRstStreamFrame) { ids.remove(((SpdyRstStreamFrame) msg).streamId()); } out.add(ReferenceCountUtil.retain(msg)); } }
/** * Convert the OData Response to Netty Response * @param response * @param odResponse */ static void convertToHttp(final HttpResponse response, final ODataResponse odResponse) { response.setStatus(HttpResponseStatus.valueOf(odResponse.getStatusCode())); for (Entry<String, List<String>> entry : odResponse.getAllHeaders().entrySet()) { for (String headerValue : entry.getValue()) { ((HttpMessage)response).headers().add(entry.getKey(), headerValue); } } if (odResponse.getContent() != null) { copyContent(odResponse.getContent(), response); } else if (odResponse.getODataContent() != null) { writeContent(odResponse, response); } }
/** * Returns the length of the content or the specified default value if the message does not have the {@code * "Content-Length" header}. Please note that this value is not retrieved from {@link HttpContent#content()} but * from the {@code "Content-Length"} header, and thus they are independent from each other. * * @param message the message * @param defaultValue the default value * @return the content length or the specified default value * @throws NumberFormatException if the {@code "Content-Length"} header does not parse as a long */ public static long getContentLength(HttpMessage message, long defaultValue) { String value = message.headers().get(HttpHeaderNames.CONTENT_LENGTH); if (value != null) { return Long.parseLong(value); } // We know the content length if it's a Web Socket message even if // Content-Length header is missing. long webSocketContentLength = getWebSocketContentLength(message); if (webSocketContentLength >= 0) { return webSocketContentLength; } // Otherwise we don't. return defaultValue; }