Skip to content

Persistent HTTP/1.1 connection doesn't get upgraded to HTTP/2 #5289

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
pingw33n opened this issue Aug 29, 2024 · 2 comments
Closed

Persistent HTTP/1.1 connection doesn't get upgraded to HTTP/2 #5289

pingw33n opened this issue Aug 29, 2024 · 2 comments
Labels

Comments

@pingw33n
Copy link

Version

4.5.9

Steps to reproduce

Kotlin code (the issue isn't Kotlin-specific):

fun main() {
    val vertx = Vertx.vertx()
    val server = vertx.createHttpServer()

    server.requestHandler { request ->
        request.response().end("Hello World!")
    }

    Thread {
        server.listen(8123)
    }.start()

    Thread.sleep(500)

//    val hostPort = "nghttp2.org" to 80
    val hostPort = "localhost" to 8123
    val socket = Socket(hostPort.first, hostPort.second)
    val inp = BufferedReader(InputStreamReader(socket.getInputStream()))
    val out = OutputStreamWriter(socket.getOutputStream())

    fun writeRequest(upgrade: Boolean) {
        out.write("GET / HTTP/1.1\r\n")
        out.write("Host: ${hostPort.first}:${hostPort.second}\r\n")
        if (upgrade) {
            out.write("Connection: Upgrade, HTTP2-Settings\r\n")
            out.write("Upgrade: h2c\r\n")
            out.write("HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA\r\n")
        }
        out.write("\r\n")
        out.flush()
    }

    fun readResponse(): String {
        val response = StringBuilder()
        var contentLength: Int? = null
        for (i in 1..Int.MAX_VALUE) {
            val line = inp.readLine()!!
            if (line.isEmpty()) {
                break
            }
            if (line.lowercase().startsWith("content-length:")) {
                check(contentLength == null)
                contentLength = line.substring("content-length:".length).trim().toInt()
            }
            if (i == 1) {
                response.append(line + '\n')
            }
        }
        if (contentLength != null) {
            inp.skip(contentLength.toLong())
        }
        return response.toString()
    }

    writeRequest(upgrade = false)
    println(readResponse())

    writeRequest(upgrade = true)
    println(readResponse())
}

The above code prints:

HTTP/1.1 200 OK
HTTP/1.1 200 OK

While it's expected to print:

HTTP/1.1 200 OK
HTTP/1.1 101 Switching Protocols
@pingw33n pingw33n added the bug label Aug 29, 2024
@vietj
Copy link
Member

vietj commented Mar 11, 2025

For the record Java reproducer:

  private static void writeRequest(boolean upgrade, OutputStreamWriter out) throws IOException {
    out.write("GET / HTTP/1.1\r\n");
    out.write("Host: ${hostPort.first}:${hostPort.second}\r\n");
    if (upgrade) {
      out.write("Connection: Upgrade, HTTP2-Settings\r\n");
      out.write("Upgrade: h2c\r\n");
      out.write("HTTP2-Settings: AAMAAABkAAQAoAAAAAIAAAAA\r\n");
    }
    out.write("\r\n");
    out.flush();
  }

  private static String readResponse(BufferedReader inp) throws Exception {
    var response = new StringBuilder();
    Integer contentLength = null;
    for (int i = 1;i < Integer.MAX_VALUE;i++) {
      var line = inp.readLine();
      if (line.isEmpty()) {
        break;
      }
      if (line.toLowerCase().startsWith("content-length:")) {
        contentLength = Integer.parseInt(line.substring("content-length:".length()).trim());
      }
      if (i == 1) {
        response.append(line + '\n');
      }
    }
    if (contentLength != null) {
      inp.skip(contentLength);
    }
    return response.toString();
  }

  public static void main(String[] args) throws Exception {
    var vertx = Vertx.vertx();
    var server = vertx.createHttpServer();

    server.requestHandler(request -> {
      request.response().end("Hello World!");
    });

    server.listen(8123).await();

    var socket = new Socket("localhost", 8123);
    var inp = new BufferedReader(new InputStreamReader((socket.getInputStream())));
    var out = new OutputStreamWriter(socket.getOutputStream());

    writeRequest(true, out);
    System.out.println(readResponse(inp));
  }
}

@vietj
Copy link
Member

vietj commented Mar 11, 2025

it responds 101 on latest 4.5.x, could you test again on latest released version ?

@vietj vietj closed this as completed Mar 11, 2025
@vietj vietj closed this as not planned Won't fix, can't repro, duplicate, stale Mar 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants