@@ -135,7 +135,7 @@ function _M.new(_)
135
135
return nil , err
136
136
end
137
137
return setmetatable ({
138
- sock = sock , keepalive_supported = true , keepalive_ready = false
138
+ sock = sock , keepalive_supported = true , reader_state = { keepalive_ready = false , mark_keepalive_ready_on_body_read = true }
139
139
}, mt )
140
140
end
141
141
@@ -197,6 +197,8 @@ function _M.tcp_only_connect(self, ...)
197
197
self .port = nil
198
198
end
199
199
200
+ -- Immediately after connection - keepalive should be possible
201
+ self .reader_state .keepalive_ready = true
200
202
self .keepalive_supported = true
201
203
self .ssl = false
202
204
@@ -211,7 +213,7 @@ function _M.set_keepalive(self, ...)
211
213
end
212
214
213
215
if self .keepalive_supported == true then
214
- if not self .keepalive_ready then
216
+ if not self .reader_state . keepalive_ready then
215
217
return nil , " response not fully read"
216
218
end
217
219
435
437
_M .transfer_encoding_is_chunked = transfer_encoding_is_chunked
436
438
437
439
438
- local function _reader_keepalive_ready_mark (http_client )
439
- return function ()
440
- http_client .keepalive_ready = true
441
- end
442
- end
443
-
444
- local function _reader_keepalive_ready_no_op ()
445
- return function () end
446
- end
447
-
448
-
449
- local function _chunked_body_reader (keepalive_ready_callback , sock , default_chunk_size )
440
+ local function _chunked_body_reader (reader_state , sock , default_chunk_size )
450
441
return co_wrap (function (max_chunk_size )
451
442
local remaining = 0
452
443
local length
@@ -505,12 +496,14 @@ local function _chunked_body_reader(keepalive_ready_callback, sock, default_chun
505
496
506
497
until length == 0
507
498
508
- keepalive_ready_callback ()
499
+ if reader_state .mark_keepalive_ready_on_body_read then
500
+ reader_state .keepalive_ready = true
501
+ end
509
502
end )
510
503
end
511
504
512
505
513
- local function _body_reader (keepalive_ready_callback , sock , content_length , default_chunk_size )
506
+ local function _body_reader (reader_state , sock , content_length , default_chunk_size )
514
507
return co_wrap (function (max_chunk_size )
515
508
max_chunk_size = max_chunk_size or default_chunk_size
516
509
@@ -540,8 +533,9 @@ local function _body_reader(keepalive_ready_callback, sock, content_length, defa
540
533
elseif not max_chunk_size then
541
534
-- We have a length and potentially keep-alive, but want everything.
542
535
co_yield (sock :receive (content_length ))
543
- keepalive_ready_callback ()
544
-
536
+ if reader_state .mark_keepalive_ready_on_body_read then
537
+ reader_state .keepalive_ready = true
538
+ end
545
539
else
546
540
-- We have a length and potentially a keep-alive, and wish to stream
547
541
-- the response.
@@ -569,7 +563,9 @@ local function _body_reader(keepalive_ready_callback, sock, content_length, defa
569
563
end
570
564
571
565
until length == 0
572
- keepalive_ready_callback ()
566
+ if reader_state .mark_keepalive_ready_on_body_read then
567
+ reader_state .keepalive_ready = true
568
+ end
573
569
end
574
570
end )
575
571
end
@@ -608,10 +604,11 @@ local function _read_body(res)
608
604
end
609
605
610
606
611
- local function _trailer_reader (keepalive_ready_callback , sock )
607
+ local function _trailer_reader (reader_state , sock )
612
608
return co_wrap (function ()
613
609
co_yield (_receive_headers (sock ))
614
- keepalive_ready_callback ()
610
+ -- We can always pool after reading trailers
611
+ reader_state .keepalive_ready = true
615
612
end )
616
613
end
617
614
@@ -677,7 +674,7 @@ function _M.send_request(self, params)
677
674
setmetatable (params , { __index = DEFAULT_PARAMS })
678
675
679
676
-- Sending a new request makes keepalive disabled until its response is fully read
680
- self .keepalive_ready = false
677
+ self .reader_state . keepalive_ready = false
681
678
682
679
local sock = self .sock
683
680
local body = params .body
@@ -830,23 +827,16 @@ function _M.read_response(self, params)
830
827
local trailer_reader
831
828
local has_body = false
832
829
local has_trailer = false
833
- local body_reader_keepalive_ready_callback
834
830
835
- if res_headers [" Trailer" ] then
836
- has_trailer = true
837
- -- If there are trailers - fully reading response body doesn't mean socket is ready to be pooled
838
- body_reader_keepalive_ready_callback = _reader_keepalive_ready_no_op ()
839
- else
840
- -- If there are no trailers - fully reading response body means socket is ready to be pooled
841
- body_reader_keepalive_ready_callback = _reader_keepalive_ready_mark (self )
842
- end
831
+ has_trailer = (res_headers [" Trailer" ] ~= nil )
832
+ self .reader_state .mark_keepalive_ready_on_body_read = not has_trailer
843
833
844
834
-- Receive the body_reader
845
835
if _should_receive_body (params .method , status ) then
846
836
has_body = true
847
837
848
838
if version == 1.1 and transfer_encoding_is_chunked (res_headers ) then
849
- body_reader , err = _chunked_body_reader (body_reader_keepalive_ready_callback , sock )
839
+ body_reader , err = _chunked_body_reader (self . reader_state , sock )
850
840
else
851
841
local length
852
842
ok , length = pcall (tonumber , res_headers [" Content-Length" ])
@@ -855,17 +845,17 @@ function _M.read_response(self, params)
855
845
length = nil
856
846
end
857
847
858
- body_reader , err = _body_reader (body_reader_keepalive_ready_callback , sock , length )
848
+ body_reader , err = _body_reader (self . reader_state , sock , length )
859
849
end
860
850
else
861
851
if not has_trailer then
862
852
-- If there's no body and no trailer - it's ready for keep-alive
863
- self .keepalive_ready = true
853
+ self .reader_state . keepalive_ready = true
864
854
end
865
855
end
866
856
867
857
if has_trailer then
868
- trailer_reader , err = _trailer_reader (_reader_keepalive_ready_mark ( self ) , sock )
858
+ trailer_reader , err = _trailer_reader (self . reader_state , sock )
869
859
end
870
860
871
861
if err then
@@ -1024,14 +1014,15 @@ function _M.get_client_body_reader(_, chunksize, sock)
1024
1014
end
1025
1015
end
1026
1016
1027
- local reader_keep_alive_ready_callback = _reader_keepalive_ready_no_op ()
1017
+ -- Reading the request body has nothing to do with pooling the upstream server socket
1018
+ local request_body_reader_state = { mark_keepalive_ready_on_body_read = false }
1028
1019
local headers = ngx_req_get_headers ()
1029
1020
local length = headers .content_length
1030
1021
if length then
1031
- return _body_reader (reader_keep_alive_ready_callback , sock , tonumber (length ), chunksize )
1022
+ return _body_reader (request_body_reader_state , sock , tonumber (length ), chunksize )
1032
1023
elseif transfer_encoding_is_chunked (headers ) then
1033
1024
-- Not yet supported by ngx_lua but should just work...
1034
- return _chunked_body_reader (reader_keep_alive_ready_callback , sock , chunksize )
1025
+ return _chunked_body_reader (request_body_reader_state , sock , chunksize )
1035
1026
else
1036
1027
return nil
1037
1028
end
0 commit comments