java 實現Http代理 (4)

來源:互聯網
上載者:User

接下來,我們將著重介紹一下Dispatcher,因為這個類才是實現的關鍵
下面這個方法完成轉寄,參數是我們之前建立的HttpRequest
首先,我們根據指定的host和port建立了一個Socket,該Socket串連到真正的主機
然後,我們調用了request方法,這個方法將request轉寄出去,比較簡單,僅僅是將要求標頭寫到Socket的OutputStream裡面。
第三步,我們使用HttpResponseFactory的read方法,從Socket的InputStream裡面讀取並封裝出一個HttpResponse對象。
第四步,將回應標頭和響應流都寫到用戶端。用戶端的OutputStream從HttpRequest對象裡面可以得到。
   

    /**     * @param request - void     */    public void dispatch(HttpRequest request, HttpResponse response, ProxyHost proxyHost)    {        String host = proxyHost.getHost();        int port = proxyHost.getPort();        Socket socket = null;        try        {            socket = this.createSocket(host, port);            socket.setSoTimeout(10000);            socket.setKeepAlive(false);            InputStream socketInputStream   = socket.getInputStream();            OutputStream socketOutputStream = socket.getOutputStream();            if(logger.isDebugEnabled())            {                // logger.debug("------------------ request.header\r\n" + request.toString());            }                        this.request(request, socketOutputStream);            HttpResponse httpResponse = HttpConnectionFactory.createHttpResponse(socketInputStream, socketOutputStream);            if(httpResponse != null)            {                response.setHttpHeader(httpResponse.getHttpHeader().clone());                response.setChunked(httpResponse.getChunked());                response.setContentType(httpResponse.getContentType());                response.setStatus(httpResponse.getStatus());                response.setReasonPhrase(httpResponse.getReasonPhrase());                this.resonse(request, httpResponse, request.getOutputStream());                response.setContentLength(httpResponse.getContentLength());            }        }        catch(IOException e)        {            if(logger.isErrorEnabled())            {                logger.error(request.getRequestURL(), e);            }        }        finally        {            if(socket != null)            {                try                {                    socket.close();                }                catch(IOException e)                {                }            }        }    }


這裡是request方法:
1. 首先我們需要對Http的要求標頭進行修改,主要是修改請求主機和連接埠號碼,否則伺服器會認為請求的不是自己,因為客戶機發的請求是到我們的代理程式的請求,而實際上我們僅僅是做個代理,所以我們需要修改一下它,然後把它發給真正的主機
2. 將要求標頭發給服務期,僅僅是將要求標頭字串寫到OutputStream裡面罷了。

3. 將客戶機的其他請求資料發給伺服器,例如POST請求或者上傳檔案的話。但是不同的請求發送的資料是不一樣的,所以我們的程式必須能夠知道客戶機發送了多少資料,我們使用ContentPump.pumpContentStream()這個方法將請求資料發到伺服器,它像是一個抽水機,把一個管道裡面的資料抽到另外一個管道裡面。但是它必須事Crowdsourced Security Testing道要抽多少,否則,阻塞IO在資料讀取到最後的時候,會被阻塞。

    /**     * @param request     * @param outputStream     * @throws IOException     */    private void request(HttpRequest request, OutputStream outputStream) throws IOException    {        String host = InetAddress.getLocalHost().getHostAddress();        if(useXForwardedFor)        {            String xForwardedFor = request.getHeader("X-Forwarded-For");                if(xForwardedFor == null)            {                xForwardedFor = host;            }            else            {                xForwardedFor = "," + host;            }                // local: not set http_client_ip             request.setHeader("HTTP_CLIENT_IP", request.getRemoteAddr());            request.setHeader("X-Forwarded-For", xForwardedFor);        }        String headers = request.toString();        outputStream.write(headers.getBytes());        outputStream.flush();        HttpStream.pipe(request.getInputStream(), outputStream, request.getContentLength());    }


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.