我正在使用apache的httpclient lib。我设法通过向服务器发送GET请求来获取HttpResponse。现在我要做的是将我得到的响应发送到clientSocket输出流。
所以基本上我想将从服务器收到的任何内容发送到开放客户端连接。由于我使用的是HttpClient,因此我以HttpResponse对象的形式获得响应。我尝试了以下方法:
private void forwardRequest(String header, String url){
try {
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet httpget = new HttpGet(url);
CloseableHttpResponse response;
//Adding the request headers to httpget
String lines[] = header.split("\\n");
for (String str : lines) {
String parts[] = str.split(":", 2);
httpget.addHeader(parts[0], parts[1]);
}
HttpResponse respone;
response = httpclient.execute(httpget);
//It works till here I can read from the response and print out the html page
//But after this I don't know how to send it to client
OutputStream bos = clientSocket.getOutputStream();
PrintWriter pw = new PrintWriter(bos);
BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
while ((line = rd.readLine()) != null) {
pw.println(line);
//bos.write(line.getBytes()); //This also doesn't work
}
response.close();
}
此外,clientSocket是一个全局变量,它与ServerSocket关联,如:
clientSocket = serverSocket.accept();
我不期待完整的解决方案。只是指出我正确的方向..谢谢你!
修改
我根据EJP的建议尝试了以下内容..它仍然无法正常工作。我想知道它是否正确实施了?
int portNumber = 8012; // port on which the program listens
ServerSocket serverSocket =
new ServerSocket(portNumber); //the socket at which the program listens
Socket clientSocket = serverSocket.accept(); //clientSocket of the program
Socket toServer = new Socket("localhost", 8089); //proxy server to which program connects
PrintWriter out =
new PrintWriter(toServer.getOutputStream(), true);
PrintWriter outClient =
new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
BufferedReader inServer = new BufferedReader(
new InputStreamReader(toServer.getInputStream()));
) {
String inputLine;
while ((inputLine = in.readLine()) != null) {
out.println(inputLine); //Writing to proxy server
outClient.println(inServer.readLine()); //writing back to original request sender
System.out.println(inputLine);
}
答案 0 :(得分:0)
客户端发出HTTP请求,因此需要HTTP响应。如果全局clientSocket只是一个原始TCP套接字而不是HttpClient,那么您需要自己添加HTTP响应协议头。
你有来自服务器的内容,你要首先返回一个HTTP响应200 OK,然后用回车符+换行符(CR + LF),然后是Content-length:,然后是文件。如果您只是代理文本文档,那么您可以在这里转换为字符串,但除此之外,我只是将mime类型,字符集和实体作为Web服务器响应的原始字节传递,这样您就可以代理任何文档,包括图像或二进制文件。
看起来像这样:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: length
<html> ...
</html>
从服务器传递http标头:
HttpEntity entity = response.getEntity();
// technically you should check the HTTP response rather than assume it is a 200
int statusCode = httpResp.getStatusLine().getStatusCode();
if(statusCode != 200)
... // do something with non 200 responses ?
clientSocket.write("HTTP/1.1 200 OK\r\n");
Header[] responseHeaders = response.getAllHeaders();
for(Header header : responseHeaders) {
clientSocket.write(header.toString() + "\r\n");
}
clientSocket.write("\r\n"); // empty line required
// Use BufferedInputStream to deal in bytes
BufferedInputStream input = new BufferedInputStream(entity.getContent());
byte[] buf = new byte[8192];
int bytesRead;
while ((bytesRead = input.read(buf, 8192)) > 0) {
clientSocket.write(buf, bytesRead);
}
我说&#34;像这样的事情&#34;,不要接受这个文字,我怀疑它编译。我不会在我面前设置开发站,但这是一般的想法。
注意:由于您使用的是Apache客户端lib,因此您应该能够使用特定的HTTP客户端而不是编写原始协议。这将在某种程度上抽象出HTTP协议。如果其他人没有提供更好的答案,我会在稍后更新答案。
答案 1 :(得分:0)
如果您只是转发请求和响应,那么除了请求的第一行之外,您根本不需要参与HTTP协议。如果客户知道您是代理,您将获得包含完整网址的GET
请求,或者同时获得CONNECT
请求。您所要做的就是连接目标,然后同时复制两个方向的字节。