<div dir="ltr">Yes. It is another Undertow server with HTTP 2.0 enabled. I can build a repo with two servers to reproduce the issue if it is necessary. <div><br></div><div>Thanks,</div><div><br></div><div>Steve</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Aug 28, 2017 at 10:43 PM, Stuart Douglas <span dir="ltr"><<a href="mailto:sdouglas@redhat.com" target="_blank">sdouglas@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">What is the endpoint that you are trying to connect to? Is it another<br>
Undertow server?<br>
<span class="HOEnZb"><font color="#888888"><br>
Stuart<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
On Tue, Aug 29, 2017 at 12:17 PM, Steve Hu <<a href="mailto:stevehu@gmail.com">stevehu@gmail.com</a>> wrote:<br>
> Hi Stuart,<br>
><br>
> Thanks for the quick reply. I have opened an issue<br>
> <a href="https://issues.jboss.org/browse/UNDERTOW-1170" rel="noreferrer" target="_blank">https://issues.jboss.org/<wbr>browse/UNDERTOW-1170</a><br>
><br>
> Also, I have tried your workaround with h2c-prior:// but got the following<br>
> error in the callback.<br>
><br>
> java.nio.channels.<wbr>ClosedChannelException<br>
> at<br>
> io.undertow.protocols.http2.<wbr>Http2Channel.createStream(<wbr>Http2Channel.java:827)<br>
> at<br>
> io.undertow.client.http2.<wbr>Http2ClientConnection.<wbr>sendRequest(<wbr>Http2ClientConnection.java:<wbr>195)<br>
> at<br>
> com.networknt.apic.handler.<wbr>DataGetHandler.handleRequest(<wbr>DataGetHandler.java:57)<br>
><br>
><br>
> On Mon, Aug 28, 2017 at 9:50 PM, Stuart Douglas <<a href="mailto:sdouglas@redhat.com">sdouglas@redhat.com</a>> wrote:<br>
>><br>
>> This looks like a bug in the client with regards to how it handles<br>
>> HTTP upgrade. If the second request is added before the initial<br>
>> upgrade request is fully processed you can get this error.<br>
>><br>
>> If you file a JIRA I will look into it. For now a possible workaround<br>
>> would be to use prior knowledge rather than upgrade (by using a URL of<br>
>> the form h2c-prior://target:p8080/<wbr>whatever).<br>
>><br>
>> Stuart<br>
>><br>
>> On Tue, Aug 29, 2017 at 11:25 AM, Steve Hu <<a href="mailto:stevehu@gmail.com">stevehu@gmail.com</a>> wrote:<br>
>> > Hi,<br>
>> ><br>
>> > I am trying to use UndertowClient to call another service in the current<br>
>> > service handleRequest using HTTP 2.0. If I have concurrent requests to<br>
>> > the<br>
>> > current service, then I will get the following error.<br>
>> ><br>
>> > java.io.IOException: UT001033: Invalid connection state<br>
>> > at<br>
>> ><br>
>> > io.undertow.client.http.<wbr>HttpClientConnection.<wbr>sendRequest(<wbr>HttpClientConnection.java:336)<br>
>> ><br>
>> > Since HTTP 2.0 connection is multiplex, so I use instance variables for<br>
>> > UndertowClient instance and ClientConnection instance and don't close<br>
>> > the<br>
>> > connection for each call.<br>
>> ><br>
>> > My question is how many requests can go through the same connection? Is<br>
>> > the<br>
>> > Invalid connection state caused by too many requests in the same<br>
>> > connection?<br>
>> > If yes, I can use a connection pool just like the HTTP 1.1. Also, is it<br>
>> > possible that the server will close the connection if it is idle for a<br>
>> > period of time?<br>
>> ><br>
>> > Here is the handler code for reference.<br>
>> ><br>
>> > public class DataGetHandler implements HttpHandler {<br>
>> > UndertowClient client = UndertowClient.getInstance();<br>
>> > ClientConnection connection;<br>
>> ><br>
>> > @Override<br>
>> > public void handleRequest(<wbr>HttpServerExchange exchange) throws<br>
>> > Exception<br>
>> > {<br>
>> > List<String> list = new ArrayList<>();<br>
>> > final CountDownLatch latch = new CountDownLatch(1);<br>
>> > if(connection == null) {<br>
>> > try {<br>
>> > connection = client.connect(new URI(apidHost),<br>
>> > Http2Client.WORKER, Http2Client.SSL, Http2Client.POOL, enableHttp2 ?<br>
>> > OptionMap.create(<wbr>UndertowOptions.ENABLE_HTTP2, true):<br>
>> > OptionMap.EMPTY).get();<br>
>> > } catch (Exception e) {<br>
>> > logger.error("Exeption:", e);<br>
>> > throw new ClientException(e);<br>
>> > }<br>
>> > }<br>
>> > final AtomicReference<<wbr>ClientResponse> reference = new<br>
>> > AtomicReference<>();<br>
>> > try {<br>
>> > ClientRequest request = new<br>
>> > ClientRequest().setMethod(<wbr>Methods.GET).setPath(apidPath)<wbr>;<br>
>> > connection.sendRequest(<wbr>request,<br>
>> > client.createClientCallback(<wbr>reference, latch));<br>
>> > latch.await();<br>
>> > int statusCode = reference.get().<wbr>getResponseCode();<br>
>> > if(statusCode >= 300){<br>
>> > throw new Exception("Failed to call API D: " +<br>
>> > statusCode);<br>
>> > }<br>
>> > List<String> apidList =<br>
>> ><br>
>> > Config.getInstance().<wbr>getMapper().readValue(<wbr>reference.get().getAttachment(<wbr>Http2Client.RESPONSE_BODY),<br>
>> > new TypeReference<List<String>>(){<wbr>});<br>
>> > list.addAll(apidList);<br>
>> > } catch (Exception e) {<br>
>> > logger.error("Exception:", e);<br>
>> > throw new ClientException(e);<br>
>> > }<br>
>> > list.add("API C: Message 1");<br>
>> > list.add("API C: Message 2");<br>
>> ><br>
>> ><br>
>> > exchange.getResponseSender().<wbr>send(Config.getInstance().<wbr>getMapper().<wbr>writeValueAsString(list));<br>
>> > }<br>
>> > }<br>
>> ><br>
>> ><br>
>> > ______________________________<wbr>_________________<br>
>> > undertow-dev mailing list<br>
>> > <a href="mailto:undertow-dev@lists.jboss.org">undertow-dev@lists.jboss.org</a><br>
>> > <a href="https://lists.jboss.org/mailman/listinfo/undertow-dev" rel="noreferrer" target="_blank">https://lists.jboss.org/<wbr>mailman/listinfo/undertow-dev</a><br>
><br>
><br>
</div></div></blockquote></div><br></div>