@@ -134,7 +134,9 @@ function _M.new(_)
134
134
if not sock then
135
135
return nil , err
136
136
end
137
- return setmetatable ({ sock = sock , keepalive = true }, mt )
137
+ return setmetatable ({
138
+ sock = sock , keepalive_supported = true , keepalive_ready = false , pool_only_after_response = false
139
+ }, mt )
138
140
end
139
141
140
142
@@ -195,7 +197,7 @@ function _M.tcp_only_connect(self, ...)
195
197
self .port = nil
196
198
end
197
199
198
- self .keepalive = true
200
+ self .keepalive_supported = true
199
201
self .ssl = false
200
202
201
203
return sock :connect (... )
@@ -208,7 +210,11 @@ function _M.set_keepalive(self, ...)
208
210
return nil , " not initialized"
209
211
end
210
212
211
- if self .keepalive == true then
213
+ if self .keepalive_supported == true then
214
+ if self .pool_only_after_response and not self .keepalive_ready then
215
+ return nil , " response not fully read"
216
+ end
217
+
212
218
return sock :setkeepalive (... )
213
219
else
214
220
-- The server said we must close the connection, so we cannot setkeepalive.
429
435
_M .transfer_encoding_is_chunked = transfer_encoding_is_chunked
430
436
431
437
432
- local function _chunked_body_reader (sock , default_chunk_size )
438
+ local function _reader_keepalive_ready_mark (http_client )
439
+ return co_wrap (function ()
440
+ http_client .keepalive_ready = true
441
+ end )
442
+ end
443
+
444
+ local function _reader_keepalive_ready_no_op ()
445
+ return co_wrap (function () end )
446
+ end
447
+
448
+
449
+ local function _chunked_body_reader (keepalive_ready_callback , sock , default_chunk_size )
433
450
return co_wrap (function (max_chunk_size )
434
451
local remaining = 0
435
452
local length
@@ -487,11 +504,13 @@ local function _chunked_body_reader(sock, default_chunk_size)
487
504
end
488
505
489
506
until length == 0
507
+
508
+ keepalive_ready_callback ()
490
509
end )
491
510
end
492
511
493
512
494
- local function _body_reader (sock , content_length , default_chunk_size )
513
+ local function _body_reader (keepalive_ready_callback , sock , content_length , default_chunk_size )
495
514
return co_wrap (function (max_chunk_size )
496
515
max_chunk_size = max_chunk_size or default_chunk_size
497
516
@@ -521,6 +540,7 @@ local function _body_reader(sock, content_length, default_chunk_size)
521
540
elseif not max_chunk_size then
522
541
-- We have a length and potentially keep-alive, but want everything.
523
542
co_yield (sock :receive (content_length ))
543
+ keepalive_ready_callback ()
524
544
525
545
else
526
546
-- We have a length and potentially a keep-alive, and wish to stream
@@ -549,6 +569,7 @@ local function _body_reader(sock, content_length, default_chunk_size)
549
569
end
550
570
551
571
until length == 0
572
+ keepalive_ready_callback ()
552
573
end
553
574
end )
554
575
end
@@ -587,9 +608,10 @@ local function _read_body(res)
587
608
end
588
609
589
610
590
- local function _trailer_reader (sock )
611
+ local function _trailer_reader (keepalive_ready_callback , sock )
591
612
return co_wrap (function ()
592
613
co_yield (_receive_headers (sock ))
614
+ keepalive_ready_callback ()
593
615
end )
594
616
end
595
617
@@ -781,7 +803,8 @@ function _M.read_response(self, params)
781
803
end
782
804
783
805
784
- local res_headers , err = _receive_headers (sock )
806
+ local res_headers
807
+ res_headers , err = _receive_headers (sock )
785
808
if not res_headers then
786
809
return nil , err
787
810
end
@@ -791,38 +814,48 @@ function _M.read_response(self, params)
791
814
if ok then
792
815
if (version == 1.1 and str_find (connection , " close" , 1 , true )) or
793
816
(version == 1.0 and not str_find (connection , " keep-alive" , 1 , true )) then
794
- self .keepalive = false
817
+ self .keepalive_supported = false
795
818
end
796
819
else
797
820
-- no connection header
798
821
if version == 1.0 then
799
- self .keepalive = false
822
+ self .keepalive_supported = false
800
823
end
801
824
end
802
825
803
826
local body_reader = _no_body_reader
804
- local trailer_reader , err
827
+ local trailer_reader
805
828
local has_body = false
829
+ local has_trailer = false
830
+ -- If there are no trailers - fully reading response body means socket is ready to be pooled
831
+ local body_reader_keepalive_ready_callback = _reader_keepalive_ready_mark (self )
832
+
833
+ if res_headers [" Trailer" ] then
834
+ has_trailer = true
835
+ -- If there are trailers - fully reading response body doesn't mean socket is ready to be pooled
836
+ body_reader_keepalive_ready_callback = _reader_keepalive_ready_no_op ()
837
+ end
806
838
807
839
-- Receive the body_reader
808
840
if _should_receive_body (params .method , status ) then
809
841
has_body = true
810
842
811
843
if version == 1.1 and transfer_encoding_is_chunked (res_headers ) then
812
- body_reader , err = _chunked_body_reader (sock )
844
+ body_reader , err = _chunked_body_reader (body_reader_keepalive_ready_callback , sock )
813
845
else
814
- local ok , length = pcall (tonumber , res_headers [" Content-Length" ])
846
+ local length
847
+ ok , length = pcall (tonumber , res_headers [" Content-Length" ])
815
848
if not ok then
816
849
-- No content-length header, read until connection is closed by server
817
850
length = nil
818
851
end
819
852
820
- body_reader , err = _body_reader (sock , length )
853
+ body_reader , err = _body_reader (body_reader_keepalive_ready_callback , sock , length )
821
854
end
822
855
end
823
856
824
- if res_headers [ " Trailer " ] then
825
- trailer_reader , err = _trailer_reader (sock )
857
+ if has_trailer then
858
+ trailer_reader , err = _trailer_reader (_reader_keepalive_ready_mark ( self ), sock )
826
859
end
827
860
828
861
if err then
@@ -981,13 +1014,14 @@ function _M.get_client_body_reader(_, chunksize, sock)
981
1014
end
982
1015
end
983
1016
1017
+ local reader_keep_alive_ready_callback = _reader_keepalive_ready_no_op ()
984
1018
local headers = ngx_req_get_headers ()
985
1019
local length = headers .content_length
986
1020
if length then
987
- return _body_reader (sock , tonumber (length ), chunksize )
1021
+ return _body_reader (reader_keep_alive_ready_callback , sock , tonumber (length ), chunksize )
988
1022
elseif transfer_encoding_is_chunked (headers ) then
989
1023
-- Not yet supported by ngx_lua but should just work...
990
- return _chunked_body_reader (sock , chunksize )
1024
+ return _chunked_body_reader (reader_keep_alive_ready_callback , sock , chunksize )
991
1025
else
992
1026
return nil
993
1027
end
0 commit comments