com.subgraph.vega.internal.http.proxy.UriRequestCreator.java Source code

Java tutorial

Introduction

Here is the source code for com.subgraph.vega.internal.http.proxy.UriRequestCreator.java

Source

/*******************************************************************************
 * Copyright (c) 2011 Subgraph.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Subgraph - initial API and implementation
 ******************************************************************************/
package com.subgraph.vega.internal.http.proxy;

import java.net.URI;
import java.net.URISyntaxException;

import org.apache.http.Header;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.protocol.HTTP;

import com.subgraph.vega.http.requests.custom.HttpEntityEnclosingMutableRequest;
import com.subgraph.vega.http.requests.custom.HttpMutableRequest;

public class UriRequestCreator {
    private final static String HTTP_SCHEME = "http://";
    private final static String HTTPS_SCHEME = "https://";

    private final boolean preferHostHeader;

    public UriRequestCreator(boolean preferHostHeader) {
        this.preferHostHeader = preferHostHeader;
    }

    public HttpUriRequest createUriRequest(HttpRequest request, boolean isSSL) throws HttpException {
        final URI uri = getUriForRequest(request, isSSL);
        final HttpUriRequest uriRequest;
        if (request instanceof HttpEntityEnclosingRequest) {
            HttpEntityEnclosingMutableRequest tmp = new HttpEntityEnclosingMutableRequest(
                    request.getRequestLine().getMethod(), uri);
            tmp.setEntity(((HttpEntityEnclosingRequest) request).getEntity());
            uriRequest = tmp;
        } else {
            uriRequest = new HttpMutableRequest(request.getRequestLine().getMethod(), uri);
        }
        uriRequest.setParams(request.getParams());
        uriRequest.setHeaders(request.getAllHeaders());
        return uriRequest;
    }

    public URI getUriForRequest(HttpRequest request, boolean isSSL) throws HttpException {
        final String scheme = (isSSL) ? HTTPS_SCHEME : HTTP_SCHEME;
        final String hostname = getHostname(request);
        final String pathAndQuery = extractPathAndQuery(request.getRequestLine().getUri());

        if (hostname == null) {
            throw new HttpException(
                    "Cannot create URI from request because no hostname is specified in either Host header or HTTP request line");
        }

        try {
            return new URI(scheme + hostname + pathAndQuery);
        } catch (URISyntaxException e) {
            throw new HttpException("Cannot create URI from request because URI format is incorrect.", e);
        }
    }

    private String getHostname(HttpRequest request) {
        final String headerHostname = requestHostHeaderValue(request);
        final String pathHostname = maybeExtractHostname(request.getRequestLine().getUri());
        if (headerHostname != null && pathHostname != null) {
            return (preferHostHeader) ? (headerHostname) : (pathHostname);
        }
        return (headerHostname != null) ? (headerHostname) : (pathHostname);
    }

    private String requestHostHeaderValue(HttpRequest request) {
        final Header hostHeader = request.getFirstHeader(HTTP.TARGET_HOST);
        if (hostHeader == null) {
            return null;
        }

        final String hostValue = hostHeader.getValue();
        return (hostValue == null || hostValue.isEmpty()) ? (null) : (hostValue);
    }

    private String maybeExtractHostname(String requestUri) {
        final int hostnameIndex = indexOfHostname(requestUri);
        if (hostnameIndex == -1)
            return null;
        final int pathIndex = indexOfPath(requestUri);
        return requestUri.substring(hostnameIndex, pathIndex);
    }

    private int indexOfHostname(String requestUri) {
        if (requestUri.startsWith(HTTP_SCHEME)) {
            return HTTP_SCHEME.length();
        } else if (requestUri.startsWith(HTTPS_SCHEME)) {
            return HTTPS_SCHEME.length();
        } else {
            return -1;
        }
    }

    private String extractPathAndQuery(String requestUri) {
        final int hostnameIndex = indexOfHostname(requestUri);
        if (hostnameIndex == -1) {
            return maybeCreateRootPath(requestUri);
        }
        final int pathIndex = indexOfPath(requestUri);
        return maybeCreateRootPath(requestUri.substring(pathIndex));
    }

    private String maybeCreateRootPath(String path) {
        return (path.isEmpty()) ? ("/") : (path);
    }

    /*
     * 
     * Returns 0 if not an absolute URI, otherwise searches for the first '/' character
     * after the hostname and if not found returns the length of the String.
     * 
     * If result is 0 then the whole string is the path otherwise,  the path can 
     * be extracted with requestUri.substring(pathIndex) and the hostname can
     * be extracted with requestUri.substring(hostnameIndex, pathIndex)
     * 
     */
    private int indexOfPath(String requestUri) {
        final int hostnameIndex = indexOfHostname(requestUri);
        if (hostnameIndex == -1)
            return 0;
        final int idx = requestUri.indexOf("/", hostnameIndex);

        return (idx == -1) ? (requestUri.length()) : (idx);
    }
}