View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2013 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.client;
20  
21  import java.net.HttpCookie;
22  import java.net.URI;
23  import java.util.ArrayList;
24  import java.util.List;
25  
26  import org.eclipse.jetty.client.api.Authentication;
27  import org.eclipse.jetty.client.api.Connection;
28  import org.eclipse.jetty.client.api.ContentProvider;
29  import org.eclipse.jetty.client.api.Request;
30  import org.eclipse.jetty.client.api.Response;
31  import org.eclipse.jetty.http.HttpField;
32  import org.eclipse.jetty.http.HttpFields;
33  import org.eclipse.jetty.http.HttpHeader;
34  import org.eclipse.jetty.http.HttpHeaderValue;
35  import org.eclipse.jetty.http.HttpMethod;
36  import org.eclipse.jetty.http.HttpVersion;
37  
38  public abstract class HttpConnection implements Connection
39  {
40      private static final HttpField CHUNKED_FIELD = new HttpField(HttpHeader.TRANSFER_ENCODING, HttpHeaderValue.CHUNKED);
41  
42      private final HttpDestination destination;
43  
44      protected HttpConnection(HttpDestination destination)
45      {
46          this.destination = destination;
47      }
48  
49      public HttpClient getHttpClient()
50      {
51          return destination.getHttpClient();
52      }
53  
54      public HttpDestination getHttpDestination()
55      {
56          return destination;
57      }
58  
59      @Override
60      public void send(Request request, Response.CompleteListener listener)
61      {
62          ArrayList<Response.ResponseListener> listeners = new ArrayList<>(2);
63          if (request.getTimeout() > 0)
64          {
65              TimeoutCompleteListener timeoutListener = new TimeoutCompleteListener(request);
66              timeoutListener.schedule(getHttpClient().getScheduler());
67              listeners.add(timeoutListener);
68          }
69          if (listener != null)
70              listeners.add(listener);
71  
72          HttpConversation conversation = getHttpClient().getConversation(request.getConversationID(), true);
73          HttpExchange exchange = new HttpExchange(conversation, getHttpDestination(), request, listeners);
74  
75          send(exchange);
76      }
77  
78      protected abstract void send(HttpExchange exchange);
79  
80      protected void normalizeRequest(Request request)
81      {
82          String method = request.getMethod();
83          HttpVersion version = request.getVersion();
84          HttpFields headers = request.getHeaders();
85          ContentProvider content = request.getContent();
86          ProxyConfiguration.Proxy proxy = destination.getProxy();
87  
88          // Make sure the path is there
89          String path = request.getPath();
90          if (path.trim().length() == 0)
91          {
92              path = "/";
93              request.path(path);
94          }
95          if (proxy != null && !HttpMethod.CONNECT.is(method))
96          {
97              path = request.getURI().toString();
98              request.path(path);
99          }
100 
101         // If we are HTTP 1.1, add the Host header
102         if (version.getVersion() > 10)
103         {
104             if (!headers.containsKey(HttpHeader.HOST.asString()))
105                 headers.put(getHttpDestination().getHostField());
106         }
107 
108         if (request.getAgent() == null)
109             headers.put(getHttpClient().getUserAgentField());
110 
111         // Add content headers
112         if (content != null)
113         {
114             long contentLength = content.getLength();
115             if (contentLength >= 0)
116             {
117                 if (!headers.containsKey(HttpHeader.CONTENT_LENGTH.asString()))
118                     headers.put(HttpHeader.CONTENT_LENGTH, String.valueOf(contentLength));
119             }
120             else
121             {
122                 if (!headers.containsKey(HttpHeader.TRANSFER_ENCODING.asString()))
123                     headers.put(CHUNKED_FIELD);
124             }
125         }
126 
127         // Cookies
128         List<HttpCookie> cookies = getHttpClient().getCookieStore().get(request.getURI());
129         StringBuilder cookieString = null;
130         for (int i = 0; i < cookies.size(); ++i)
131         {
132             if (cookieString == null)
133                 cookieString = new StringBuilder();
134             if (i > 0)
135                 cookieString.append("; ");
136             HttpCookie cookie = cookies.get(i);
137             cookieString.append(cookie.getName()).append("=").append(cookie.getValue());
138         }
139         if (cookieString != null)
140             request.header(HttpHeader.COOKIE.asString(), cookieString.toString());
141 
142         // Authorization
143         URI authenticationURI = proxy != null ? proxy.getURI() : request.getURI();
144         if (authenticationURI != null)
145         {
146             Authentication.Result authnResult = getHttpClient().getAuthenticationStore().findAuthenticationResult(authenticationURI);
147             if (authnResult != null)
148                 authnResult.apply(request);
149         }
150     }
151 
152     @Override
153     public String toString()
154     {
155         return String.format("%s@%h", getClass().getSimpleName(), this);
156     }
157 }