Windows (Windows 7) マシンの TCP ソケットに書き込まれたデータが何かによって変更されています。具体的には、バイトが特定の HTTP POST パターンに従う場合、接続の対応するリスナー ソケット側からバイトが読み取られるときにパターンが繰り返されます。
次のバイトがクライアント ソケットに書き込まれます (注: 各行はキャリッジ リターンと改行で終わり、2 つの非空白行の後に 2 つの空白行が続きます)。
POST / HTTP/1.1
Transfer-Encoding: chunked
リスナーソケットから読み取られるものは次のとおりです。
POST / HTTP/1.1
Transfer-Encoding: chunked
POST / HTTP/1.1
Transfer-Encoding: chunked
これを自分のマシンのループバック (127.0.0.1) アドレスでテストしましたが、リスナー ソケットが別のマシンにあるときに変更されたバイトも見たので、クライアント側でバイトが変更されているようです。私のマシンで netcat と Java プログラム (以下を参照) の両方を使用して問題を再現したので、問題は TCP スタックにあるようです。特定の HTTP ヘッダー セットでのみ発生させることができたので、何かが TCP 通信でディープ パケット インスペクションを実行し、それを変更しているようです。入力バイトを少し変更すると (たとえば、「POST」を「QOST」に変更するなどして有効な HTTP 要求ではない場合、正常に動作します)。
以下は、これとその出力を示す、私が書いた Java プログラムです。
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.Charset;
public final class Main {
private static final String PAYLOAD
= "POST / HTTP/1.1\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "\r\n"
+ "\r\n"
;
private static final int PORT = 8080;
public static final void main(final String[] args) throws Exception {
final Thread serverThread = new Thread(new Server());
serverThread.start();
final byte[] payloadBytes = PAYLOAD.getBytes(Charset.forName("UTF-8"));
int i = 0;
try (final Socket socket = new Socket(InetAddress.getLoopbackAddress(), PORT)) {
socket.setTcpNoDelay(true);
final OutputStream os = socket.getOutputStream();
for (final byte byteValue : payloadBytes) {
os.write(byteValue);
os.flush();
i++;
}
}
serverThread.join();
System.out.println("bytes written: " + i);
}
private static final class Server implements Runnable {
@Override
public void run() {
try (final ServerSocket serverSocket = new ServerSocket(PORT)) {
// while (true) {
final Socket socket = serverSocket.accept();
socket.setTcpNoDelay(true);
try (final InputStream is = socket.getInputStream()) {
int i = 0;
int byteValue;
while ((byteValue = is.read()) >= 0) {
System.out.print((char) byteValue);
System.out.flush();
i++;
}
System.out.println("----------------");
System.out.println("bytes read: " + i);
}
// }
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
}
}
出力:
POST / HTTP/1.1
Transfer-Encoding: chunked
POST / HTTP/1.1
Transfer-Encoding: chunked
----------------
bytes read: 96
bytes written: 49
以下は、Windows で netcat (cygwin の nc.exe) を使用した同じテストです (注: ファイル test_payload.blob には、上記のバイトが含まれており、Java プログラムの PAYLOAD 定数から派生しています)。
nc リスナーを開始します。
nc -l 8080 > nc_capture; more nc_capture
nc クライアントを (リスナーから別のシェルで) 実行します。
nc -v 127.0.0.1 8080 < test_payload.blob
nc_capture に書き込まれた出力:
POST / HTTP/1.1
Transfer-Encoding: chunked
POST / HTTP/1.1
Transfer-Encoding: chunked
私が最初に考えたのはバグのあるファイアウォールだと思ったので、それを無効にしましたが、それでも発生します。また、winsock と tcp/ip をリセットしようとしましたが、それでも発生します。すべてのネットワーク アダプタを無効にしてみました (上記のテストはループバック IP アドレスで機能するため、必要ありません)。この時点で、私はアイデアがほとんどなくなっており、これをより低いレベルでデバッグしようとする方法さえわかりません。誰もこれまでにこのようなものを見たことがありますか? TCP スタックに何がフックされているかを確認するために使用できる、Windows 用の低レベルの診断ツールはありますか?