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 <a href="http://mina.apache.org">Apache MINA Project</a>
    37   * @since MINA 2.0.0-M3
    38   */
    39  public class HttpProxyRequest extends ProxyRequest {
    40      private final static Logger logger = LoggerFactory.getLogger(HttpProxyRequest.class);
    41
    42      /**
    43       * The HTTP verb.
    44       */
    45      public final String httpVerb;
    46
    47      /**
    48       * The HTTP URI.
    49       */
    50      public final String httpURI;
    51
    52      /**
    53       * The HTTP protocol version.
    54       */
    55      private String httpVersion;
    56
    57      /**
    58       * The target hostname.
    59       */
    60      private String host;
    61
    62      /**
    63       * The request headers.
    64       */
    65      private Map<String, List<String>> headers;
    66
    67      /**
    68       * The additionnal properties supplied to use with the proxy for
    69       * authentication for example.
    70       */
    71      private transient Map<String, String> properties;
    72
    73      /**
    74       * Constructor which creates a HTTP/1.0 CONNECT request to the specified
    75       * endpoint.
    76       *
    77       * @param endpointAddress the endpoint to connect to
    78       */
    79      public HttpProxyRequest(final InetSocketAddress endpointAddress) {
    80          this(endpointAddress, HttpProxyConstants.HTTP_1_0, null);
    81      }
    82
    83      /**
    84       * Constructor which creates a CONNECT request to the specified endpoint
    85       * using the provided protocol version.
    86       *
    87       * @param endpointAddress the endpoint to connect to
    88       * @param httpVersion the HTTP protocol version
    89       */
    90      public HttpProxyRequest(final InetSocketAddress endpointAddress, final String httpVersion) {
    91          this(endpointAddress, httpVersion, null);
    92      }
    93
    94      /**
    95       * Constructor which creates a CONNECT request to the specified endpoint
    96       * using the provided protocol version and setting the requested headers.
    97       *
    98       * @param endpointAddress the endpoint to connect to
    99       * @param httpVersion the HTTP protocol version
    100      * @param headers the additionnal http headers
    101      */
    102     public HttpProxyRequest(final InetSocketAddress endpointAddress, final String httpVersion,
    103             final Map<String, List<String>> headers) {
    104         this.httpVerb = HttpProxyConstants.CONNECT;
    105         if (!endpointAddress.isUnresolved()) {
    106             this.httpURI = endpointAddress.getHostName() + ":" + endpointAddress.getPort();
    107         } else {
    108             this.httpURI = endpointAddress.getAddress().getHostAddress() + ":" + endpointAddress.getPort();
    109         }
    110
    111         this.httpVersion = httpVersion;
    112         this.headers = headers;
    113     }
    114
    115     /**
    116      * Constructor which creates a HTTP/1.0 GET request to the specified
    117      * http URI.
    118      *
    119      * @param httpURI the target URI
    120      */
    121     public HttpProxyRequest(final String httpURI) {
    122         this(HttpProxyConstants.GET, httpURI, HttpProxyConstants.HTTP_1_0, null);
    123     }
    124
    125     /**
    126      * Constructor which creates a GET request to the specified http URI
    127      * using the provided protocol version
    128      *
    129      * @param httpURI the target URI
    130      * @param httpVersion the HTTP protocol version
    131      */
    132     public HttpProxyRequest(final String httpURI, final String httpVersion) {
    133         this(HttpProxyConstants.GET, httpURI, httpVersion, null);
    134     }
    135
    136     /**
    137      * Constructor which creates a request using the provided HTTP verb targeted at
    138      * the specified http URI using the provided protocol version.
    139      *
    140      * @param httpVerb the HTTP verb to use
    141      * @param httpURI the target URI
    142      * @param httpVersion the HTTP protocol version
    143      */
    144     public HttpProxyRequest(final String httpVerb, final String httpURI, final String httpVersion) {
    145         this(httpVerb, httpURI, httpVersion, null);
    146     }
    147
    148     /**
    149      * Constructor which creates a request using the provided HTTP verb targeted at
    150      * the specified http URI using the provided protocol version and setting the
    151      * requested headers.
    152      *
    153      * @param httpVerb the HTTP verb to use
    154      * @param httpURI the target URI
    155      * @param httpVersion the HTTP protocol version
    156      * @param headers the additional http headers
    157      */
    158     public HttpProxyRequest(final String httpVerb, final String httpURI, final String httpVersion,
    159             final Map<String, List<String>> headers) {
    160         this.httpVerb = httpVerb;
    161         this.httpURI = httpURI;
    162         this.httpVersion = httpVersion;
    163         this.headers = headers;
    164     }
    165
    166     /**
    167      * Returns the HTTP request verb.
    168      */
    169     public final String getHttpVerb() {
    170         return httpVerb;
    171     }
    172
    173     /**
    174      * Returns the HTTP version.
    175      */
    176     public String getHttpVersion() {
    177         return httpVersion;
    178     }
    179
    180     /**
    181      * Sets the HTTP version.
    182      *
    183      * @param httpVersion the HTTP protocol version
    184      */
    185     public void setHttpVersion(String httpVersion) {
    186         this.httpVersion = httpVersion;
    187     }
    188
    189     /**
    190      * Returns the host to which we are connecting.
    191      */
    192     public synchronized final String getHost() {
    193         if (host == null) {
    194             if (getEndpointAddress() != null && !getEndpointAddress().isUnresolved()) {
    195                 host = getEndpointAddress().getHostName();
    196             }
    197
    198             if (host == null && httpURI != null) {
    199                 try {
    200                     host = (new URL(httpURI)).getHost();
    201                 } catch (MalformedURLException e) {
    202                     logger.debug("Malformed URL", e);
    203                 }
    204             }
    205         }
    206
    207         return host;
    208     }
    209
    210     /**
    211      * Returns the request HTTP URI.
    212      */
    213     public final String getHttpURI() {
    214         return httpURI;
    215     }
    216
    217     /**
    218      * Returns the HTTP headers.
    219      */
    220     public final Map<String, List<String>> getHeaders() {
    221         return headers;
    222     }
    223
    224     /**
    225      * Set the HTTP headers.
    226      */
    227     public final void setHeaders(Map<String, List<String>> headers) {
    228         this.headers = headers;
    229     }
    230
    231     /**
    232      * Returns additional properties for the request.
    233      */
    234     public Map<String, String> getProperties() {
    235         return properties;
    236     }
    237
    238     /**
    239      * Set additional properties for the request.
    240      */
    241     public void setProperties(Map<String, String> properties) {
    242         this.properties = properties;
    243     }
    244
    245     /**
    246      * Check if the given property(ies) is(are) set. Otherwise throws a
    247      * {@link ProxyAuthException}.
    248      */
    249     public void checkRequiredProperties(String... propNames) throws ProxyAuthException {
    250         StringBuilder sb = new StringBuilder();
    251         for (String propertyName : propNames) {
    252             if (properties.get(propertyName) == null) {
    253                 sb.append(propertyName).append(' ');
    254             }
    255         }
    256         if (sb.length() > 0) {
    257             sb.append("property(ies) missing in request");
    258             throw new ProxyAuthException(sb.toString());
    259         }
    260     }
    261
    262     /**
    263      * Returns the string representation of the HTTP request .
    264      */
    265     public String toHttpString() {
    266         StringBuilder sb = new StringBuilder();
    267
    268         sb.append(getHttpVerb()).append(' ').append(getHttpURI()).append(' ').append(getHttpVersion())
    269                 .append(HttpProxyConstants.CRLF);
    270
    271         boolean hostHeaderFound = false;
    272
    273         if (getHeaders() != null) {
    274             for (Map.Entry<String, List<String>> header : getHeaders().entrySet()) {
    275                 if (!hostHeaderFound) {
    276                     hostHeaderFound = header.getKey().equalsIgnoreCase("host");
    277                 }
    278
    279                 for (String value : header.getValue()) {
    280                     sb.append(header.getKey()).append(": ").append(value).append(HttpProxyConstants.CRLF);
    281                 }
    282             }
    283
    284             if (!hostHeaderFound && getHttpVersion() == HttpProxyConstants.HTTP_1_1) {
    285                 sb.append("Host: ").append(getHost()).append(HttpProxyConstants.CRLF);
    286             }
    287         }
    288
    289         sb.append(HttpProxyConstants.CRLF);
    290
    291         return sb.toString();
    292     }
    293 }