Package org.xlightweb

Source Code of org.xlightweb.HttpProxy2$HttpReverseHandler

package org.xlightweb;




import java.io.IOException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;


import org.apache.commons.codec.binary.Base64;
import org.xlightweb.HttpResponse;
import org.xlightweb.IHttpExchange;
import org.xlightweb.IHttpRequest;
import org.xlightweb.IHttpRequestHandler;
import org.xlightweb.IHttpResponse;
import org.xlightweb.IHttpResponseHandler;
import org.xlightweb.IHttpSocketTimeoutHandler;
import org.xlightweb.InvokeOn;
import org.xlightweb.client.HttpClient;
import org.xlightweb.server.HttpServer;
import org.xsocket.Execution;
import org.xsocket.ILifeCycle;
import org.xsocket.MaxReadSizeExceededException;
import org.xsocket.connection.IDataHandler;
import org.xsocket.connection.IDisconnectHandler;
import org.xsocket.connection.INonBlockingConnection;
import org.xsocket.connection.NonBlockingConnection;
import org.xsocket.connection.IConnection.FlushMode;


public class HttpProxy2 extends HttpServer {

  public HttpProxy2(boolean isAuthRequired) throws IOException {
    this(0, isAuthRequired);
  }
 
  public HttpProxy2(int port, boolean isAuthRequired) throws IOException {
    super(port, new HttpForwardHandler(isAuthRequired));
  }
 
 
  private static final class HttpForwardHandler implements IHttpRequestHandler, ILifeCycle {

    private HttpClient httpClient = null;
 
    private boolean isAuthRequired = false;
   
    public HttpForwardHandler(boolean isAuthRequired) {
      this.isAuthRequired = isAuthRequired;
    }
   
    public void onInit() {
      httpClient = new HttpClient();
    }
   
    public void onDestroy() throws IOException {
      httpClient.close();
    }
   

    public void onRequest(IHttpExchange exchange) throws IOException {

      IHttpRequest req = exchange.getRequest();

      if (isAuthRequired) {
        String s = req.getHeader("Proxy-Authorization");
        if (s != null) {
          int idx = s.indexOf(" ");
          String algorithm = s.substring(0, idx);
          if (algorithm.equalsIgnoreCase("Basic")) {
            String decoded = new String(Base64.decodeBase64(s.substring(idx + 1, s.length()).getBytes()));
            String[] upp = decoded.split(":");
            if (!upp[0].equals(upp[1])) {
              exchange.sendError(401);
              return;
            }
          }
        }
      }
     
     
     
      if (req.getMethod().equalsIgnoreCase("CONNECT")) {
        establishTunnel(exchange);
        return;
      }
     
     
      String path = req.getRequestUrl().getFile();
      URL target = new URL(path);
     
      req.setRequestUrl(target);
     
     
      // add via header
      req.addHeader("Via", "myProxy");
   
     
       
      // .. and forward the request
      try {
        httpClient.send(req, new HttpReverseHandler(exchange));
      } catch (ConnectException ce) {
        exchange.sendError(502, ce.getMessage());
      }
    }
   

    private void establishTunnel(IHttpExchange exchange) {
      IHttpRequest req = exchange.getRequest();
     
      String forwardHost = null;
      int forwardPort = 443;
     
      String uri = req.getRequestURI();
      int idx = uri.lastIndexOf(":");
      if (idx == -1) {
        forwardHost = uri;
      } else {
        forwardHost = uri.substring(0, idx);
        forwardPort = Integer.parseInt(uri.substring(idx + 1, uri.length()));
      }
     
      try {
        INonBlockingConnection forwardCon = new NonBlockingConnection(forwardHost, forwardPort);
        INonBlockingConnection tcpCon = exchange.getConnection().getUnderlyingTcpConnection();

        forwardCon.setAttachment(tcpCon);
        tcpCon.setAttachment(forwardCon);
       
        forwardCon.setFlushmode(FlushMode.ASYNC);
        forwardCon.setAutoflush(true);
        tcpCon.setFlushmode(FlushMode.ASYNC);
        tcpCon.setAutoflush(true);

        forwardCon.setHandler(new TcpProxyHandler());
        tcpCon.setHandler(new TcpProxyHandler());
       
        IHttpResponse response = new HttpResponse(200);
        response.getResponseHeader().setReason("Connection established");
        response.setHeader("Proxy-agent", "myProxy");
        exchange.send(response);
       
      } catch (IOException ioe) {
        exchange.sendError(ioe);
      }
    }
  }

 
 
 
  private static final class HttpReverseHandler implements IHttpResponseHandler, IHttpSocketTimeoutHandler {
   
    private IHttpExchange exchange = null;
   
     
    public HttpReverseHandler(IHttpExchange exchange) {
      this.exchange = exchange;
    }


    @Execution(Execution.NONTHREADED)
    @InvokeOn(InvokeOn.HEADER_RECEIVED)
    public void onResponse(IHttpResponse resp) throws IOException {
     
       
      // add via header
      resp.addHeader("Via", "myProxy");
     
      //   return the response
      exchange.send(resp);
    }

    @Execution(Execution.NONTHREADED)
    public void onException(IOException ioe) {
      exchange.sendError(500, ioe.toString());
    }
   
    @Execution(Execution.NONTHREADED)
    public void onException(SocketTimeoutException stoe) {
      exchange.sendError(504, stoe.toString());
    }
  }
 
 

  private static class TcpProxyHandler implements IDataHandler, IDisconnectHandler {
   
 
    public boolean onDisconnect(INonBlockingConnection connection) throws IOException {
      INonBlockingConnection reverseConnection = (INonBlockingConnection) connection.getAttachment();
      if (reverseConnection != null) {
        connection.setAttachment(null);
        reverseConnection.close();
      }
      return true;
    }
   
   
    public boolean onData(INonBlockingConnection connection) throws IOException, BufferUnderflowException, MaxReadSizeExceededException {
      INonBlockingConnection forwardConnection = (INonBlockingConnection) connection.getAttachment();
       
      int available = connection.available();
      if (available > 0) {
        ByteBuffer[] data = connection.readByteBufferByLength(connection.available());
        forwardConnection.write(data);
      } else if (available == -1) {
        connection.close();
      }
     
      return true;
    }
  } 
}
TOP

Related Classes of org.xlightweb.HttpProxy2$HttpReverseHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.