Hacker News new | ask | show | jobs
by Twirrim 2974 days ago
Honestly? I'm with the author here. "Response.ok" should tell me that the response is ok. It's the most natural expectation. If it's only going to check status code, Response.status_code.ok would be more reasonable.
3 comments

It's the most natural expectation. If it's only going to check status code, Response.status_code.ok would be more reasonable.

Except that the status line is literally "HTTP 200 OK", and the 'ok' check is simply using the domain terminology. This is not a bad thing. And having 'request.ok' be a general "I have examined every possible aspect of this response for problems and found none" is probably impossible, despite being what you apparently expect.

The solution is not to rename the method, it's to also warn or error when there's something fishy in the response. Which is apparently what requests 3.x will do.

There's also the issue that the Content-Length header, while generally well-adopted, is optional (sending either Content-Length or Transfer-Encoding is a SHOULD in RFC 7230, not a MUST), and sending an incorrect Content-Length, while annoying, is not actually against the RFC (the only MUST NOT prohibitions on an incorrect Content-Length value in the response are when the request was a HEAD or a conditional GET).

I'm not sure I agree with your assessment that sending an incorrect Content-Length is permitted. This specific post quotes a section in RFC-2616 that deals with this directly[1]:

  When a Content-Length is given in a message where a message-body is allowed, its field value MUST exactly
  match the number of OCTETs in the message-body.
According to this, the Content-Length MUST match the data. Can you share an example of the opposite being stated?

[1] https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4....

RFC2616 is obsoleted by RFC7230. Relevant section:

https://tools.ietf.org/html/rfc7230#section-3.3.2

Occurrences of MUST NOT for the server in that section are:

A sender MUST NOT send a Content-Length header field in any message that contains a Transfer-Encoding header field.

(so can't send both Content-Length and Transfer-Encoding)

A server MAY send a Content-Length header field in a response to a HEAD request (Section 4.3.2 of [RFC7231]); a server MUST NOT send Content-Length in such a response unless its field-value equals the decimal number of octets that would have been sent in the payload body of a response if the same request had used the GET method.

(if you send Content-Length on HEAD, it must match the length of the response you would have sent for GET)

A server MAY send a Content-Length header field in a 304 (Not Modified) response to a conditional GET request (Section 4.1 of [RFC7232]); a server MUST NOT send Content-Length in such a response unless its field-value equals the decimal number of octets that would have been sent in the payload body of a 200 (OK) response to the same request.

(you can send Content-Length on conditional GET; if you do, must match length of the response you would have sent for GET)

A server MUST NOT send a Content-Length header field in any response with a status code of 1xx (Informational) or 204 (No Content). A server MUST NOT send a Content-Length header field in any 2xx (Successful) response to a CONNECT request (Section 4.3.6 of [RFC7231]).

(some other situations that can't use Content-Length)

It may be an oversight, but nothing in that section requires that the Content-Length, in general, must match the size of the response body.

I'd say the HEAD section is the best implication about the behavior they expect. Where in this section there is precedent set for the spec requiring it to be equal.

I'll agree and admit that implication is not explicit specification, but I think it's a reasonable example to follow.

It's worth noting that browsers allow a lot of things that either look like errors to a human or are forbidden by the RFCs. Some people want defacto behavior, others want dejure.
Except that the status line is literally "HTTP 200 OK", and the 'ok' check is simply using the domain terminology.

Well, not exactly. From the documentation of .ok: "This is not a check to see if the response code is 200 OK."

Technically, it checks if status code is not between 400 and 600.

I agree with your point that there should be some baked in capability for a more comprehensive check on the HTTP response. There are probably some edge cases around this regarding stream=True (load header only, not content) and iter_content() which pulls chunks from a buffer so the entire content isn't loaded into memory at once. Probably surmountable.

FWIW Response.status_code is an int, so it might need to be a member function on Response.

Response.status_code is an int

No, it acts like an int; whether it is one (should be) irrelevant :)

    class StatusCode(int):
        @property
        def ok(self):
            return 200 <= self < 300
If a HTTP response is malformed, the most natural expectation for an exception to be thrown.

I'm glad to see the requests 3.0 does this by default for invalid Content-Length.