[ 
https://issues.apache.org/jira/browse/HTTPCLIENT-2197?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17477873#comment-17477873
 ] 

Nils Renaud commented on HTTPCLIENT-2197:
-----------------------------------------

Almost, `httpClient.execute(...)`  : 
- fails for a non-USASCII character either in the request or response headers 
(that's good)
- succeed for a illegal header name character such as `=` (that does not comply 
with the spec)

Moreover, it's not really easy to set that option to the httpClient : 
{code:java}
@Test
    void shouldFailOnInvalidHeaderName() throws Exception {
        final CharCodingConfig strict = CharCodingConfig.custom()
                                                        
.setMalformedInputAction(CodingErrorAction.REPORT)
                                                        
.setUnmappableInputAction(CodingErrorAction.REPORT)
                                                        
.setCharset(StandardCharsets.US_ASCII)
                                                        .build();
        final HttpConnectionFactory<ManagedHttpClientConnection> 
connectionFactory =
                new ManagedHttpClientConnectionFactory(Http1Config.DEFAULT,
                                                       strict,
                                                       new 
DefaultHttpRequestWriterFactory(),
                                                       new 
DefaultHttpResponseParserFactory());
        HttpClientConnectionManager manager = new 
BasicHttpClientConnectionManager(getDefaultRegistry(),
                                                                                
   connectionFactory);

        try (CloseableHttpClient httpclient = 
HttpClients.custom().setConnectionManager(manager).build()) {
            HttpGet httpGet = new HttpGet("http://localhost:8282/";);
            httpGet.addHeader("=", "aa");
            httpclient.execute(httpGet); // Should throw exception on "=" or "😱"
        }
    }

    // I copied/pasted this from the BasicHttpClientConnectionManager, it would 
be better to avoid that.
    private static Registry<ConnectionSocketFactory> getDefaultRegistry() {
        return RegistryBuilder.<ConnectionSocketFactory>create()
                              .register(URIScheme.HTTP.id, 
PlainConnectionSocketFactory.getSocketFactory())
                              .register(URIScheme.HTTPS.id, 
SSLConnectionSocketFactory.getSocketFactory())
                              .build();
    }
{code}

 But thanks for pointing at this settings anyway [~olegk] ! I guess I could 
write my own {{HttpRequestWriterFactory}} and {{HttpResponseParserFactory}} to 
catch the US-ASCII illegal characters, but that starts to be quite complex at 
this point.

So I would love to have something like {{HttpClients.strict()}} available.

> 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: Wish
>    Affects Versions: 4.5.13, 5.1.2
>            Reporter: Nils Renaud
>            Priority: Minor
>
> 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