1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.http2.client.http;
20
21 import org.eclipse.jetty.client.HttpContent;
22 import org.eclipse.jetty.client.HttpExchange;
23 import org.eclipse.jetty.client.HttpSender;
24 import org.eclipse.jetty.client.api.Request;
25 import org.eclipse.jetty.http.HttpURI;
26 import org.eclipse.jetty.http.HttpVersion;
27 import org.eclipse.jetty.http.MetaData;
28 import org.eclipse.jetty.http2.api.Stream;
29 import org.eclipse.jetty.http2.frames.DataFrame;
30 import org.eclipse.jetty.http2.frames.HeadersFrame;
31 import org.eclipse.jetty.util.Callback;
32 import org.eclipse.jetty.util.Promise;
33
34 public class HttpSenderOverHTTP2 extends HttpSender
35 {
36 private Stream stream;
37
38 public HttpSenderOverHTTP2(HttpChannelOverHTTP2 channel)
39 {
40 super(channel);
41 }
42
43 @Override
44 protected HttpChannelOverHTTP2 getHttpChannel()
45 {
46 return (HttpChannelOverHTTP2)super.getHttpChannel();
47 }
48
49 @Override
50 protected void sendHeaders(HttpExchange exchange, final HttpContent content, final Callback callback)
51 {
52 final Request request = exchange.getRequest();
53 HttpURI uri = new HttpURI(request.getScheme(), request.getHost(), request.getPort(), request.getPath(), null, request.getQuery(), null);
54 MetaData.Request metaData = new MetaData.Request(request.getMethod(), uri, HttpVersion.HTTP_2, request.getHeaders());
55 HeadersFrame headersFrame = new HeadersFrame(metaData, null, !content.hasContent());
56 HttpChannelOverHTTP2 channel = getHttpChannel();
57 Promise<Stream> promise = new Promise<Stream>()
58 {
59 @Override
60 public void succeeded(Stream stream)
61 {
62 HttpSenderOverHTTP2.this.stream = stream;
63 stream.setIdleTimeout(request.getIdleTimeout());
64
65 if (content.hasContent() && !expects100Continue(request))
66 {
67 boolean advanced = content.advance();
68 boolean lastContent = content.isLast();
69 if (advanced || lastContent)
70 {
71 DataFrame dataFrame = new DataFrame(stream.getId(), content.getByteBuffer(), lastContent);
72 stream.data(dataFrame, callback);
73 return;
74 }
75 }
76 callback.succeeded();
77 }
78
79 @Override
80 public void failed(Throwable failure)
81 {
82 callback.failed(failure);
83 }
84 };
85
86 channel.getSession().newStream(headersFrame, promise, channel.getStreamListener());
87 }
88
89 @Override
90 protected void sendContent(HttpExchange exchange, HttpContent content, Callback callback)
91 {
92 if (content.isConsumed())
93 {
94 callback.succeeded();
95 }
96 else
97 {
98 DataFrame frame = new DataFrame(stream.getId(), content.getByteBuffer(), content.isLast());
99 stream.data(frame, callback);
100 }
101 }
102
103 @Override
104 protected void reset()
105 {
106 super.reset();
107 stream = null;
108 }
109 }