简体   繁体   English

为什么在 Java 中发送 HTTPS 时需要显式 CR?

[英]Why do I need explicit CR when sending HTTPS in Java?

I'm writing a simple HTTPS client in Java (exploring ideas for interesting/fun labs for my web programming course).我正在用 Java 编写一个简单的 HTTPS 客户端(为我的网络编程课程探索有趣/有趣的实验室的想法)。 In order to get the web server to respond, I have to explicitly add a '\\r' to the end of each line.为了让 Web 服务器做出响应,我必须在每行的末尾显式添加一个 '\\r'。 (If I don't, the web server replies with status 400 and "Your browser sent a request that this server could not understand.") (如果我不这样做,Web 服务器会回复状态 400 和“您的浏览器发送了此服务器无法理解的请求。”)

Should I have to explicitly add "\\r";我是否必须明确添加 "\\r"; or, is there a configuration I'm missing?或者,是否有我缺少的配置? (In other words, is there a way to tell Java to automatically add the CR?) Interestingly enough, I also tried to run openssl from the command line on my Mac to grab a web page, and I had to add -crlf to the command. (换句话说,有没有办法告诉 Java 自动添加 CR?)有趣的是,我还尝试从 Mac 上的命令行运行openssl来抓取网页,我不得不将-crlf添加到命令。

When I use a "regular" socket to connect to and HTTP server on port 80, I don't have this issue (similarly when using telnet ).当我使用“常规”套接字连接到端口 80 上的 HTTP 服务器时,我没有这个问题(使用telnet时类似)。 So, who exactly is being picky?那么,究竟是谁在挑剔呢? Is the HTTPS protocol different? HTTPS 协议有什么不同吗? Is there a way to get Java to use '\\r\\n' instead of just '\\n'?有没有办法让 Java 使用 '\\r\\n' 而不仅仅是 '\\n'?

My code is below:我的代码如下:

public class HTTPSClient {
    public static void main(String[] args) throws Exception {

        SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();

        SSLSocket socket = (SSLSocket) factory.createSocket("www.emu.edu", 443);

        socket.startHandshake();

        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));

        out.println("GET / HTTP/1.1\r");
        out.println("host: www.emu.edu\r");
        out.println("connection: close\r");
        out.println("\r");
        out.flush();

        /*
         * Make sure there were no surprises
         */
        if (out.checkError())
            System.out.println("SSLSocketClient:  java.io.PrintWriter error");

        /* read response */
        BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

        String inputLine;
        while ((inputLine = in.readLine()) != null) {
            System.out.println(inputLine);
        }

        socket.close();
    }
}

The HTTP standard clearly says that \\r\\n is required. HTTP 标准清楚地表明\\r\\n是必需的。 Most servers though accept a simple \\n too - but some actually have a strict (and correct) interpretation of the standard.大多数服务器虽然也接受简单的\\n - 但有些服务器实际上对标准有严格(且正确)的解释。 My guess is that you've tested different servers with "regular" sockets than you did with your Java application.我的猜测是,您使用“常规”套接字测试了与 Java 应用程序不同的服务器。 And as with telnet - depending on the setup it might actually send \\r\\n instead of only \\n as line end.telnet - 根据设置,它实际上可能会发送\\r\\n而不仅仅是\\n作为行尾。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM