1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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
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
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
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
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
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 }