diff --git a/spec/std/http/server/handlers/compress_handler_spec.cr b/spec/std/http/server/handlers/compress_handler_spec.cr index f6c0b5ab653d..cb4badc994d1 100644 --- a/spec/std/http/server/handlers/compress_handler_spec.cr +++ b/spec/std/http/server/handlers/compress_handler_spec.cr @@ -127,7 +127,7 @@ describe HTTP::CompressHandler do response.close io.rewind - io.to_s.should eq("HTTP/1.1 304 Not Modified\r\nContent-Length: 0\r\n\r\n") + io.to_s.should eq("HTTP/1.1 304 Not Modified\r\n\r\n") end it "don't try to compress upgraded response" do diff --git a/spec/std/http/server/response_spec.cr b/spec/std/http/server/response_spec.cr index 0042f40c008f..f22aed60b294 100644 --- a/spec/std/http/server/response_spec.cr +++ b/spec/std/http/server/response_spec.cr @@ -42,6 +42,40 @@ describe HTTP::Server::Response do io.to_s.should eq("HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n") end + it "does not automatically add the `content-length` header if the response is a 304" do + io = IO::Memory.new + response = Response.new(io) + response.status = :not_modified + response.close + io.to_s.should eq("HTTP/1.1 304 Not Modified\r\n\r\n") + end + + it "does not automatically add the `content-length` header if the response is a 204" do + io = IO::Memory.new + response = Response.new(io) + response.status = :no_content + response.close + io.to_s.should eq("HTTP/1.1 204 No Content\r\n\r\n") + end + + it "does not automatically add the `content-length` header if the response is informational" do + io = IO::Memory.new + response = Response.new(io) + response.status = :processing + response.close + io.to_s.should eq("HTTP/1.1 102 Processing\r\n\r\n") + end + + # Case where the content-length represents the size of the data that would have been returned. + it "allows specifying the content-length header explicitly" do + io = IO::Memory.new + response = Response.new(io) + response.status = :not_modified + response.headers["Content-Length"] = "5" + response.close + io.to_s.should eq("HTTP/1.1 304 Not Modified\r\nContent-Length: 5\r\n\r\n") + end + it "prints less then buffer's size" do io = IO::Memory.new response = Response.new(io) diff --git a/src/http/server/response.cr b/src/http/server/response.cr index a2651339fcca..8b6a5fab736a 100644 --- a/src/http/server/response.cr +++ b/src/http/server/response.cr @@ -223,7 +223,12 @@ class HTTP::Server def close return if closed? - if !response.wrote_headers? && !response.headers.has_key?("Content-Length") + # Conditionally determine based on status if the `content-length` header should be added automatically. + # See https://tools.ietf.org/html/rfc7230#section-3.3.2. + status = response.status + set_content_length = !(status.not_modified? || status.no_content? || status.informational?) + + if !response.wrote_headers? && !response.headers.has_key?("Content-Length") && set_content_length response.content_length = @out_count end