【问题标题】:Forwarding HTTP Requests in Java在 Java 中转发 HTTP 请求
【发布时间】:2014-04-02 08:58:30
【问题描述】:

所以基本上我正在编写一个简单的代理,它接受 HTTP 请求,其中方法名称是小写的,我必须将它们大写并将它们转发到服务器。不过,转发到服务器部分是我遇到的麻烦。在我的代码中,这就是“forwardToServer”方法。我已经设法规范化请求,获取主机的 IP 地址,但是当我尝试将请求发送到主机时,出现连接超时异常。我对套接字编程很陌生,所以我真的不知道发生了什么。

package proxy;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

public class WebProxy {

public String requestNormalizer(String badRequest) {

    return badRequest.replace(badRequest.substring(0, badRequest.indexOf(" ")), badRequest
            .substring(0, badRequest.indexOf(" ")).toUpperCase());
}

public void requestFromClient(String badRequest) throws IOException {

    ServerSocket welcome = new ServerSocket(9001);

    while (true) {

        Socket connection = welcome.accept();

        BufferedReader clientInput = new BufferedReader(new InputStreamReader(
                connection.getInputStream()));

    }
}

public void fowrardToServer(String request) throws UnknownHostException, IOException {

    Socket client;

    if (!dnsQuery(request)[1].equals(""))
        client = new Socket((InetAddress) dnsQuery(request)[0], (int) dnsQuery(request)[1]);
    else
        client = new Socket((InetAddress) dnsQuery(request)[0], 9001);

    DataOutputStream output = new DataOutputStream(client.getOutputStream());

    BufferedReader input = new BufferedReader(new InputStreamReader(client.getInputStream()));

    output.writeBytes(request);

    System.out.println(input.readLine());
}

public Object[] dnsQuery(String request) throws UnknownHostException {

    Object[] addressPort = new Object[2];
    String hostname = request.substring(request.indexOf("host") + 6);
    hostname = hostname.substring(0, hostname.indexOf("\r"));

    if (hostname.contains(":")) {

        hostname = hostname.substring(0, hostname.indexOf(":"));
        addressPort[1] = hostname.substring(hostname.indexOf(":"));
    }
    else
        addressPort[1] = "";

    addressPort[0] = InetAddress.getByName(hostname);

    return addressPort;
}

这是异常的堆栈跟踪:

Exception in thread "main" java.net.ConnectException: Connection timed out: connect
    at java.net.DualStackPlainSocketImpl.connect0(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
    at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
    at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
    at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
    at java.net.PlainSocketImpl.connect(Unknown Source)
    at java.net.SocksSocketImpl.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.<init>(Unknown Source)
    at java.net.Socket.<init>(Unknown Source)
    at proxy.WebProxy.main(WebProxy.java:99)

这是我用于测试目的的 GET 请求:

GET http://www.uga.edu/ HTTP/1.1
Host: www.uga.edu
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:18.0) Gecko/20100101
Firefox/18.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate

提前致谢!

编辑: 我用来测试的代码很常规,我只是在测试forwardToServer方法

public static void main(String[] args) throws IOException {

    WebProxy wp = new WebProxy();
    String request = "get http://www.uga.edu/ HTTP/1.1\r\nhost: www.google.com\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Language: en-US,en;q=0.5\r\nAccept-Encoding: gzip, deflate";

    wp.forwardToServer(wp.requestNormalizer(request));
}

【问题讨论】:

    标签: java sockets http proxy


    【解决方案1】:

    您收到来自套接字级别(而不是 HTTP 级别)的“连接超时”错误,这意味着网络级别存在阻止 TCP 连接建立的问题。

    • 这并不是说您正在使用的 IP/端口上没有任何连接正在侦听...因为这会导致“连接被拒绝”错误。

    • (可能)不是您拥有虚假的主机名或 IP 地址,因为这会导致不同的消息。

    • 最可能的解释是连接被客户端、服务器或两者之间的防火墙阻止。

    尝试使用网络浏览器连接到相同的主机/端口……或一些允许您打开简单 TCP/IP 连接的命令行工具。 (telnet 命令在 Linux 上经常用于此目的......)


    请注意,堆栈跟踪表明您正在 WebProxy 类的 main 方法中创建一个 Socket 对象......但您没有向我们展示该代码。事实上,根据堆栈跟踪,没有您包含的代码与您当前的问题直接相关。

    【讨论】:

    • 当我尝试通过 telnet 查询 www.uga.edu 时,它说连接被拒绝。可能是我正在使用的端口吗?所以你的意思是它很可能不是代码,而是防火墙或其他什么?
    • 当您使用 telnet 连接时,您连接的端口是否与您在代码中使用的端口相同? (请注意,正如我上面所说,您没有向我们展示尝试建立连接的代码......根据堆栈跟踪。)
    • “所以你的意思是它很可能不是代码,而是防火墙或其他什么?” - 好吧,直到你向我们展示代码,我无法回答这个问题:-)。
    • 我上传了我正在测试的代码,但我所做的只是调用 requestNormalizer 来修复 HTTP 请求和 forwardToServer,这就是我遇到的问题。
    • @KlamBurglar - 堆栈跟踪仍然与代码不匹配。堆栈跟踪显示Socket 正在由main 构造,但源代码没有说new Socket。如果您提供的证据不一致,就很难为您提供帮助......
    猜你喜欢
    • 2011-03-20
    • 2014-03-12
    • 1970-01-01
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    相关资源
    最近更新 更多