View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
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          // TODO optimize the send of HEADERS and DATA frames.
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 }