View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.hc.core5.testing.nio;
29  
30  import java.io.IOException;
31  
32  import org.apache.hc.core5.http.HeaderElements;
33  import org.apache.hc.core5.http.HttpException;
34  import org.apache.hc.core5.http.HttpHeaders;
35  import org.apache.hc.core5.http.HttpRequest;
36  import org.apache.hc.core5.http.HttpResponse;
37  import org.apache.hc.core5.http.URIScheme;
38  import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
39  import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
40  import org.apache.hc.core5.http.impl.bootstrap.StandardFilter;
41  import org.apache.hc.core5.http.nio.AsyncEntityProducer;
42  import org.apache.hc.core5.http.nio.AsyncFilterChain;
43  import org.apache.hc.core5.http.nio.AsyncPushProducer;
44  import org.apache.hc.core5.http.protocol.UriPatternMatcher;
45  import org.apache.hc.core5.reactor.IOReactorConfig;
46  import org.apache.hc.core5.testing.extension.SocksProxyResource;
47  import org.apache.hc.core5.testing.nio.extension.HttpAsyncRequesterResource;
48  import org.apache.hc.core5.testing.nio.extension.HttpAsyncServerResource;
49  import org.apache.hc.core5.util.Timeout;
50  import org.junit.jupiter.api.Order;
51  import org.junit.jupiter.api.extension.RegisterExtension;
52  
53  public abstract class Http1SocksProxyCoreTransportTest extends HttpCoreTransportTest {
54  
55      private static final Timeout TIMEOUT = Timeout.ofMinutes(1);
56  
57      @RegisterExtension
58      @Order(-Integer.MAX_VALUE)
59      private final SocksProxyResource proxyResource;
60      @RegisterExtension
61      private final HttpAsyncServerResource serverResource;
62      @RegisterExtension
63      private final HttpAsyncRequesterResource clientResource;
64  
65      public Http1SocksProxyCoreTransportTest(final URIScheme scheme) {
66          super(scheme);
67          this.proxyResource = new SocksProxyResource();
68          this.serverResource = new HttpAsyncServerResource(bootstrap -> bootstrap
69                  .setIOReactorConfig(
70                          IOReactorConfig.custom()
71                                  .setSoTimeout(TIMEOUT)
72                                  .build())
73                  .setLookupRegistry(new UriPatternMatcher<>())
74                  .register("*", () -> new EchoHandler(2048))
75                  .addFilterBefore(StandardFilter.MAIN_HANDLER.name(), "no-keepalive", (request, entityDetails, context, responseTrigger, chain) ->
76                          chain.proceed(request, entityDetails, context, new AsyncFilterChain.ResponseTrigger() {
77  
78                              @Override
79                              public void sendInformation(
80                                      final HttpResponse response) throws HttpException, IOException {
81                                  responseTrigger.sendInformation(response);
82                              }
83  
84                              @Override
85                              public void submitResponse(
86                                      final HttpResponse response,
87                                      final AsyncEntityProducer entityProducer) throws HttpException, IOException {
88                                  if (request.getPath().startsWith("/no-keep-alive")) {
89                                      response.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
90                                  }
91                                  responseTrigger.submitResponse(response, entityProducer);
92                              }
93  
94                              @Override
95                              public void pushPromise(
96                                      final HttpRequest promise,
97                                      final AsyncPushProducer responseProducer) throws HttpException, IOException {
98                                  responseTrigger.pushPromise(promise, responseProducer);
99                              }
100 
101                         }))
102         );
103         this.clientResource = new HttpAsyncRequesterResource(bootstrap -> bootstrap
104                 .setIOReactorConfig(IOReactorConfig.custom()
105                         .setSocksProxyAddress(proxyResource.proxy().getProxyAddress())
106                         .setSoTimeout(TIMEOUT)
107                         .build())
108         );
109     }
110 
111     @Override
112     HttpAsyncServer serverStart() throws IOException {
113         return serverResource.start();
114     }
115 
116     @Override
117     HttpAsyncRequester clientStart() {
118         return clientResource.start();
119     }
120 
121 }