私はしばらくの間、カスタムプロキシを機能させるためにいくつかの異なる方法を試してきましたが、これまでにできた唯一の方法は、ApacheのHttpClientを使用することです。ただし、知るために、以下の独自のプロキシハンドルの実装で問題が発生しているのはなぜか疑問に思いました。
public void processProxyRequest (Socket client, String request) throws Exception {
if ( !request.equals("") ) {
String[] requestHeaders = request.split("\\r\\n");
Pattern p = Pattern.compile("([A-Z]*)\\s*([^:\\/]*):\\/\\/([^\\s]*)\\s*(?:HTTP.*)");
Matcher m = p.matcher(requestHeaders[0]);
if ( m.matches() ) {
String method = m.group(1).toUpperCase();
String proto = m.group(2).toLowerCase();
String[] requestInfo = m.group(3).split("\\/", 2);
String host = requestInfo[0];
host = ( host.split("\\.").length < 3 ) ? "www." + host : host;
String page = "/";
if ( requestInfo.length == 2 && !requestInfo[1].equals("") ) {
page += requestInfo[1];
}
int remotePort = 80;
if ( proto.equals("https") ) {
remotePort = 443;
}
else if ( proto.equals("ftp") ) {
remotePort = 21;
}
this.sendAndReceive(client, request, host, remotePort);
}
}
}
public void sendAndReceive (Socket client, String request, String host, int port) throws Exception {
Socket target = new Socket(host, port);
System.out.println("Connected to server");
ByteArrayInputStream inStream = new ByteArrayInputStream(request.getBytes());
this.inToOut(inStream, target.getOutputStream());
System.out.println("Sent");
this.inToOut(target.getInputStream(), client.getOutputStream());
System.out.println("Received");
target.close();
}
public void inToOut (InputStream input, OutputStream output) throws IOException {
byte[] buffer = new byte[1024]; // Adjust if you want
int bytesRead;
System.out.println("reading");
while ((bytesRead = input.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
}
一言で言えば(そして私のリクエストヘッダー解析の欠陥を無視して)、上記のコードはコンパイルされて実行されますが、inToOut()
メソッドは少し苦労し、input.read()中にロックアップするようです。理由はよくわかりません。私が渡した元のソケットが有効であり、エラーなしで開かれていることを事実として知っています。さらに、System.out
inToOut()関数のinは「読み取り」を出力しますが、そのread()
部分を超えることはありません。
提案ありがとうございます!