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

Oleg Kalnichevski commented on HTTPCORE-689:
--------------------------------------------

[~andressolm96] The same example with just minor modifications works for me as 
expected.

Oleg
{code:java}
        if (args.length < 1) {
            System.err.println("Please specify document root directory");
            System.exit(1);
        }
        // Document root directory
        final File docRoot = new File(args[0]);
        int port = 8080;
        if (args.length >= 2) {
            port = Integer.parseInt(args[1]);
        }

        final URL resource1 = 
AsyncFileServerExample.class.getResource("/test-server.p12");
        final String storePassword = "nopassword";
        final String keyPassword = "nopassword";
        final SSLContext serverSslContext = SSLContextBuilder.create()
                .loadKeyMaterial(resource1, storePassword.toCharArray(), 
keyPassword.toCharArray())
                .build();

        final IOReactorConfig config = IOReactorConfig.custom()
                .setSoTimeout(15, TimeUnit.SECONDS)
                .setTcpNoDelay(true)
                .build();

        final HttpAsyncServer server = AsyncServerBootstrap.bootstrap()
                .setIOReactorConfig(config)
                .setTlsStrategy(new BasicServerTlsStrategy(serverSslContext, 
new SSLSessionVerifier() {

                    @Override
                    public TlsDetails verify(final NamedEndpoint endpoint, 
final SSLEngine sslEngine) throws SSLException {
                        return new TlsDetails(sslEngine.getSession(), 
sslEngine.getApplicationProtocol());
                    }

                }))
                .register("*", new 
AsyncServerRequestHandler<Message<HttpRequest, Void>>() {

                    @Override
                    public AsyncRequestConsumer<Message<HttpRequest, Void>> 
prepare(
                            final HttpRequest request,
                            final EntityDetails entityDetails,
                            final HttpContext context) throws HttpException {
                        return new BasicRequestConsumer<>(entityDetails != null 
? new NoopEntityConsumer() : null);
                    }

                    @Override
                    public void handle(
                            final Message<HttpRequest, Void> message,
                            final ResponseTrigger responseTrigger,
                            final HttpContext context) throws HttpException, 
IOException {
                        final HttpRequest request = message.getHead();
                        final URI requestUri;
                        try {
                            requestUri = request.getUri();
                        } catch (final URISyntaxException ex) {
                            throw new ProtocolException(ex.getMessage(), ex);
                        }
                        final String path = requestUri.getPath();
                        final File file = new File(docRoot, path);
                        if (!file.exists()) {

                            final String msg = "File " + file.getPath() + " not 
found";
                            println(msg);
                            responseTrigger.submitResponse(
                                    
AsyncResponseBuilder.create(HttpStatus.SC_NOT_FOUND)
                                            .setEntity("<html><body><h1>" + msg 
+ "</h1></body></html>", ContentType.TEXT_HTML)
                                            .build(),
                                    context);

                        } else if (!file.canRead() || file.isDirectory()) {

                            final String msg = "Cannot read file " + 
file.getPath();
                            println(msg);
                            
responseTrigger.submitResponse(AsyncResponseBuilder.create(HttpStatus.SC_FORBIDDEN)
                                            .setEntity("<html><body><h1>" + msg 
+ "</h1></body></html>", ContentType.TEXT_HTML)
                                            .build(),
                                    context);

                        } else {

                            final ContentType contentType;
                            final String filename = 
file.getName().toLowerCase(Locale.ROOT);
                            if (filename.endsWith(".txt")) {
                                contentType = ContentType.TEXT_PLAIN;
                            } else if (filename.endsWith(".html") || 
filename.endsWith(".htm")) {
                                contentType = ContentType.TEXT_HTML;
                            } else if (filename.endsWith(".xml")) {
                                contentType = ContentType.TEXT_XML;
                            } else {
                                contentType = ContentType.DEFAULT_BINARY;
                            }

                            final HttpCoreContext coreContext = 
HttpCoreContext.adapt(context);
                            final EndpointDetails endpoint = 
coreContext.getEndpointDetails();

                            println(endpoint + " | serving file " + 
file.getPath());

                            responseTrigger.submitResponse(
                                    
AsyncResponseBuilder.create(HttpStatus.SC_OK)
                                            
.setEntity(AsyncEntityProducers.create(file, contentType))
                                            .build(),
                                    context);
                        }
                    }

                })
                .create();

        Runtime.getRuntime().addShutdownHook(new Thread() {
            @Override
            public void run() {
                println("HTTP server shutting down");
                server.close(CloseMode.GRACEFUL);
            }
        });

        server.start();
        final Future<ListenerEndpoint> future = server.listen(new 
InetSocketAddress(port), URIScheme.HTTPS);
        final ListenerEndpoint listenerEndpoint = future.get();
        println("Listening on " + listenerEndpoint.getAddress());
        server.awaitShutdown(TimeValue.MAX_VALUE);
    }

    static final void println(final String msg) {
        System.out.println(HttpDateGenerator.INSTANCE.getCurrentDate() + " | " 
+ msg);
    }
{code}
{noformat}
$ curl -k https://localhost:8080/test.txt -v
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* 
  Trying ::1:8080...
* Connected to localhost (::1) port 8080 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt
  CApath: none
} [5 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [193 bytes data]
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
} [1 bytes data]
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
} [512 bytes data]
* TLSv1.3 (IN), TLS handshake, Server hello (2):
{ [155 bytes data]
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
{ [28 bytes data]
* TLSv1.3 (IN), TLS handshake, Certificate (11):
{ [1985 bytes data]
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
{ [264 bytes data]
* TLSv1.3 (IN), TLS handshake, Finished (20):
{ [52 bytes data]
* TLSv1.3 (OUT), TLS handshake, Finished (20):
} [52 bytes data]
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
*  subject: O=Apache Software Foundation; OU=HttpComponents Project; CN=Test 
Server
*  start date: Oct 11 15:56:37 2019 GMT
*  expire date: Jul 26 15:56:37 2293 GMT
*  issuer: O=Apache Software Foundation; OU=HttpComponents Project; CN=Test CA; 
[email protected]
*  SSL certificate verify result: self signed certificate in certificate chain 
(19), continuing anyway.
} [5 bytes data]
> GET /test.txt HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.71.1
> Accept: */*
>
{ [5 bytes data]
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
{ [50 bytes data]
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Thu, 28 Oct 2021 07:51:19 GMT
< Server: Apache-HttpCore/5.1.3-SNAPSHOT (Java/11.0.9)
< Content-Length: 5
< Content-Type: text/plain; charset=ISO-8859-1
<
{ [5 bytes data]
100     5  100     5    0     0     31      0 --:--:-- --:--:-- --:--:--    
31BLAH!
* Connection #0 to host localhost left intact
{noformat}

> HttpAsyncServer with TLsStrategy Error in BasicParseLine
> --------------------------------------------------------
>
>                 Key: HTTPCORE-689
>                 URL: https://issues.apache.org/jira/browse/HTTPCORE-689
>             Project: HttpComponents HttpCore
>          Issue Type: Bug
>          Components: Examples, HttpCore
>    Affects Versions: 5.1
>         Environment: Mac OS 11.6 / Maven 3.8.1 / AdoptOpenJDK-11.0.11+9
>            Reporter: Andres
>            Priority: Major
>
> I've being followed the example in 
> [https://github.com/apache/httpcomponents-core/blob/5.1.x/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFileServerExample.java]
> This example is working as expected. However when I try to implement a 
> SSLContext with the method:
> {code:java}
> final HttpAsyncServer server = 
> AsyncServerBootstrap.bootstrap().setIOReactorConfig(config)                
> .setTlsStrategy(new BasicServerTlsStrategy(sslContext))
> ...
> {code}
> After triggering a http request, the parseLine is failing with:
> {code:java}
> Exception has occurred: 
> org.apache.hc.core5.http.ParseException"org.apache.hc.core5.http.ParseException:
>  Invalid request line; error at offset 31: 
> <[0x2b][0x2c][0x2d][0x2e]ß[0x30][0x31][0x32]Û[0x34][0x35]WåT¾±)•âJ3Ëɇ€k{Eµ’>"
> {code}
> I'm not sure if the HTTPS (TLS) handshake is not working as expected in the 
> non-blocking message transport classes, because SSLContext it's working fine 
> in booking classes.
> Or could you provide an example to create a HttpAsyncServer with HTTPS (TLS)



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

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

Reply via email to