简体   繁体   English

Java代理未将任何内容发送回浏览器

[英]Java Proxy is not sending anything back to browser

I have created a proxy server in Java, (See code below), the thing is, I'm getting response back from the web-server however my client-side of the proxy which handles the connections between clients(browser) and the web-server after a socket has been created with the server side of the proxy. 我已经用Java创建了一个代理服务器(请参见下面的代码),问题是,我从Web服务器获取了响应,但是代理的客户端处理了客户端(浏览器)和Web之间的连接在使用代理的服务器端创建套接字后,使用-server。 The server side creates a client and sends the request and socket and this is then handled in a new thread. 服务器端创建一个客户端,并发送请求和套接字,然后在新线程中对其进行处理。 I have a few questions: 我有几个问题:

First Code is of the Client-side of the proxy second code part is of the Server-side of the proxy 第一个代码属于代理的客户端,第二个代码部分属于代理的服务器端

  • What type of streams should I use when sending data between browser/proxy/webserver? 在浏览器/代理/网络服务器之间发送数据时应使用哪种类型的流?
  • Is it fine to use a String or should I use some type of byte array when sending and receiving from streams? 从流发送和接收时,使用String是否合适还是应该使用某种类型的字节数组?

  • Why is the browser not receiving anything from the proxy? 为什么浏览器没有收到来自代理的任何信息? Since I can print it out from the console but when writing to the stream nothing happens in the browser. 由于我可以从控制台中将其打印出来,但是当写入流时,浏览器中什么也没有发生。

  • Also, why do I need to click "enter" twice in the browser for the proxy to react? 另外,为什么我需要在浏览器中单击两次“输入”以使代理作出反应?

     public class Client implements Runnable { private String request; private String response; private Socket browserSocket; public Client(String request, Socket browserSocket) { this.request = request; this.response = ""; this.browserSocket = browserSocket; } @Override public void run() { /* Send request to web server and get the response. */ this.request = Client.modifyHttpHeader("Connection", "close", this.request); String hostName = Client.getHttpHeader("Host", this.request); if (!hostName.isEmpty()) { try { /* Send request to the web-server. */ Socket socket = new Socket(hostName, 80); OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream()); PrintWriter pw = new PrintWriter(osw); pw.write(this.request); pw.flush(); System.out.println("---S:REQUEST---"); System.out.println(this.request); System.out.println("---S:REQUEST---"); /* Receive the response from the web-server. */ BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); String response = ""; int tmpData; while ((tmpData = br.read()) != -1) { response += (char)tmpData; } this.response = response; socket.close(); /* Close the socket between client-side and web-server. */ /* Send the response back to the browser. */ OutputStreamWriter oswbrowser = new OutputStreamWriter(this.browserSocket.getOutputStream()); PrintWriter pwBrowser = new PrintWriter(oswbrowser); pwBrowser.write(this.response); pwBrowser.flush(); pwBrowser.close(); this.browserSocket.close(); /* Close the socket between client-side and browser. */ System.out.println("---C:RESPONSE---"); System.out.println(this.response); System.out.println("---C:RESPONSE---"); } catch (Exception e) { System.err.println(e.getMessage()); e.printStackTrace(); } } } public String getHttpResponse() { return this.response; } /** * * @param header * The name of the HTTP header. Example: "GET". * Note: Header name is case sensitive. * @param request * The HTTP message. * @return * On success: The value following the HTTP header ": " (colon and whitespace). * On failure: Empty string. */ public static String getHttpHeader(String header, String request) { int startHeaderIndex = request.indexOf(header) + header.length(); int endHeaderIndex = request.indexOf('\\n', startHeaderIndex); /* Could not find the searched header. */ if (startHeaderIndex == -1 || endHeaderIndex == -1) return ""; /* Add 2 to remove ':' and ' '(white space). Decrement 1 to exclude '\\r' and '\\n' */ return request.substring(startHeaderIndex + 2, endHeaderIndex - 1); } /** * * @param header * The name of the HTTP header. Example: "Connection" * Note: The header is case sensitive. * @param value * The new value you want to put. Example: "Close" * @param request * The HTTP message. * @return * On success: A new HTTP request with the modified header value. * On failure: Empty string. * */ public static String modifyHttpHeader(String header, String value, String request) { int startHeaderIndex = request.indexOf(header) + header.length(); int endHeaderIndex = request.indexOf('\\n', startHeaderIndex); /* Could not find the searched header. */ if (startHeaderIndex == -1 || endHeaderIndex == -1) return ""; String newRequest = ""; /* Copy all characters including ':' and ' ' (whitespace) */ for (int i = 0; i < startHeaderIndex + 2; i++) { newRequest += request.charAt(i); } newRequest += value; newRequest += "\\r\\n"; /* Add the rest of the request. */ for (int i = endHeaderIndex + 1; i < request.length(); i++) { newRequest += request.charAt(i); } return newRequest; } } public class Server { public static void main(String[] args) throws Exception{ /* Receiving and parsing port number from command line arguments. */ int ssPort = 0; if (args.length > 1 || args.length == 0){ System.err.println("Only one argument allowed; port number (int)."); System.exit(1); } else { try { ssPort = Integer.parseInt(args[0]); } catch(NumberFormatException exception) { System.err.println("Argument \\"" + args[0] + "\\" must be a number."); System.exit(1); } } ServerSocket serverSocket = new ServerSocket(ssPort); /* Creating the server socket. */ System.out.println("Proxy running on port: " + ssPort); while(true) { System.out.println("Waiting for client..."); Socket clientSocket = serverSocket.accept(); /* Listening for connections. */ BufferedReader bReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); String request = ""; int tmpData; while ((tmpData = bReader.read()) != -1) { request += (char)tmpData; } Client clientObject = new Client(request, clientSocket); Thread clientThread = new Thread(clientObject); clientThread.start(); /* Start the client thread. */ } } 

    } }

Throw it all away. 扔了这一切。 This isn't how proxies are written. 代理不是这样写的。 An HTTP proxy should: HTTP代理应:

  1. Read one line from the downstream client, to determine whom to connect to upstream, without buffering. 阅读来自下游客户端一行 ,以确定谁连接到上游,没有缓冲。
  2. Connect upstream. 连接上游。
  3. If (2) fails, send an appropriate HTTP response downstream and close the connection. 如果(2)失败,则向下游发送适当的HTTP响应并关闭连接。
  4. Otherwise, start copying bytes, in both directions, simultaneously. 否则,请同时开始双向复制字节

You should not attempt to assemble the entire request, or even the headers, and the words 'bytes' and 'simultaneously' above are critical. 不应尝试组装整个请求,或甚至标头,和上面的字“字节”和“同时”是至关重要的。 Note that you don't have to do anything about HTTP keep-alive, Connection headers, HTTPS, etc. 请注意,您无需执行任何有关HTTP保持活动, Connection头,HTTPS等的操作。

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

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