View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.mina.proxy.handlers.http;
21  
22  import java.net.InetSocketAddress;
23  import java.net.MalformedURLException;
24  import java.net.URL;
25  import java.util.List;
26  import java.util.Map;
27  
28  import org.apache.mina.proxy.ProxyAuthException;
29  import org.apache.mina.proxy.handlers.ProxyRequest;
30  import org.slf4j.Logger;
31  import org.slf4j.LoggerFactory;
32  
33  /**
34   * HttpProxyRequest.java - Wrapper class for HTTP requests.
35   * 
36   * @author The Apache MINA Project (dev@mina.apache.org)
37   * @version $Rev: 759731 $, $Date: 2009-03-29 19:52:41 +0200 (Sun, 29 Mar 2009) $
38   * @since MINA 2.0.0-M3
39   */
40  public class HttpProxyRequest extends ProxyRequest {
41      private final static Logger logger = LoggerFactory
42              .getLogger(HttpProxyRequest.class);
43  
44      /**
45       * The HTTP verb.
46       */
47      public final String httpVerb;
48  
49      /**
50       * The HTTP URI.
51       */
52      public final String httpURI;
53  
54      /**
55       * The HTTP protocol version.
56       */
57      private String httpVersion;
58  
59      /**
60       * The target hostname.
61       */
62      private String host;
63  
64      /**
65       * The request headers.
66       */
67      private Map<String, List<String>> headers;
68  
69      /**
70       * The additionnal properties supplied to use with the proxy for 
71       * authentication for example. 
72       */
73      private transient Map<String, String> properties;
74  
75      /**
76       * Constructor which creates a HTTP/1.0 CONNECT request to the specified 
77       * endpoint.
78       *  
79       * @param endpointAddress the endpoint to connect to
80       */
81      public HttpProxyRequest(final InetSocketAddress endpointAddress) {
82          this(endpointAddress, HttpProxyConstants.HTTP_1_0, null);
83      }
84  
85      /**
86       * Constructor which creates a CONNECT request to the specified endpoint
87       * using the provided protocol version.
88       *  
89       * @param endpointAddress the endpoint to connect to
90       * @param httpVersion the HTTP protocol version
91       */    
92      public HttpProxyRequest(final InetSocketAddress endpointAddress,
93              final String httpVersion) {
94          this(endpointAddress, httpVersion, null);
95      }
96  
97      /**
98       * Constructor which creates a CONNECT request to the specified endpoint
99       * using the provided protocol version and setting the requested headers.
100      *  
101      * @param endpointAddress the endpoint to connect to
102      * @param httpVersion the HTTP protocol version
103      * @param headers the additionnal http headers
104      */    
105     public HttpProxyRequest(final InetSocketAddress endpointAddress,
106             final String httpVersion, final Map<String, List<String>> headers) {
107     	this.httpVerb = HttpProxyConstants.CONNECT;
108         if (!endpointAddress.isUnresolved()) {
109         	this.httpURI = endpointAddress.getHostName() + ":"
110             				+ endpointAddress.getPort();
111         } else {
112         	this.httpURI = endpointAddress.getAddress().getHostAddress() + ":"
113 							+ endpointAddress.getPort();
114         }
115         
116         this.httpVersion = httpVersion;
117         this.headers = headers;
118     }
119 
120     /**
121      * Constructor which creates a HTTP/1.0 GET request to the specified 
122      * http URI.
123      *  
124      * @param httpURI the target URI
125      */    
126     public HttpProxyRequest(final String httpURI) {
127         this(HttpProxyConstants.GET, httpURI, HttpProxyConstants.HTTP_1_0, null);
128     }
129 
130     /**
131      * Constructor which creates a GET request to the specified http URI
132      * using the provided protocol version
133      *  
134      * @param httpURI the target URI
135      * @param httpVersion the HTTP protocol version
136      */        
137     public HttpProxyRequest(final String httpURI, final String httpVersion) {
138         this(HttpProxyConstants.GET, httpURI, httpVersion, null);
139     }
140 
141     /**
142      * Constructor which creates a request using the provided HTTP verb targeted at
143      * the specified http URI using the provided protocol version.
144      * 
145      * @param httpVerb the HTTP verb to use 
146      * @param httpURI the target URI
147      * @param httpVersion the HTTP protocol version
148      */        
149     public HttpProxyRequest(final String httpVerb, final String httpURI,
150             final String httpVersion) {
151         this(httpVerb, httpURI, httpVersion, null);
152     }
153 
154     /**
155      * Constructor which creates a request using the provided HTTP verb targeted at
156      * the specified http URI using the provided protocol version and setting the 
157      * requested headers.
158      * 
159      * @param httpVerb the HTTP verb to use 
160      * @param httpURI the target URI
161      * @param httpVersion the HTTP protocol version
162      * @param headers the additional http headers
163      */
164     public HttpProxyRequest(final String httpVerb, final String httpURI,
165             final String httpVersion, final Map<String, List<String>> headers) {
166         this.httpVerb = httpVerb;
167         this.httpURI = httpURI;
168         this.httpVersion = httpVersion;
169         this.headers = headers;
170     }
171 
172     /**
173      * Returns the HTTP request verb.
174      */
175     public final String getHttpVerb() {
176         return httpVerb;
177     }
178 
179     /**
180      * Returns the HTTP version.
181      */
182     public String getHttpVersion() {
183         return httpVersion;
184     }
185 
186     /**
187      * Sets the HTTP version.
188      * 
189      * @param httpVersion the HTTP protocol version
190      */
191     public void setHttpVersion(String httpVersion) {
192         this.httpVersion = httpVersion;
193     }
194 
195     /**
196      * Returns the host to which we are connecting.
197      */
198     public synchronized final String getHost() {
199         if (host == null) {
200             if (getEndpointAddress() != null && 
201             		!getEndpointAddress().isUnresolved()) {
202                 host = getEndpointAddress().getHostName();
203             }
204 
205             if (host == null && httpURI != null) {
206                 try {
207                     host = (new URL(httpURI)).getHost();
208                 } catch (MalformedURLException e) {
209                     logger.debug("Malformed URL", e);
210                 }
211             }
212         }
213 
214         return host;
215     }
216 
217     /**
218      * Returns the request HTTP URI.
219      */
220     public final String getHttpURI() {
221         return httpURI;
222     }
223 
224     /**
225      * Returns the HTTP headers.
226      */
227     public final Map<String, List<String>> getHeaders() {
228         return headers;
229     }
230 
231     /**
232      * Set the HTTP headers.
233      */
234     public final void setHeaders(Map<String, List<String>> headers) {
235         this.headers = headers;
236     }
237 
238     /**
239      * Returns additional properties for the request.
240      */
241     public Map<String, String> getProperties() {
242         return properties;
243     }
244 
245     /**
246      * Set additional properties for the request.
247      */
248     public void setProperties(Map<String, String> properties) {
249         this.properties = properties;
250     }
251 
252     /**
253      * Check if the given property(ies) is(are) set. Otherwise throws a 
254      * {@link ProxyAuthException}.
255      */
256     public void checkRequiredProperties(String... propNames) throws ProxyAuthException {
257 		StringBuilder sb = new StringBuilder();
258     	for (String propertyName : propNames) {
259 	        if (properties.get(propertyName) == null) {	        	
260 	        	sb.append(propertyName).append(' ');
261 	        }
262     	}
263         if (sb.length() > 0) {
264         	sb.append("property(ies) missing in request");
265         	throw new ProxyAuthException(sb.toString());
266         }
267     }
268     
269     /**
270      * Returns the string representation of the HTTP request .
271      */
272     public String toHttpString() {
273         StringBuilder sb = new StringBuilder();
274 
275         sb.append(getHttpVerb()).append(' ').append(getHttpURI()).append(' ')
276                 .append(getHttpVersion()).append(HttpProxyConstants.CRLF);
277 
278         boolean hostHeaderFound = false;
279 
280         if (getHeaders() != null) {
281             for (Map.Entry<String, List<String>> header : getHeaders()
282                     .entrySet()) {
283                 if (!hostHeaderFound) {
284                     hostHeaderFound = header.getKey().equalsIgnoreCase("host");
285                 }
286 
287                 for (String value : header.getValue()) {
288                     sb.append(header.getKey()).append(": ").append(value)
289                             .append(HttpProxyConstants.CRLF);
290                 }
291             }
292 
293             if (!hostHeaderFound
294                     && getHttpVersion() == HttpProxyConstants.HTTP_1_1) {
295                 sb.append("Host: ").append(getHost()).append(
296                         HttpProxyConstants.CRLF);
297             }
298         }
299 
300         sb.append(HttpProxyConstants.CRLF);
301 
302         return sb.toString();
303     }
304 }