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 java.net.URI;
22
23 import org.eclipse.jetty.client.HttpContent;
24 import org.eclipse.jetty.client.HttpExchange;
25 import org.eclipse.jetty.client.HttpSender;
26 import org.eclipse.jetty.client.api.Request;
27 import org.eclipse.jetty.http.HttpURI;
28 import org.eclipse.jetty.http.HttpVersion;
29 import org.eclipse.jetty.http.MetaData;
30 import org.eclipse.jetty.http2.api.Stream;
31 import org.eclipse.jetty.http2.frames.DataFrame;
32 import org.eclipse.jetty.http2.frames.HeadersFrame;
33 import org.eclipse.jetty.util.Callback;
34 import org.eclipse.jetty.util.Promise;
35
36 public class HttpSenderOverHTTP2 extends HttpSender
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 Request request = exchange.getRequest();
53 String path = relativize(request.getPath());
54 HttpURI uri = new HttpURI(request.getScheme(), request.getHost(), request.getPort(), path, null, request.getQuery(), null);
55 MetaData.Request metaData = new MetaData.Request(request.getMethod(), uri, HttpVersion.HTTP_2, request.getHeaders());
56 HeadersFrame headersFrame = new HeadersFrame(metaData, null, !content.hasContent());
57 HttpChannelOverHTTP2 channel = getHttpChannel();
58 Promise<Stream> promise = new Promise<Stream>()
59 {
60 @Override
61 public void succeeded(Stream stream)
62 {
63 getHttpChannel().setStream(stream);
64 stream.setIdleTimeout(request.getIdleTimeout());
65
66 if (content.hasContent() && !expects100Continue(request))
67 {
68 boolean advanced = content.advance();
69 boolean lastContent = content.isLast();
70 if (advanced || lastContent)
71 {
72 DataFrame dataFrame = new DataFrame(stream.getId(), content.getByteBuffer(), lastContent);
73 stream.data(dataFrame, callback);
74 return;
75 }
76 }
77 callback.succeeded();
78 }
79
80 @Override
81 public void failed(Throwable failure)
82 {
83 callback.failed(failure);
84 }
85 };
86
87 channel.getSession().newStream(headersFrame, promise, channel.getStreamListener());
88 }
89
90 private String relativize(String path)
91 {
92 try
93 {
94 String result = path;
95 URI uri = URI.create(result);
96 if (uri.isAbsolute())
97 result = uri.getPath();
98 return result.isEmpty() ? "/" : result;
99 }
100 catch (Throwable x)
101 {
102 if (LOG.isDebugEnabled())
103 LOG.debug("Could not relativize " + path);
104 return path;
105 }
106 }
107
108 @Override
109 protected void sendContent(HttpExchange exchange, HttpContent content, Callback callback)
110 {
111 if (content.isConsumed())
112 {
113 callback.succeeded();
114 }
115 else
116 {
117 Stream stream = getHttpChannel().getStream();
118 DataFrame frame = new DataFrame(stream.getId(), content.getByteBuffer(), content.isLast());
119 stream.data(frame, callback);
120 }
121 }
122 }