From 134a285bd66040589c41ecc843137f6db5c1cecc Mon Sep 17 00:00:00 2001 From: findstr Date: Mon, 16 Sep 2024 16:27:49 +0800 Subject: [PATCH] fix http2 window handle --- lualib/core/http/h2stream.lua | 9 ++++--- test/testhttp2.lua | 50 ++++++++++++++++++++++++++++------- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/lualib/core/http/h2stream.lua b/lualib/core/http/h2stream.lua index 483c71d..2ac1771 100644 --- a/lualib/core/http/h2stream.lua +++ b/lualib/core/http/h2stream.lua @@ -357,7 +357,8 @@ local function frame_winupdate(ch, id, flag, dat) if n > 0 then local dat = remove(ch, 1) if dat then - n = n - #dat + local len = remove(ch, 1) + n = n - len ch.socket:write(dat) end end @@ -440,7 +441,6 @@ local function handshake_as_client(ch, socket) end frame_settings(ch, id, f, dat) write(socket, build_setting(0x01)) - write(socket, build_winupdate(0, 0, 1*1024*1024)) while true do local t,f,dat,id = read_frame(socket) if not t then @@ -479,7 +479,6 @@ local function handshake_as_server(socket, ch) end frame_settings(ch, id, f, dat) write(socket, build_setting(0x01)) - write(socket, build_winupdate(0, 0, 1*1024*1024)) while true do local t,f,dat,id = read_frame(socket) if not t then @@ -726,13 +725,15 @@ local function write_func(close) end end dat = dat or "" + local body_len = #dat dat = build_body(s.id, ch.frame_max_size, dat, close) local win = ch.window_size if win <= 0 then ch[#ch + 1] = dat + ch[#ch + 1] = body_len return true, "ok" else - ch.window_size = win - #dat + ch.window_size = win - body_len return ch.socket:write(dat) end end diff --git a/test/testhttp2.lua b/test/testhttp2.lua index be25e82..fea9dd2 100644 --- a/test/testhttp2.lua +++ b/test/testhttp2.lua @@ -6,6 +6,38 @@ local testaux = require "test.testaux" local f = io.open("./a.txt", "w") +local data = crypto.randomkey(65*1024) + +local alpn_protos = {"http/1.1", "h2"} +local function POST(url, header, body) + if body then + header = header or {} + header["content-length"] = #body * 2 + end + local stream, err = http.request("POST", url, header, false, alpn_protos) + if not stream then + return nil, err + end + local version = stream.version + if version == "HTTP/2" then + stream:write(body) + stream:close(body) + else + stream:write(body) + end + local status, header = stream:readheader() + if not status then + return nil, header + end + testaux.asserteq(stream.channel.window_size, 65535, "http2.client window_size") + local body = stream:readall() + return { + status = status, + header = header, + body = body, + } +end + if not crypto.digestsign then print("not enable openssl") return @@ -29,7 +61,7 @@ http.listen { testaux.asserteq(stream.path, "/test", "http2.server path") testaux.asserteq(header['hello'], "world", "http2.server header") local body = stream:readall() - testaux.asserteq(body, "http2", "http2 body") + testaux.asserteq(body, data .. data, "http2 body") stream:respond(200, {["foo"] = header['foo']}) stream:close("http2") end @@ -62,14 +94,14 @@ print("test http2 server") local wg = waitgroup:create() for i = 1, 2000 do wg:fork(function() - local key = crypto.randomkey(1028) - local ack, err = http.POST("https://localhost:8082/test", { - ['hello'] = 'world', - ['foo'] = key, - }, "http2") - testaux.asserteq(ack.status, 200, "http2.client status") - testaux.asserteq(ack.header['foo'], key, "http2.client header") - testaux.asserteq(ack.body, 'http2', "http2.client body") + local key = crypto.randomkey(1028) + local ack, err = POST("https://localhost:8082/test", { + ['hello'] = 'world', + ['foo'] = key, + }, data) + testaux.asserteq(ack.status, 200, "http2.client status") + testaux.asserteq(ack.header['foo'], key, "http2.client header") + testaux.asserteq(ack.body, 'http2', "http2.client body") end) end wg:wait()