@@ -24,7 +24,7 @@ defmodule Bandit.HTTP1.Socket do
2424 @ type read_state :: :unread | :headers_read | :read
2525
2626 @ typedoc "An HTTP/1 write state"
27- @ type write_state :: :unsent | :writing | :chunking | :sent
27+ @ type write_state :: :unsent | :writing | :chunking | :chunk_streaming | : sent
2828
2929 @ typedoc "The information necessary to communicate to/from a socket"
3030 @ type t :: % __MODULE__ {
@@ -328,18 +328,24 @@ defmodule Bandit.HTTP1.Socket do
328328
329329 { headers , socket } = handle_keepalive ( status , headers , socket )
330330
331+ has_content_length = Bandit.Headers . get_header ( headers , "content-length" ) != nil
332+
331333 case body_disposition do
332334 :raw ->
333335 # This is an optimization for the common case of sending a non-encoded body (or file),
334336 # and coalesces the header and body send calls into a single ThousandIsland.Socket.send/2
335337 # call. This makes a _substantial_ difference in practice
336338 % { socket | write_state: :writing , send_buffer: [ resp_line | encode_headers ( headers ) ] }
337339
338- :chunk_encoded ->
340+ :chunk_encoded when not has_content_length ->
339341 headers = [ { "transfer-encoding" , "chunked" } | headers ]
340342 send! ( socket . socket , [ resp_line | encode_headers ( headers ) ] )
341343 % { socket | write_state: :chunking }
342344
345+ :chunk_encoded when has_content_length ->
346+ send! ( socket . socket , [ resp_line | encode_headers ( headers ) ] )
347+ % { socket | write_state: :chunk_streaming }
348+
343349 :no_body ->
344350 send! ( socket . socket , [ resp_line | encode_headers ( headers ) ] )
345351 % { socket | write_state: :sent }
@@ -394,6 +400,12 @@ defmodule Bandit.HTTP1.Socket do
394400 % { socket | write_state: write_state }
395401 end
396402
403+ def send_data ( % @ for { write_state: :chunk_streaming } = socket , data , end_request ) do
404+ send! ( socket . socket , data )
405+ write_state = if end_request , do: :sent , else: :chunk_streaming
406+ % { socket | write_state: write_state }
407+ end
408+
397409 def sendfile ( % @ for { write_state: :writing } = socket , path , offset , length ) do
398410 send! ( socket . socket , socket . send_buffer )
399411
0 commit comments