11/**
2- * Copyright 2012-2020 The Feign Authors
2+ * Copyright 2012-2021 The Feign Authors
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
55 * in compliance with the License. You may obtain a copy of the License at
1313 */
1414package feign .http2client ;
1515
16- import feign .Client ;
17- import feign .Request ;
18- import feign .Request .Options ;
19- import feign .Response ;
20- import feign .Util ;
2116import java .io .ByteArrayInputStream ;
2217import java .io .IOException ;
2318import java .net .URI ;
3227import java .net .http .HttpResponse ;
3328import java .net .http .HttpResponse .BodyHandlers ;
3429import java .time .Duration ;
35- import java .util .*;
30+ import java .util .Arrays ;
31+ import java .util .Collection ;
32+ import java .util .Collections ;
33+ import java .util .HashMap ;
34+ import java .util .HashSet ;
35+ import java .util .List ;
36+ import java .util .Map ;
37+ import java .util .Optional ;
38+ import java .util .OptionalLong ;
39+ import java .util .Set ;
40+ import java .util .TreeSet ;
41+ import java .util .concurrent .CompletableFuture ;
3642import java .util .function .Function ;
3743import java .util .stream .Collectors ;
44+ import feign .AsyncClient ;
45+ import feign .Client ;
46+ import feign .Request ;
47+ import feign .Request .Options ;
48+ import feign .Response ;
49+ import feign .Util ;
3850
39- public class Http2Client implements Client {
51+ public class Http2Client implements Client , AsyncClient < Object > {
4052
4153 private final HttpClient client ;
4254
@@ -59,9 +71,16 @@ public Http2Client(HttpClient client) {
5971
6072 @ Override
6173 public Response execute (Request request , Options options ) throws IOException {
62- final HttpRequest httpRequest = newRequestBuilder (request , options ).build ();
63- HttpClient clientForRequest = getOrCreateClient (options );
74+ final HttpRequest httpRequest ;
75+ try {
76+ httpRequest = newRequestBuilder (request , options )
77+ .version (client .version ())
78+ .build ();
79+ } catch (URISyntaxException e ) {
80+ throw new IOException ("Invalid uri " + request .url (), e );
81+ }
6482
83+ HttpClient clientForRequest = getOrCreateClient (options );
6584 HttpResponse <byte []> httpResponse ;
6685 try {
6786 httpResponse = clientForRequest .send (httpRequest , BodyHandlers .ofByteArray ());
@@ -70,17 +89,37 @@ public Response execute(Request request, Options options) throws IOException {
7089 throw new IOException ("Invalid uri " + request .url (), e );
7190 }
7291
92+ return toFeignResponse (request , httpResponse );
93+ }
94+
95+ @ Override
96+ public CompletableFuture <Response > execute (Request request ,
97+ Options options ,
98+ Optional <Object > requestContext ) {
99+ HttpRequest httpRequest ;
100+ try {
101+ httpRequest = newRequestBuilder (request , options ).build ();
102+ } catch (URISyntaxException e ) {
103+ throw new IllegalArgumentException ("Invalid uri " + request .url (), e );
104+ }
105+
106+ HttpClient clientForRequest = getOrCreateClient (options );
107+ CompletableFuture <HttpResponse <byte []>> future =
108+ clientForRequest .sendAsync (httpRequest , HttpResponse .BodyHandlers .ofByteArray ());
109+ return future .thenApply (httpResponse -> toFeignResponse (request , httpResponse ));
110+ }
111+
112+ protected Response toFeignResponse (Request request , HttpResponse <byte []> httpResponse ) {
73113 final OptionalLong length = httpResponse .headers ().firstValueAsLong ("Content-Length" );
74114
75- final Response response = Response .builder ()
115+ return Response .builder ()
76116 .body (new ByteArrayInputStream (httpResponse .body ()),
77117 length .isPresent () ? (int ) length .getAsLong () : null )
78118 .reason (httpResponse .headers ().firstValue ("Reason-Phrase" ).orElse ("OK" ))
79119 .request (request )
80120 .status (httpResponse .statusCode ())
81121 .headers (castMapCollectType (httpResponse .headers ().map ()))
82122 .build ();
83- return response ;
84123 }
85124
86125 private HttpClient getOrCreateClient (Options options ) {
@@ -116,13 +155,8 @@ private static java.net.http.HttpClient.Builder newClientBuilder(Options options
116155 .connectTimeout (Duration .ofMillis (options .connectTimeoutMillis ()));
117156 }
118157
119- private Builder newRequestBuilder (Request request , Options options ) throws IOException {
120- URI uri ;
121- try {
122- uri = new URI (request .url ());
123- } catch (final URISyntaxException e ) {
124- throw new IOException ("Invalid uri " + request .url (), e );
125- }
158+ private Builder newRequestBuilder (Request request , Options options ) throws URISyntaxException {
159+ URI uri = new URI (request .url ());
126160
127161 final BodyPublisher body ;
128162 final byte [] data = request .body ();
@@ -135,7 +169,7 @@ private Builder newRequestBuilder(Request request, Options options) throws IOExc
135169 final Builder requestBuilder = HttpRequest .newBuilder ()
136170 .uri (uri )
137171 .timeout (Duration .ofMillis (options .readTimeoutMillis ()))
138- .version (Version . HTTP_2 );
172+ .version (client . version () );
139173
140174 final Map <String , Collection <String >> headers = filterRestrictedHeaders (request .headers ());
141175 if (!headers .isEmpty ()) {
0 commit comments