Skip to content

Conversation

stefanoverna
Copy link
Contributor

As Rack::Lint points out, if the response status is 204, there should not be any Content-Type header set. Let me know if everything is alright with this PR @jodosha. I don't really like having to reference @_status outside of Lotus::Action::Rack, but there's no getter :confused:

@jodosha
Copy link
Member

jodosha commented Dec 12, 2014

@stefanoverna Thanks for this PR. I agree, referencing @_status from there isn't great and that conditional looks "magic". Can you please abstract with something like if send_content_type?.

@rugginoso
Copy link

There are others http responses which require an empty body, from the rfc (http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html):
"All 1xx (informational), 204 (no content), and 304 (not modified) responses MUST NOT include a message-body. All other responses do include a message-body, although it MAY be of zero length."

@jodosha
Copy link
Member

jodosha commented Dec 13, 2014

@rugginoso True, I've put that thing in place for lotusrb full stack, but not here.

I think we should differentiate between "empty headers" policy and "empty body", because some HTTP statuses like 204 want totally empty response.

Also, this looks like a control to move away from Lotus::Action::Mime and put into another custom module like Action::Http where we do those kind of checks.

The reason is simple: we need to check at the end of the pipeline that the body/headers are empty when needed.

Would you guys mind to amend this PR with those changes and rebase? Thank you!

@stefanoverna
Copy link
Contributor Author

@jodosha yeah, sure. Will try to do it! 👍

@stefanoverna
Copy link
Contributor Author

@jodosha how about something like this?

@coveralls
Copy link

Coverage Status

Coverage increased (+0.03%) when pulling 2b6468f on stefanoverna:no-content into 975feb8 on lotus:master.

@jodosha
Copy link
Member

jodosha commented Dec 19, 2014

@stefanoverna I'm sorry for the late reply here.

RFC 2616

10.2.5 204 No Content

The server has fulfilled the request but does not need to return an
entity-body, and might want to return updated metainformation. The
response MAY include new or updated metainformation in the form of
entity-headers, which if present SHOULD be associated with the
requested variant.

Source

In my understanding, HTTP headers can be sent if they are related to entities (aka custom headers). At the same time, default headers like Content-Type and Content-Length MUST not be sent. At least according to the Rack::Lint interpretation.

Because this isn't mime type related issue, we should extract that test into a separated case under test/integration/ and make sure that the following diff passes.

diff --git a/test/integration/mime_type_test.rb b/test/integration/mime_type_test.rb
index bd7fe18..c339332 100644
--- a/test/integration/mime_type_test.rb
+++ b/test/integration/mime_type_test.rb
@@ -78,6 +78,8 @@ module Mimes

     def call(params)
       self.status = 204
+      headers['Content-Length'] = '0'
+      headers['X-Entity']       = 'OK'
     end
   end
 end
@@ -114,7 +116,9 @@ describe 'Content type' do
   it 'does not produce a "Content-Type" header when the request has a 204 No Content status' do
     response = @app.get('/nocontent')
     response.headers['Content-Type'].must_be_nil
-    response.body.must_equal                    ''
+    response.headers['Content-Length'].must_be_nil
+    response.headers['X-Entity'].must_equal 'OK'
+    response.body.must_equal                ''
   end

Would you like to take care of this? Thank you!

@stefanoverna
Copy link
Contributor Author

@jodosha I'm not entirely sold on your interpretation.. entity-headers are not custom headers (ie. X-Entity), but these headers:

7.1 Entity Header Fields

   Entity-header fields define metainformation about the entity-body or,
   if no body is present, about the resource identified by the request.
   Some of this metainformation is OPTIONAL; some might be REQUIRED by
   portions of this specification.

       entity-header  = Allow                    ; Section 14.7
                      | Content-Encoding         ; Section 14.11
                      | Content-Language         ; Section 14.12
                      | Content-Length           ; Section 14.13
                      | Content-Location         ; Section 14.14
                      | Content-MD5              ; Section 14.15
                      | Content-Range            ; Section 14.16
                      | Content-Type             ; Section 14.17
                      | Expires                  ; Section 14.21
                      | Last-Modified            ; Section 14.29
                      | extension-header

So, it seems that passing ie. Content-Type or Content-Length together with a 204 response code is perfectly valid. Rack::Lint is, well.. a linter, so it goes a step beyond and assumes it's not the right thing to do, even if valid.

@jodosha jodosha modified the milestone: v0.3.2 Jan 21, 2015
@jodosha
Copy link
Member

jodosha commented Jan 21, 2015

@stefanoverna @rugginoso There was some Git conflicts now solved. I also cleaned up the code and added new tests.

I'm going to merge this to ease the workflow, but there are still some unresolved points that I would love to discuss in another GH issue.

Thanks for your effort until now! 👍

@jodosha jodosha self-assigned this Jan 21, 2015
@jodosha jodosha added the bug label Jan 21, 2015
@jodosha jodosha merged commit 2b6468f into hanami:master Jan 21, 2015
@stefanoverna stefanoverna deleted the no-content branch January 21, 2015 11:44
@stefanoverna
Copy link
Contributor Author

great @jodosha feel free to mention us :)

@jodosha
Copy link
Member

jodosha commented Jan 21, 2015

@stefanoverna @rugginoso @lotus/core-team I moved the discussion here: rack/rack#787

@stefanoverna
Copy link
Contributor Author

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants