mercredi 29 juin 2016

Reverse Proxy using java for multiple targets

I need to implement a reverse proxy using java which will support multiple targets. Target for a particular request should be identified from the request(e.g. from the request header).

I have got an example from https://hc.apache.org/httpcomponents-core-ga/httpcore/examples/org/apache/http/examples/ElementalReverseProxy.java link and it is working fine for a single target. I tried to update on that code to create the inconn and outconn in the run method of RequestListenerThread class instead of it's constructor but while trying to obtain the request header for an incoming request using inconn.receiveRequestHeader() then it is returning null after the first request.

    public void run() {
        System.out.println("Listening on port " + this.serversocket.getLocalPort());
        while (!Thread.interrupted()) {
            try {
                // Set up HTTP protocol processor for incoming connections
                final HttpProcessor inhttpproc = new ImmutableHttpProcessor(
                        new HttpRequestInterceptor[] {
                                new RequestContent(true),
                                new RequestTargetHost(),
                                new RequestConnControl(),
                                new RequestUserAgent("Test/1.1"),
                                new RequestExpectContinue(true)
                 });

                // Set up HTTP protocol processor for outgoing connections
                final HttpProcessor outhttpproc = new ImmutableHttpProcessor(
                        new HttpResponseInterceptor[] {
                                new ResponseDate(),
                                new ResponseServer("Test/1.1"),
                                new ResponseContent(),
                                new ResponseConnControl()
                });

                final int bufsize = 8 * 1024;
                // Set up incoming HTTP connection
                final Socket insocket = this.serversocket.accept();
                final DefaultBHttpServerConnection inconn = new DefaultBHttpServerConnection(bufsize);
                System.out.println("Incoming connection from " + insocket.getInetAddress());
                inconn.bind(insocket);

                HttpRequest request = inconn.receiveRequestHeader();

                Header[] rawCookie = request.getHeaders("Cookie");

                // Set up outgoing request executor
                final HttpRequestExecutor httpexecutor = new HttpRequestExecutor();

                // Set up incoming request handler
                final UriHttpRequestHandlerMapper reqistry = new UriHttpRequestHandlerMapper();
                reqistry.register("*", new ProxyHandler(
                        this.targetList.get(0),
                        outhttpproc,
                        httpexecutor));

                // Set up the HTTP service
                this.httpService = new HttpService(inhttpproc, reqistry);

                // Set up outgoing HTTP connection
                final Socket outsocket = new Socket(this.targetList.get(0).getHostName(), this.targetList.get(0).getPort());
                final DefaultBHttpClientConnection outconn = new DefaultBHttpClientConnection(bufsize);
                outconn.bind(outsocket);
                System.out.println("Outgoing connection to " + outsocket.getInetAddress());

                // Start worker thread
                final Thread t = new ProxyThread(this.httpService, inconn, outconn);
                t.setDaemon(true);
                t.start();
            } catch (final InterruptedIOException ex) {
                break;
            } catch (final IOException e) {
                System.err.println("I/O error initialising connection thread: "
                        + e.getMessage());
                break;
            }
        }
    } 

My intention was to use the target HttpHost in the UriHttpRequestHandlerMapper and in the outsocket based on the request cookie. Now can someone please advise if I am not taking the right approach or any other ways to fulfill my requirement?

Aucun commentaire:

Enregistrer un commentaire