Nils Renaud created HTTPCLIENT-2197:
---------------------------------------

             Summary: HTTP client should not accept to send requests nor 
receive responses with illegal header names
                 Key: HTTPCLIENT-2197
                 URL: https://issues.apache.org/jira/browse/HTTPCLIENT-2197
             Project: HttpComponents HttpClient
          Issue Type: Bug
    Affects Versions: 5.1.2, 4.5.13
            Reporter: Nils Renaud


h1. Description
Currently the HTTP client (both 1.1 and 2.0) permits to :
- send an HTTP request with an illegal header name
- receive an HTTP response with an illegal header name

h1. Expected behaviour

- The HttpClient should reject such request either during request creation or 
request sending.
- The HttpClient should not accept HTTP responses containing illegal HTTP 
headers.

h1. The HTTP specification

The [HTTP 1.1 RFC|https://datatracker.ietf.org/doc/html/rfc7230#appendix-B] 
says (reordered) :
{noformat}
header-field = field-name ":" OWS field-value OWS
field-name = token
token = 1*tchar
tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." /
 "^" / "_" / "`" / "|" / "~" / DIGIT / ALPHA
{noformat}

And also in [section 3|https://datatracker.ietf.org/doc/html/rfc7230#section-3] 
:
{noformat}
A recipient MUST parse an HTTP message as a sequence of octets in an
encoding that is a superset of US-ASCII [USASCII].
{noformat}

And then [HTTP/2.0 
RFC|https://datatracker.ietf.org/doc/html/rfc7540#section-8.1.2] says : 
{noformat}
Just as in HTTP/1.x, header field names are strings of ASCII
characters that are compared in a case-insensitive fashion.  However,
header field names MUST be converted to lowercase prior to their
encoding in HTTP/2.
{noformat}

h1. Reproducer

I've created an HTTP Client and server both sending this illegal header name : 
😱 (coded as "\uD83D\uDE31" in Java convention)

Here is the Client part I used to reproduce the issue : 

{code:java}
try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
    HttpGet httpGet = new HttpGet("http://localhost:8282/";);
    httpGet.addHeader("\uD83D\uDE31", "aa");
    try (CloseableHttpResponse response1 = httpclient.execute(httpGet)) {
    // Sends header "??: aa"
        for (final Header header : response1.getHeaders()) {
            System.out.println(header.getName() + ": " + header.getValue());
            // print header : "😱: aaa"
        }
        System.out.println(response1.getCode() + " " + 
response1.getReasonPhrase());
    }
}
{code}

And the server code : 

{code:java}
ServerSocket server = new ServerSocket(8282, 1, InetAddress.getLocalHost());
while (true) {
    System.out.println("WAITING");
    Socket client = server.accept();
    System.out.println("RECEIVED");
    String content = "HTTP/1.1 200 OK\r\n"
        + "\uD83D\uDE31: aaa\r\n"
        + "Content-Length: 2\r\n"
        + "\r\n"
        + "OK";
    client.getOutputStream().write(content.getBytes(StandardCharsets.UTF_8));
    client.getOutputStream().flush();
    client.close();
}
{code}




--
This message was sent by Atlassian Jira
(v8.20.1#820001)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to