/** Sets the {@code "Date"} header. */ public static void setDate(HttpMessage message, Date value) { if (value != null) { message.headers().set(Names.DATE, HttpHeaderDateFormat.get().format(value)); } else { message.headers().set(Names.DATE, null); } }
/** * Sets or removes the {@code "Expect: 100-continue"} header to / from the specified message. If * the specified {@code value} is {@code true}, the {@code "Expect: 100-continue"} header is set * and all other previous {@code "Expect"} headers are removed. Otherwise, all {@code "Expect"} * headers are removed completely. */ public static void set100ContinueExpected(HttpMessage message, boolean set) { if (set) { message.headers().set(Names.EXPECT, Values.CONTINUE); } else { message.headers().remove(Names.EXPECT); } }
/** * Sets a new date header with the specified name and value. If there is an existing header with * the same name, the existing header is removed. The specified value is formatted as defined in * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1">RFC2616</a> */ public static void setDateHeader(HttpMessage message, CharSequence name, Date value) { if (value != null) { message.headers().set(name, HttpHeaderDateFormat.get().format(value)); } else { message.headers().set(name, null); } }
/** * 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) { String connection = message.headers().get(Names.CONNECTION); if (connection != null && equalsIgnoreCase(Values.CLOSE, connection)) { return false; } if (message.getProtocolVersion().isKeepAliveDefault()) { return !equalsIgnoreCase(Values.CLOSE, connection); } else { return equalsIgnoreCase(Values.KEEP_ALIVE, connection); } }
/** * Returns the header value with the specified header name. If there are more than one header * value for the specified header name, the first value is returned. * * @return the header value or the {@code defaultValue} if there is no such header */ public static String getHeader(HttpMessage message, CharSequence name, String defaultValue) { String value = message.headers().get(name); if (value == null) { return defaultValue; } return value; }
/** * 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>remove otherwise. * </ul> * <li>If the connection is closed by default: * <ul> * <li>set to {@code "keep-alive"} if {@code keepAlive} is {@code true}. * <li>remove otherwise. * </ul> * </ul> */ public static void setKeepAlive(HttpMessage message, boolean keepAlive) { HttpHeaders h = message.headers(); if (message.getProtocolVersion().isKeepAliveDefault()) { if (keepAlive) { h.remove(Names.CONNECTION); } else { h.set(Names.CONNECTION, Values.CLOSE); } } else { if (keepAlive) { h.set(Names.CONNECTION, Values.KEEP_ALIVE); } else { h.remove(Names.CONNECTION); } } }
public static void removeTransferEncodingChunked(HttpMessage m) { List<String> values = m.headers().getAll(Names.TRANSFER_ENCODING); if (values.isEmpty()) { return; } Iterator<String> valuesIt = values.iterator(); while (valuesIt.hasNext()) { String value = valuesIt.next(); if (equalsIgnoreCase(value, Values.CHUNKED)) { valuesIt.remove(); } } if (values.isEmpty()) { m.headers().remove(Names.TRANSFER_ENCODING); } else { m.headers().set(Names.TRANSFER_ENCODING, values); } }
/** * Returns {@code true} if and only if the specified message contains the {@code "Expect: * 100-continue"} header. */ public static boolean is100ContinueExpected(HttpMessage message) { // Expect: 100-continue is for requests only. if (!(message instanceof HttpRequest)) { return false; } // It works only on HTTP/1.1 or later. if (message.getProtocolVersion().compareTo(HttpVersion.HTTP_1_1) < 0) { return false; } // In most cases, there will be one or zero 'Expect' header. String value = message.headers().get(Names.EXPECT); if (value == null) { return false; } if (equalsIgnoreCase(Values.CONTINUE, value)) { return true; } // Multiple 'Expect' headers. Search through them. return message.headers().contains(Names.EXPECT, Values.CONTINUE, true); }
/** * Returns the length of the content. 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. * * @return the content length or {@code defaultValue} if this message does not have the {@code * "Content-Length"} header or its value is not a number */ public static long getContentLength(HttpMessage message, long defaultValue) { String contentLength = message.headers().get(Names.CONTENT_LENGTH); if (contentLength != null) { try { return Long.parseLong(contentLength); } catch (NumberFormatException e) { return defaultValue; } } // 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; }
/** * 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) { // WebSockset messages have constant content-lengths. HttpHeaders h = message.headers(); if (message instanceof HttpRequest) { HttpRequest req = (HttpRequest) message; if (HttpMethod.GET.equals(req.getMethod()) && h.contains(Names.SEC_WEBSOCKET_KEY1) && h.contains(Names.SEC_WEBSOCKET_KEY2)) { return 8; } } else if (message instanceof HttpResponse) { HttpResponse res = (HttpResponse) message; if (res.getStatus().code() == 101 && h.contains(Names.SEC_WEBSOCKET_ORIGIN) && h.contains(Names.SEC_WEBSOCKET_LOCATION)) { return 16; } } // Not a web socket message return -1; }
/** * Sets a new date header with the specified name and values. If there is an existing header with * the same name, the existing header is removed. The specified values are formatted as defined in * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1">RFC2616</a> */ public static void setDateHeader(HttpMessage message, CharSequence name, Iterable<Date> values) { message.headers().set(name, values); }
/** * Returns the header value with the specified header name. If there are more than one header * value for the specified header name, the first value is returned. * * @return the header value or {@code null} if there is no such header */ public static String getHeader(HttpMessage message, CharSequence name) { return message.headers().get(name); }
/** Sets the {@code "Host"} header. */ public static void setHost(HttpMessage message, CharSequence value) { message.headers().set(Names.HOST, value); }
/** Returns the value of the {@code "Host"} header. */ public static String getHost(HttpMessage message) { return message.headers().get(Names.HOST); }
/** Sets the {@code "Content-Length"} header. */ public static void setContentLength(HttpMessage message, long length) { message.headers().set(Names.CONTENT_LENGTH, length); }
/** * Sets a new header with the specified name and value. If there is an existing header with the * same name, the existing header is removed. If the specified value is not a {@link String}, it * is converted into a {@link String} by {@link Object#toString()}, except for {@link Date} and * {@link Calendar} which are formatted to the date format defined in <a * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1">RFC2616</a>. */ public static void setHeader(HttpMessage message, CharSequence name, Object value) { message.headers().set(name, value); }
/** Removes the header with the specified name. */ public static void removeHeader(HttpMessage message, CharSequence name) { message.headers().remove(name); }
/** Removes all headers from the specified message. */ public static void clearHeaders(HttpMessage message) { message.headers().clear(); }
/** Adds a new integer header with the specified name and value. */ public static void addIntHeader(HttpMessage message, CharSequence name, int value) { message.headers().add(name, value); }
/** * Sets a new integer header with the specified name and values. If there is an existing header * with the same name, the existing header is removed. */ public static void setIntHeader( HttpMessage message, CharSequence name, Iterable<Integer> values) { message.headers().set(name, values); }
/** * Checks to see if the transfer encoding in a specified {@link HttpMessage} is chunked * * @param message The message to check * @return True if transfer encoding is chunked, otherwise false */ public static boolean isTransferEncodingChunked(HttpMessage message) { return message.headers().contains(Names.TRANSFER_ENCODING, Values.CHUNKED, true); }
/** * Adds a new date header with the specified name and value. The specified value is formatted as * defined in <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1">RFC2616</a> */ public static void addDateHeader(HttpMessage message, CharSequence name, Date value) { message.headers().add(name, value); }
public static boolean isContentLengthSet(HttpMessage m) { return m.headers().contains(Names.CONTENT_LENGTH); }
private static void encodeHeaders(ByteBuf buf, HttpMessage message) { for (Map.Entry<String, String> h : message.headers()) { encodeHeader(buf, h.getKey(), h.getValue()); } }