com.k42b3.aletheia.protocol.http.HttpProtocol.java Source code

Java tutorial

Introduction

Here is the source code for com.k42b3.aletheia.protocol.http.HttpProtocol.java

Source

/**
 * aletheia
 * A browser like application to send raw http requests. It is designed for 
 * debugging and finding security issues in web applications. For the current 
 * version and more informations visit <http://code.google.com/p/aletheia>
 * 
 * Copyright (c) 2010-2015 Christoph Kappestein <k42b3.x@gmail.com>
 * 
 * This file is part of Aletheia. Aletheia is free software: you can 
 * redistribute it and/or modify it under the terms of the GNU 
 * General Public License as published by the Free Software Foundation, 
 * either version 3 of the License, or at any later version.
 * 
 * Aletheia is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Aletheia. If not, see <http://www.gnu.org/licenses/>.
 */

package com.k42b3.aletheia.protocol.http;

import java.net.Socket;
import java.net.URL;
import java.net.URLStreamHandler;
import java.util.ArrayList;
import java.util.LinkedList;

import org.apache.http.ConnectionReuseStrategy;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.DefaultConnectionReuseStrategy;
import org.apache.http.impl.DefaultHttpClientConnection;
import org.apache.http.message.BasicHttpEntityEnclosingRequest;
import org.apache.http.message.BasicHttpRequest;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.params.SyncBasicHttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.ExecutionContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpProcessor;
import org.apache.http.protocol.HttpRequestExecutor;
import org.apache.http.protocol.ImmutableHttpProcessor;
import org.apache.http.protocol.RequestConnControl;
import org.apache.http.protocol.RequestContent;
import org.apache.http.protocol.RequestExpectContinue;
import org.apache.http.protocol.RequestTargetHost;

import com.k42b3.aletheia.Aletheia;
import com.k42b3.aletheia.protocol.CallbackInterface;
import com.k42b3.aletheia.protocol.ProtocolAbstract;

/**
 * HttpProtocol
 *
 * @author     Christoph Kappestein <k42b3.x@gmail.com>
 * @license    http://www.gnu.org/licenses/gpl.html GPLv3
 * @link       http://aletheia.k42b3.com
 */
public class HttpProtocol extends ProtocolAbstract {
    public final static String newLine = "\r\n";
    public final static String type = "HTTP/1.1";
    public final static String method = "GET";

    protected HttpParams params;
    protected HttpHost host;
    protected HttpProcessor httpproc;
    protected HttpRequestExecutor httpexecutor;
    protected HttpContext context;
    protected ConnectionReuseStrategy connStrategy;
    protected DefaultHttpClientConnection conn;

    public HttpProtocol() {
        // http settings
        params = new SyncBasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpProtocolParams.setContentCharset(params, "UTF-8");
        HttpProtocolParams.setUseExpectContinue(params, true);

        HttpRequestInterceptor[] interceptors = { new RequestContent(true), new RequestTargetHost(),
                new RequestConnControl(), new RequestExpectContinue() };

        httpproc = new ImmutableHttpProcessor(interceptors);
        httpexecutor = new HttpRequestExecutor();
    }

    public void setRequest(com.k42b3.aletheia.protocol.Request request, CallbackInterface callback)
            throws Exception {
        super.setRequest(request, callback);

        // request settings
        int port = request.getUrl().getPort();

        if (port == -1) {
            if (request.getUrl().getProtocol().equalsIgnoreCase("https")) {
                port = 443;
            } else {
                port = 80;
            }
        }

        context = new BasicHttpContext(null);
        host = new HttpHost(request.getUrl().getHost(), port);

        conn = new DefaultHttpClientConnection();
        connStrategy = new DefaultConnectionReuseStrategy();

        context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
        context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host);
    }

    public void run() {
        try {
            // get socket
            Socket socket = this.getSocket();
            conn.bind(socket, params);

            // build request
            BasicHttpRequest request;

            if (!this.getRequest().getBody().isEmpty()) {
                request = new BasicHttpEntityEnclosingRequest(this.getRequest().getMethod(),
                        this.getRequest().getPath());
            } else {
                request = new BasicHttpRequest(this.getRequest().getMethod(), this.getRequest().getPath());
            }

            // add headers
            String boundary = null;
            ArrayList<String> ignoreHeader = new ArrayList<String>();
            ignoreHeader.add("Content-Length");
            ignoreHeader.add("Expect");

            LinkedList<Header> headers = this.getRequest().getHeaders();

            for (int i = 0; i < headers.size(); i++) {
                if (!ignoreHeader.contains(headers.get(i).getName())) {
                    // if the content-type header gets set the conent-length
                    // header is automatically added
                    request.addHeader(headers.get(i));
                }

                if (headers.get(i).getName().equals("Content-Type")
                        && headers.get(i).getValue().startsWith("multipart/form-data")) {
                    String header = headers.get(i).getValue().substring(headers.get(i).getValue().indexOf(";") + 1)
                            .trim();

                    if (!header.isEmpty()) {
                        String parts[] = header.split("=");

                        if (parts.length >= 2) {
                            boundary = parts[1];
                        }
                    }
                }
            }

            // set body
            if (request instanceof BasicHttpEntityEnclosingRequest && boundary != null) {
                boundary = "--" + boundary;
                StringBuilder body = new StringBuilder();
                String req = this.getRequest().getBody();

                int i = 0;
                String partHeader;
                String partBody;

                while ((i = req.indexOf(boundary, i)) != -1) {
                    int hPos = req.indexOf("\n\n", i + 1);
                    if (hPos != -1) {
                        partHeader = req.substring(i + boundary.length() + 1, hPos).trim();
                    } else {
                        partHeader = null;
                    }

                    int bpos = req.indexOf(boundary, i + 1);
                    if (bpos != -1) {
                        partBody = req.substring(hPos == -1 ? i : hPos + 2, bpos);
                    } else {
                        partBody = req.substring(hPos == -1 ? i : hPos + 2);
                    }

                    if (partBody.equals(boundary + "--")) {
                        body.append(boundary + "--" + "\r\n");
                        break;
                    } else if (!partBody.isEmpty()) {
                        body.append(boundary + "\r\n");
                        if (partHeader != null && !partHeader.isEmpty()) {
                            body.append(partHeader.replaceAll("\n", "\r\n"));
                            body.append("\r\n");
                            body.append("\r\n");
                        }
                        body.append(partBody);
                    }

                    i++;
                }

                this.getRequest().setBody(body.toString().replaceAll("\r\n", "\n"));

                HttpEntity entity = new StringEntity(this.getRequest().getBody());

                ((BasicHttpEntityEnclosingRequest) request).setEntity(entity);
            } else if (request instanceof BasicHttpEntityEnclosingRequest) {
                HttpEntity entity = new StringEntity(this.getRequest().getBody());

                ((BasicHttpEntityEnclosingRequest) request).setEntity(entity);
            }

            logger.info("> " + request.getRequestLine().getUri());

            // request
            request.setParams(params);
            httpexecutor.preProcess(request, httpproc, context);

            HttpResponse response = httpexecutor.execute(request, conn, context);
            response.setParams(params);
            httpexecutor.postProcess(response, httpproc, context);

            logger.info("< " + response.getStatusLine());

            // update request headers 
            LinkedList<Header> header = new LinkedList<Header>();
            Header[] allHeaders = request.getAllHeaders();

            for (int i = 0; i < allHeaders.length; i++) {
                header.add(allHeaders[i]);
            }

            this.getRequest().setHeaders(header);

            // create response
            this.response = new Response(response);

            // call callback
            callback.onResponse(this.request, this.response);
        } catch (Exception e) {
            Aletheia.handleException(e);
        } finally {
            try {
                conn.close();
            } catch (Exception e) {
                Aletheia.handleException(e);
            }
        }
    }

    public Request buildRequest(URL url, String content) throws Exception {
        return new Request(url, content);
    }

    public Request getRequest() {
        return (Request) this.request;
    }

    public Response getResponse() {
        return (Response) this.response;
    }

    public URLStreamHandler getStreamHandler() {
        return new HttpURLStreamHandler();
    }

    public Socket getSocket() throws Exception {
        return new Socket(host.getHostName(), host.getPort());
    }
}