Skip to content

Commit 2539481

Browse files
committed
refactor: refactored the request/response headers table logic.
Previously, there is a bug in session.headers, we didn't assign the __index metamethod to this table, this results in that all non-normalized headers cannot be indexed. This commit refactored this part of logic, all headers will be saved with the lowercase and hyphen form. Also, session.headers will have the __index metamethod (created by util.dict()). Unfortunately there are many test cases need to be modified...
1 parent 913a04d commit 2539481

File tree

7 files changed

+86
-87
lines changed

7 files changed

+86
-87
lines changed

lib/resty/requests/adapter.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ local function parse_headers(self)
106106
end
107107

108108
if name and value then
109+
-- FIXME transform underscore to hyphen
109110
name = lower(name)
110111

111112
local ovalue = headers[name]

lib/resty/requests/request.lua

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -71,31 +71,31 @@ local function prepare(url_parts, session, config)
7171

7272
if json then
7373
content = cjson.encode(json)
74-
headers["Content-Length"] = #content
75-
headers["Content-Type"] = "application/json"
74+
headers["content-length"] = #content
75+
headers["content-type"] = "application/json"
7676
else
7777
content = body
7878
if is_func(body) then
7979
-- users may know their request body size
80-
if not headers["Content-Length"] then
81-
headers["Transfer-Encoding"] = "chunked"
80+
if not headers["content-length"] then
81+
headers["transfer-encoding"] = "chunked"
8282
end
8383

84-
if not headers["Content-Type"] and config.use_default_type then
85-
headers["Content-Type"] = "application/octet-stream"
84+
if not headers["content-type"] and config.use_default_type then
85+
headers["content-type"] = "application/octet-stream"
8686
end
8787

8888
elseif is_str(body) then
89-
headers["Content-Length"] = #body
90-
headers["Transfer-Encoding"] = nil
89+
headers["content-length"] = #body
90+
headers["transfer-encoding"] = nil
9191

92-
if not headers["Content-Type"] and config.use_default_type then
93-
headers["Content-Type"] = "text/plain"
92+
if not headers["content-type"] and config.use_default_type then
93+
headers["content-type"] = "text/plain"
9494
end
9595

9696
elseif is_tab(body) then
97-
if not headers["Content-Type"] and config.use_default_type then
98-
headers["Content-Type"] = "application/x-www-form-urlencoded"
97+
if not headers["content-type"] and config.use_default_type then
98+
headers["content-type"] = "application/x-www-form-urlencoded"
9999
end
100100

101101
local param = new_tab(4, 0)
@@ -104,24 +104,24 @@ local function prepare(url_parts, session, config)
104104
end
105105

106106
content = concat(param, "&")
107-
headers["Content-Length"] = #content
108-
headers["Transfer-Encoding"] = nil
107+
headers["content-length"] = #content
108+
headers["transfer-encoding"] = nil
109109
end
110110
end
111111

112-
if not headers["Host"] then
113-
headers["Host"] = url_parts.host
112+
if not headers["host"] then
113+
headers["host"] = url_parts.host
114114
end
115115

116-
if headers["Transfer-Encoding"] then
117-
headers["Content-Length"] = nil
116+
if headers["transfer-encoding"] then
117+
headers["content-length"] = nil
118118
end
119119

120-
headers["Connection"] = "keep-alive"
120+
headers["connection"] = "keep-alive"
121121

122122
local auth = session.auth
123123
if auth then
124-
headers["Authorization"] = auth
124+
headers["authorization"] = auth
125125
end
126126

127127
local cookie = session.cookie
@@ -131,7 +131,7 @@ local function prepare(url_parts, session, config)
131131
insert(plain, ("%s=%s"):format(k, v))
132132
end
133133

134-
headers["Cookie"] = concat(plain, "; ")
134+
headers["cookie"] = concat(plain, "; ")
135135
end
136136

137137
return content
@@ -146,7 +146,7 @@ local function new(method, url, session, config)
146146

147147
local body = prepare(url_parts, session, config)
148148

149-
local expect = session.headers["Expect"] == "100-continue"
149+
local expect = session.headers["expect"] == "100-continue"
150150

151151
local r = {
152152
method = method,

lib/resty/requests/response.lua

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ local function new(opts)
205205
end
206206

207207
if r._http_ver ~= HTTP20 then
208-
local chunk = r.headers["Transfer-Encoding"]
208+
local chunk = r.headers["transfer-encoding"]
209209
if chunk and find(chunk, "chunked", nil, true) then
210210
r._chunk = {
211211
size = 0, -- current chunked header size
@@ -214,14 +214,14 @@ local function new(opts)
214214
reader = r._adapter:reader("\r\n"),
215215
}
216216
else
217-
r._rest = tonumber(r.headers["Content-Length"])
217+
r._rest = tonumber(r.headers["content-length"])
218218
if r._rest == 0 or no_body(r) then
219219
r._read_eof = true
220220
end
221221
end
222222
end
223223

224-
local connection = r.headers["Connection"]
224+
local connection = r.headers["connection"]
225225
if connection == "keep-alive" or r._http_ver == HTTP20 then
226226
r._keepalive = true
227227
end
@@ -301,7 +301,7 @@ local function json(r)
301301
return nil, err
302302
end
303303

304-
local content_type = r.headers["Content-Type"]
304+
local content_type = r.headers["content-type"]
305305
if not content_type then
306306
return nil, "not json"
307307
end

lib/resty/requests/session.lua

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ local adapter = require "resty.requests.adapter"
77
local setmetatable = setmetatable
88
local format = string.format
99
local pairs = pairs
10-
local new_tab = util.new_tab
1110
local ngx_now = ngx.now
1211

1312
local _M = { _VERSION = "0.2" }
@@ -17,7 +16,7 @@ local BUILTIN_HEADERS = util.BUILTIN_HEADERS
1716
local send_request
1817

1918
local function new()
20-
local headers = new_tab(0, 8)
19+
local headers = util.dict(nil, 0, 8)
2120

2221
for k, v in pairs(BUILTIN_HEADERS) do
2322
headers[k] = v

lib/resty/requests/util.lua

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,22 @@
33
local type = type
44
local pcall = pcall
55
local pairs = pairs
6+
local error = error
67
local rawget = rawget
78
local setmetatable = setmetatable
89
local lower = string.lower
9-
local upper = string.upper
1010
local ngx_gsub = ngx.re.gsub
11-
local ngx_sub = ngx.re.sub
1211
local base64 = ngx.encode_base64
1312

1413
local _M = { _VERSION = '0.1' }
1514

1615
local header_mt = {
1716
__index = function(t, k)
18-
local name = ngx_gsub(lower(k), "_", "-", "jo")
17+
local name, _, err = ngx_gsub(lower(k), "_", "-", "jo")
18+
if err then
19+
error(err)
20+
end
21+
1922
return rawget(t, name)
2023
end
2124
}
@@ -28,8 +31,8 @@ if not ok then
2831
end
2932

3033
local BUILTIN_HEADERS = {
31-
["Accept"] = "*/*",
32-
["User-Agent"] = "resty-requests",
34+
["accept"] = "*/*",
35+
["user-agent"] = "resty-requests",
3336
}
3437

3538
local STATE = {
@@ -69,15 +72,6 @@ local function is_tab(obj) return type(obj) == "table" end
6972
local function is_func(obj) return type(obj) == "function" end
7073

7174

72-
local function normalize_header_name(name)
73-
local f = function(m) return upper(m[1]) end
74-
75-
name = ngx_sub(name, "(^[a-z])", f)
76-
name = ngx_sub(name, "(-[a-z])", f)
77-
return name
78-
end
79-
80-
8175
local function dict(d, narr, nrec)
8276
if not d then
8377
d = new_tab(narr, nrec)
@@ -115,12 +109,17 @@ local function set_config(opts)
115109
end
116110

117111
-- 3) request headers
118-
config.headers = dict(opts.headers, 0, 5)
112+
config.headers = dict(nil, 0, 5)
119113

120-
for k, v in pairs(config.headers) do
121-
local name = normalize_header_name(k)
122-
config.headers[k] = nil
123-
config.headers[name] = v
114+
if opts.headers then
115+
for k, v in pairs(opts.headers) do
116+
local name, _, err = ngx_gsub(lower(k), "_", "-", "jo")
117+
if err then
118+
error(err)
119+
end
120+
121+
config.headers[name] = v
122+
end
124123
end
125124

126125
for k, v in pairs(BUILTIN_HEADERS) do

t/00-sanity.t

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -182,10 +182,10 @@ GET /t
182182
183183
--- response_body eval
184184
qq{GET /t1?foo=bar&c= HTTP/1.1\r
185-
User-Agent: resty-requests\r
186-
Accept: */*\r
187-
Connection: keep-alive\r
188-
Host: 127.0.0.1\r
185+
host: 127.0.0.1\r
186+
user-agent: resty-requests\r
187+
accept: */*\r
188+
connection: keep-alive\r
189189
\r
190190
};
191191
@@ -235,11 +235,11 @@ GET /t
235235
236236
--- response_body eval
237237
qq{GET /t1 HTTP/1.1\r
238-
User-Agent: resty-requests\r
239-
Accept: */*\r
240-
Connection: keep-alive\r
241-
Cache-Control: max-age=0\r
242-
Host: 127.0.0.1\r
238+
cache-control: max-age=0\r
239+
user-agent: resty-requests\r
240+
accept: */*\r
241+
connection: keep-alive\r
242+
host: 127.0.0.1\r
243243
\r
244244
}
245245
@@ -280,12 +280,12 @@ GET /t1
280280
--- status_code: 200
281281
--- response_body eval
282282
qq{GET /t3?usebody=true&af=b HTTP/1.1\r
283-
User-Agent: resty-requests\r
284-
Accept: */*\r
285-
Content-Type: text/plain\r
286-
Connection: keep-alive\r
287-
Content-Length: 18\r
288-
Host: 127.0.0.1\r
283+
host: 127.0.0.1\r
284+
content-length: 18\r
285+
user-agent: resty-requests\r
286+
accept: */*\r
287+
connection: keep-alive\r
288+
content-type: text/plain\r
289289
\r
290290
你好吗?Hello?}
291291
@@ -329,12 +329,12 @@ GET /t1
329329
330330
--- response_body eval
331331
qq{GET /t3 HTTP/1.1\r
332-
User-Agent: resty-requests\r
333-
Accept: */*\r
334-
Connection: keep-alive\r
335-
Content-Type: application/octet-stream\r
336-
Host: 127.0.0.1\r
337-
Transfer-Encoding: chunked\r
332+
host: 127.0.0.1\r
333+
content-type: application/octet-stream\r
334+
user-agent: resty-requests\r
335+
accept: */*\r
336+
connection: keep-alive\r
337+
transfer-encoding: chunked\r
338338
\r
339339
hellohellohellohello}
340340
@@ -524,10 +524,10 @@ GET /t1
524524
525525
--- response_body eval
526526
qq{GET /t1?test=event_hook HTTP/1.1\r
527-
User-Agent: resty-requests\r
528-
Accept: */*\r
529-
Connection: keep-alive\r
530-
Host: 127.0.0.1\r
527+
host: 127.0.0.1\r
528+
user-agent: resty-requests\r
529+
accept: */*\r
530+
connection: keep-alive\r
531531
\r
532532
};
533533
@@ -1093,11 +1093,11 @@ GET /t
10931093

10941094
--- response_body eval
10951095
qq{GET /t1 HTTP/1.1\r
1096-
User-Agent: resty-requests\r
1097-
Accept: */*\r
1098-
Connection: keep-alive\r
1099-
Content-Length: 3\r
1100-
Host: 127.0.0.1\r
1096+
host: 127.0.0.1\r
1097+
content-length: 3\r
1098+
user-agent: resty-requests\r
1099+
accept: */*\r
1100+
connection: keep-alive\r
11011101
\r
11021102
};
11031103
--- no_error_log

t/02-shortpath.t

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,11 @@ GET /t
7777
7878
--- response_body eval
7979
qq{GET /t1 HTTP/1.1\r
80-
User-Agent: resty-requests\r
81-
Accept: */*\r
82-
Cookie: name3=value3; name1=value1; name2=value2\r
83-
Connection: keep-alive\r
84-
Host: 127.0.0.1\r
80+
host: 127.0.0.1\r
81+
cookie: name3=value3; name1=value1; name2=value2\r
82+
user-agent: resty-requests\r
83+
accept: */*\r
84+
connection: keep-alive\r
8585
\r
8686
};
8787
@@ -125,11 +125,11 @@ GET /t
125125
126126
--- response_body eval
127127
qq{GET /t1 HTTP/1.1\r
128-
User-Agent: resty-requests\r
129-
Accept: */*\r
130-
Authorization: Basic YWxleDoxMjM0NTY=\r
131-
Connection: keep-alive\r
132-
Host: 127.0.0.1\r
128+
host: 127.0.0.1\r
129+
authorization: Basic YWxleDoxMjM0NTY=\r
130+
user-agent: resty-requests\r
131+
accept: */*\r
132+
connection: keep-alive\r
133133
\r
134134
};
135135

0 commit comments

Comments
 (0)