All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.netty.handler.codec.http.DefaultHttpHeaders Maven / Gradle / Ivy

There is a newer version: 5.0.0.Alpha2
Show newest version
/*
 * Copyright 2012 The Netty Project
 *
 * The Netty Project licenses this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */
package io.netty.handler.codec.http;

import io.netty.handler.codec.CharSequenceValueConverter;
import io.netty.handler.codec.DateFormatter;
import io.netty.handler.codec.DefaultHeaders;
import io.netty.handler.codec.DefaultHeaders.NameValidator;
import io.netty.handler.codec.DefaultHeaders.ValueValidator;
import io.netty.handler.codec.DefaultHeadersImpl;
import io.netty.handler.codec.Headers;
import io.netty.handler.codec.HeadersUtils;
import io.netty.handler.codec.ValueConverter;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import static io.netty.util.AsciiString.CASE_INSENSITIVE_HASHER;
import static io.netty.util.AsciiString.CASE_SENSITIVE_HASHER;

/**
 * Default implementation of {@link HttpHeaders}.
 */
public class DefaultHttpHeaders extends HttpHeaders {
    private final DefaultHeaders headers;

    /**
     * Create a new, empty HTTP headers object.
     * 

* Header names and values are validated as they are added, to ensure they are compliant with the HTTP protocol. */ public DefaultHttpHeaders() { this(nameValidator(true), valueValidator(true)); } /** * Warning! Setting {@code validate} to {@code false} will mean that Netty won't * validate & protect against user-supplied header values that are malicious. * This can leave your server implementation vulnerable to * * CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting') * . * When disabling this validation, it is the responsibility of the caller to ensure that the values supplied * do not contain a non-url-escaped carriage return (CR) and/or line feed (LF) characters. * * @param validate Should Netty validate header values to ensure they aren't malicious. * @deprecated Prefer using the {@link #DefaultHttpHeaders()} constructor instead, * to always have validation enabled. */ @Deprecated public DefaultHttpHeaders(boolean validate) { this(nameValidator(validate), valueValidator(validate)); } /** * Create an HTTP headers object with the given name validator. *

* Warning! It is strongly recommended that the name validator implement validation that is at least as * strict as {@link HttpHeaderValidationUtil#validateToken(CharSequence)}. * It is also strongly recommended that {@code validateValues} is enabled. *

* Without these validations in place, your code can be susceptible to * * CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting') * . * It is the responsibility of the caller to ensure that the values supplied * do not contain a non-url-escaped carriage return (CR) and/or line feed (LF) characters. * * @param validateValues Should Netty validate header values to ensure they aren't malicious. * @param nameValidator The {@link NameValidator} to use, never {@code null. */ protected DefaultHttpHeaders(boolean validateValues, NameValidator nameValidator) { this(nameValidator, valueValidator(validateValues)); } /** * Create an HTTP headers object with the given name and value validators. *

* Warning! It is strongly recommended that the name validator implement validation that is at least as * strict as {@link HttpHeaderValidationUtil#validateToken(CharSequence)}. * And that the value validator is at least as strict as * {@link HttpHeaderValidationUtil#validateValidHeaderValue(CharSequence)}. *

* Without these validations in place, your code can be susceptible to * * CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting') * . * It is the responsibility of the caller to ensure that the values supplied * do not contain a non-url-escaped carriage return (CR) and/or line feed (LF) characters. * * @param nameValidator The {@link NameValidator} to use, never {@code null}. * @param valueValidator The {@link ValueValidator} to use, never {@code null}. */ protected DefaultHttpHeaders( NameValidator nameValidator, ValueValidator valueValidator) { this(nameValidator, valueValidator, 16); } /** * Create an HTTP headers object with the given name and value validators. *

* Warning! It is strongly recommended that the name validator implement validation that is at least as * strict as {@link HttpHeaderValidationUtil#validateToken(CharSequence)}. * And that the value validator is at least as strict as * {@link HttpHeaderValidationUtil#validateValidHeaderValue(CharSequence)}. *

* Without these validations in place, your code can be susceptible to * * CWE-113: Improper Neutralization of CRLF Sequences in HTTP Headers ('HTTP Response Splitting') * . * It is the responsibility of the caller to ensure that the values supplied * do not contain a non-url-escaped carriage return (CR) and/or line feed (LF) characters. * * @param nameValidator The {@link NameValidator} to use, never {@code null}. * @param valueValidator The {@link ValueValidator} to use, never {@code null}. * @param sizeHint A hint about the anticipated number of entries. */ protected DefaultHttpHeaders( NameValidator nameValidator, ValueValidator valueValidator, int sizeHint) { this(new DefaultHeadersImpl( CASE_INSENSITIVE_HASHER, HeaderValueConverter.INSTANCE, nameValidator, sizeHint, valueValidator)); } protected DefaultHttpHeaders(DefaultHeaders headers) { this.headers = headers; } public Headers unwrap() { return headers; } @Override public HttpHeaders add(HttpHeaders headers) { if (headers instanceof DefaultHttpHeaders) { this.headers.add(((DefaultHttpHeaders) headers).headers); return this; } else { return super.add(headers); } } @Override public HttpHeaders set(HttpHeaders headers) { if (headers instanceof DefaultHttpHeaders) { this.headers.set(((DefaultHttpHeaders) headers).headers); return this; } else { return super.set(headers); } } @Override public HttpHeaders add(String name, Object value) { headers.addObject(name, value); return this; } @Override public HttpHeaders add(CharSequence name, Object value) { headers.addObject(name, value); return this; } @Override public HttpHeaders add(String name, Iterable values) { headers.addObject(name, values); return this; } @Override public HttpHeaders add(CharSequence name, Iterable values) { headers.addObject(name, values); return this; } @Override public HttpHeaders addInt(CharSequence name, int value) { headers.addInt(name, value); return this; } @Override public HttpHeaders addShort(CharSequence name, short value) { headers.addShort(name, value); return this; } @Override public HttpHeaders remove(String name) { headers.remove(name); return this; } @Override public HttpHeaders remove(CharSequence name) { headers.remove(name); return this; } @Override public HttpHeaders set(String name, Object value) { headers.setObject(name, value); return this; } @Override public HttpHeaders set(CharSequence name, Object value) { headers.setObject(name, value); return this; } @Override public HttpHeaders set(String name, Iterable values) { headers.setObject(name, values); return this; } @Override public HttpHeaders set(CharSequence name, Iterable values) { headers.setObject(name, values); return this; } @Override public HttpHeaders setInt(CharSequence name, int value) { headers.setInt(name, value); return this; } @Override public HttpHeaders setShort(CharSequence name, short value) { headers.setShort(name, value); return this; } @Override public HttpHeaders clear() { headers.clear(); return this; } @Override public String get(String name) { return get((CharSequence) name); } @Override public String get(CharSequence name) { return HeadersUtils.getAsString(headers, name); } @Override public Integer getInt(CharSequence name) { return headers.getInt(name); } @Override public int getInt(CharSequence name, int defaultValue) { return headers.getInt(name, defaultValue); } @Override public Short getShort(CharSequence name) { return headers.getShort(name); } @Override public short getShort(CharSequence name, short defaultValue) { return headers.getShort(name, defaultValue); } @Override public Long getTimeMillis(CharSequence name) { return headers.getTimeMillis(name); } @Override public long getTimeMillis(CharSequence name, long defaultValue) { return headers.getTimeMillis(name, defaultValue); } @Override public List getAll(String name) { return getAll((CharSequence) name); } @Override public List getAll(CharSequence name) { return HeadersUtils.getAllAsString(headers, name); } @Override public List> entries() { if (isEmpty()) { return Collections.emptyList(); } List> entriesConverted = new ArrayList>( headers.size()); for (Entry entry : this) { entriesConverted.add(entry); } return entriesConverted; } @Deprecated @Override public Iterator> iterator() { return HeadersUtils.iteratorAsString(headers); } @Override public Iterator> iteratorCharSequence() { return headers.iterator(); } @Override public Iterator valueStringIterator(CharSequence name) { final Iterator itr = valueCharSequenceIterator(name); return new Iterator() { @Override public boolean hasNext() { return itr.hasNext(); } @Override public String next() { return itr.next().toString(); } @Override public void remove() { itr.remove(); } }; } @Override public Iterator valueCharSequenceIterator(CharSequence name) { return headers.valueIterator(name); } @Override public boolean contains(String name) { return contains((CharSequence) name); } @Override public boolean contains(CharSequence name) { return headers.contains(name); } @Override public boolean isEmpty() { return headers.isEmpty(); } @Override public int size() { return headers.size(); } @Override public boolean contains(String name, String value, boolean ignoreCase) { return contains((CharSequence) name, (CharSequence) value, ignoreCase); } @Override public boolean contains(CharSequence name, CharSequence value, boolean ignoreCase) { return headers.contains(name, value, ignoreCase ? CASE_INSENSITIVE_HASHER : CASE_SENSITIVE_HASHER); } @Override public Set names() { return HeadersUtils.namesAsString(headers); } @Override public boolean equals(Object o) { return o instanceof DefaultHttpHeaders && headers.equals(((DefaultHttpHeaders) o).headers, CASE_SENSITIVE_HASHER); } @Override public int hashCode() { return headers.hashCode(CASE_SENSITIVE_HASHER); } @Override public HttpHeaders copy() { return new DefaultHttpHeaders(headers.copy()); } static ValueConverter valueConverter() { return HeaderValueConverter.INSTANCE; } static ValueValidator valueValidator(boolean validate) { return validate ? DefaultHttpHeadersFactory.headersFactory().getValueValidator() : DefaultHttpHeadersFactory.headersFactory().withValidation(false).getValueValidator(); } static NameValidator nameValidator(boolean validate) { return validate ? DefaultHttpHeadersFactory.headersFactory().getNameValidator() : DefaultHttpHeadersFactory.headersFactory().withNameValidation(false).getNameValidator(); } private static class HeaderValueConverter extends CharSequenceValueConverter { static final HeaderValueConverter INSTANCE = new HeaderValueConverter(); @Override public CharSequence convertObject(Object value) { if (value instanceof CharSequence) { return (CharSequence) value; } if (value instanceof Date) { return DateFormatter.format((Date) value); } if (value instanceof Calendar) { return DateFormatter.format(((Calendar) value).getTime()); } return value.toString(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy