org.apache.mina.proxy.handlers.http.HttpProxyRequest Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.mina.proxy.handlers.http;
import java.net.InetSocketAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import org.apache.mina.proxy.ProxyAuthException;
import org.apache.mina.proxy.handlers.ProxyRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* HttpProxyRequest.java - Wrapper class for HTTP requests.
*
* @author Apache MINA Project
* @since MINA 2.0.0-M3
*/
public class HttpProxyRequest extends ProxyRequest {
private static final Logger LOGGER = LoggerFactory.getLogger(HttpProxyRequest.class);
/**
* The HTTP verb.
*/
private final String httpVerb;
/**
* The HTTP URI.
*/
private final String httpURI;
/**
* The HTTP protocol version.
*/
private String httpVersion;
/**
* The target hostname.
*/
private String host;
/**
* The request headers.
*/
private Map> headers;
/**
* The additionnal properties supplied to use with the proxy for
* authentication for example.
*/
private Map properties;
/**
* Constructor which creates a HTTP/1.0 CONNECT request to the specified
* endpoint.
*
* @param endpointAddress the endpoint to connect to
*/
public HttpProxyRequest(final InetSocketAddress endpointAddress) {
this(endpointAddress, HttpProxyConstants.HTTP_1_0, null);
}
/**
* Constructor which creates a CONNECT request to the specified endpoint
* using the provided protocol version.
*
* @param endpointAddress the endpoint to connect to
* @param httpVersion the HTTP protocol version
*/
public HttpProxyRequest(final InetSocketAddress endpointAddress, final String httpVersion) {
this(endpointAddress, httpVersion, null);
}
/**
* Constructor which creates a CONNECT request to the specified endpoint
* using the provided protocol version and setting the requested headers.
*
* @param endpointAddress the endpoint to connect to
* @param httpVersion the HTTP protocol version
* @param headers the additionnal http headers
*/
public HttpProxyRequest(final InetSocketAddress endpointAddress, final String httpVersion,
final Map> headers) {
this.httpVerb = HttpProxyConstants.CONNECT;
if (!endpointAddress.isUnresolved()) {
this.httpURI = endpointAddress.getHostName() + ":" + endpointAddress.getPort();
} else {
this.httpURI = endpointAddress.getAddress().getHostAddress() + ":" + endpointAddress.getPort();
}
this.httpVersion = httpVersion;
this.headers = headers;
}
/**
* Constructor which creates a HTTP/1.0 GET request to the specified
* http URI.
*
* @param httpURI the target URI
*/
public HttpProxyRequest(final String httpURI) {
this(HttpProxyConstants.GET, httpURI, HttpProxyConstants.HTTP_1_0, null);
}
/**
* Constructor which creates a GET request to the specified http URI
* using the provided protocol version
*
* @param httpURI the target URI
* @param httpVersion the HTTP protocol version
*/
public HttpProxyRequest(final String httpURI, final String httpVersion) {
this(HttpProxyConstants.GET, httpURI, httpVersion, null);
}
/**
* Constructor which creates a request using the provided HTTP verb targeted at
* the specified http URI using the provided protocol version.
*
* @param httpVerb the HTTP verb to use
* @param httpURI the target URI
* @param httpVersion the HTTP protocol version
*/
public HttpProxyRequest(final String httpVerb, final String httpURI, final String httpVersion) {
this(httpVerb, httpURI, httpVersion, null);
}
/**
* Constructor which creates a request using the provided HTTP verb targeted at
* the specified http URI using the provided protocol version and setting the
* requested headers.
*
* @param httpVerb the HTTP verb to use
* @param httpURI the target URI
* @param httpVersion the HTTP protocol version
* @param headers the additional http headers
*/
public HttpProxyRequest(final String httpVerb, final String httpURI, final String httpVersion,
final Map> headers) {
this.httpVerb = httpVerb;
this.httpURI = httpURI;
this.httpVersion = httpVersion;
this.headers = headers;
}
/**
* @return the HTTP request verb.
*/
public final String getHttpVerb() {
return httpVerb;
}
/**
* @return the HTTP version.
*/
public String getHttpVersion() {
return httpVersion;
}
/**
* Sets the HTTP version.
*
* @param httpVersion the HTTP protocol version
*/
public void setHttpVersion(String httpVersion) {
this.httpVersion = httpVersion;
}
/**
* @return the host to which we are connecting.
*/
public final synchronized String getHost() {
if (host == null) {
if (getEndpointAddress() != null && !getEndpointAddress().isUnresolved()) {
host = getEndpointAddress().getHostName();
}
if (host == null && httpURI != null) {
try {
host = (new URL(httpURI)).getHost();
} catch (MalformedURLException e) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Malformed URL", e);
}
}
}
}
return host;
}
/**
* @return the request HTTP URI.
*/
public final String getHttpURI() {
return httpURI;
}
/**
* @return the HTTP headers.
*/
public final Map> getHeaders() {
return headers;
}
/**
* Set the HTTP headers.
*
* @param headers The HTTP headers to set
*/
public final void setHeaders(Map> headers) {
this.headers = headers;
}
/**
* @return additional properties for the request.
*/
public Map getProperties() {
return properties;
}
/**
* Set additional properties for the request.
*
* @param properties The properties to add to the reqyest
*/
public void setProperties(Map properties) {
this.properties = properties;
}
/**
* Check if the given property(ies) is(are) set. Otherwise throws a
* {@link ProxyAuthException}.
*
* @param propNames The list of property name to check
* @throws ProxyAuthException If we get an error during the proxy authentication
*/
public void checkRequiredProperties(String... propNames) throws ProxyAuthException {
StringBuilder sb = new StringBuilder();
for (String propertyName : propNames) {
if (properties.get(propertyName) == null) {
sb.append(propertyName).append(' ');
}
}
if (sb.length() > 0) {
sb.append("property(ies) missing in request");
throw new ProxyAuthException(sb.toString());
}
}
/**
* @return the string representation of the HTTP request .
*/
public String toHttpString() {
StringBuilder sb = new StringBuilder();
sb.append(getHttpVerb()).append(' ').append(getHttpURI()).append(' ').append(getHttpVersion())
.append(HttpProxyConstants.CRLF);
boolean hostHeaderFound = false;
if (getHeaders() != null) {
for (Map.Entry> header : getHeaders().entrySet()) {
if (!hostHeaderFound) {
hostHeaderFound = "host".equalsIgnoreCase(header.getKey());
}
for (String value : header.getValue()) {
sb.append(header.getKey()).append(": ").append(value).append(HttpProxyConstants.CRLF);
}
}
if (!hostHeaderFound && getHttpVersion() == HttpProxyConstants.HTTP_1_1) {
sb.append("Host: ").append(getHost()).append(HttpProxyConstants.CRLF);
}
}
sb.append(HttpProxyConstants.CRLF);
return sb.toString();
}
}