From e20a6a9685b969a1bdc3a20df8e0bd158ca7f85f Mon Sep 17 00:00:00 2001
From: zzz <zzz@mail.i2p>
Date: Sun, 3 Feb 2019 16:31:26 +0000
Subject: [PATCH] i2ptunnel: Fix HTTP websockets by passing through Connection
 headers containing "upgrade" (ticket #2422) Client-side change only.
 Server-side todo.

---
 .../i2ptunnel/HTTPResponseOutputStream.java   |  8 ++++++-
 .../i2p/i2ptunnel/I2PTunnelHTTPClient.java    | 23 +++++++++++++------
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/HTTPResponseOutputStream.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/HTTPResponseOutputStream.java
index 14b269807a..4139086099 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/HTTPResponseOutputStream.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/HTTPResponseOutputStream.java
@@ -174,7 +174,13 @@ class HTTPResponseOutputStream extends FilterOutputStream {
                             
                             String lcKey = key.toLowerCase(Locale.US);
                             if ("connection".equals(lcKey)) {
-                                out.write(DataHelper.getASCII("Connection: close\r\n"));
+                                if (val.toLowerCase(Locale.US).contains("upgrade")) {
+                                    // pass through for websocket
+                                    out.write(DataHelper.getASCII("Connection: " + val + "\r\n"));
+                                    proxyConnectionSent = true;
+                                } else {
+                                    out.write(DataHelper.getASCII("Connection: close\r\n"));
+                                }
                                 connectionSent = true;
                             } else if ("proxy-connection".equals(lcKey)) {
                                 out.write(DataHelper.getASCII("Proxy-Connection: close\r\n"));
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java
index a6643b7b72..6a06e9b218 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java
@@ -414,6 +414,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
             int remotePort = 0;
             String referer = null;
             URI origRequestURI = null;
+            boolean preserveConnectionHeader = false;
             while((line = reader.readLine(method)) != null) {
                 line = line.trim();
                 if(_log.shouldLog(Log.DEBUG)) {
@@ -421,11 +422,6 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
                 }
 
                 String lowercaseLine = line.toLowerCase(Locale.US);
-                if(lowercaseLine.startsWith("connection: ") ||
-                        lowercaseLine.startsWith("keep-alive: ") ||
-                        lowercaseLine.startsWith("proxy-connection: ")) {
-                    continue;
-                }
 
                 if(method == null) { // first line (GET /base64/realaddr)
                     if(_log.shouldLog(Log.DEBUG)) {
@@ -940,7 +936,17 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
                 // end first line processing
 
                 } else {
-                    if(lowercaseLine.startsWith("host: ") && !usingWWWProxy && !usingInternalOutproxy) {
+                    if (lowercaseLine.startsWith("connection: ")) {
+                        if (lowercaseLine.contains("upgrade")) {
+                            // pass through for websocket
+                            preserveConnectionHeader = true;
+                        } else {
+                            continue;
+                        }
+                    } else if (lowercaseLine.startsWith("keep-alive: ") ||
+                               lowercaseLine.startsWith("proxy-connection: ")) {
+                        continue;
+                    } else if (lowercaseLine.startsWith("host: ") && !usingWWWProxy && !usingInternalOutproxy) {
                         // Note that we only pass the original Host: line through to the outproxy
                         // But we don't create a Host: line if it wasn't sent to us
                         line = "Host: " + host;
@@ -1081,7 +1087,10 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
                                     .append("\r\n");
                         }
                     }
-                    newRequest.append("Connection: close\r\n\r\n");
+                    if (preserveConnectionHeader)
+                        newRequest.append("\r\n");
+                    else
+                        newRequest.append("Connection: close\r\n\r\n");
                     s.setSoTimeout(0);
                     break;
                 } else {
-- 
GitLab