Repository navigation
Reject response header blocks that don’t include the :status field - #311
Conversation
| # an internal event, so we can do away with this branch. | ||
| is_trailer = False | ||
|
|
||
| is_response_header = is_response and not is_trailer |
There was a problem hiding this comment.
is_response should be completely determinable by the events. Do we really need the extra parameter?
|
Great start @sunu! So far this looks really good, I've left a few notes inline for you to look over. |
|
Thanks for the review @Lukasa @alexwlchan. I've updated the PR addressing most of the comments. |
| ) | ||
| is_response_header = isinstance( | ||
| events[0], ResponseReceived | ||
| ) and not self.state_machine.client |
There was a problem hiding this comment.
Do we need this and not check? I believe that ResponseReceived can only fire when we are a client.
While we're here, I suspect we're going to need an internal-only _ResponseSent event, much like the _TrailersSent event you can see in the block above.
|
Great! I have left some more notes. |
| u':status' not in seen_pseudo_header_fields | ||
| ): | ||
| seen_status_field = (b':status' in seen_pseudo_header_fields or | ||
| u':status' in seen_pseudo_header_fields) |
There was a problem hiding this comment.
Oops. Yeah, sorry about that. Will fix.
Lukasa
left a comment
There was a problem hiding this comment.
Awesome, one small comment change and then I think we're ready to go!
| This is an internal event, used to determine validation steps on | ||
| outgoing header blocks. | ||
| """ | ||
| pass |
There was a problem hiding this comment.
I'd like at this point to also add a _RequestHeadersSent field. We don't have to do it as part of this PR, but can you open a new issue to track adding the new internal event? The lack of symmetry is making me sad. ;)
| c.initiate_connection() | ||
| c.send_headers(1, self.example_request_headers) | ||
| f = frame_factory.build_headers_frame(self.example_request_headers) | ||
| f = frame_factory.build_headers_frame(self.example_response_headers) |
There was a problem hiding this comment.
Heh, nice catch! That's a good validation that the new code is working as expected!
|
Response headers may never contain |
@Lukasa which comment change are you refering to? (I have already added a comment about ResponseHeadersSent event if that's the one you're refering to) Also, what about the failing test? :P |
|
@Lukasa @nateprewitt Off topic but I get emails whenever you guys comment, but I can't find the last couple of comments on the Github ui anywhere (I tried for at least 5 minutes :P) Any idea what's going on? |
|
Heh, sorry, they're in an outdated diff. If you scroll up a little bit you'll find a dropdown saying "x commented on an outdated diff": you want the one with lots of comments in it. ;) |
|
@Lukasa PR updated |
| hdr_validation_flags): | ||
| def test_matching_authority_host_headers( | ||
| self, validation_function, hdr_validation_flags | ||
| ): |
There was a problem hiding this comment.
Heh, sorry, I know that this isn't what you were told earlier, but the original style of this function was better. Basically, for function definitions I like having the argument names lined up, but for any other multiline sections I like having the parentheses by themselves.
Lukasa
left a comment
There was a problem hiding this comment.
One tiny comment note! We're nearly there!
| # Some state changes don't emit an internal event (for example, | ||
| # sending a push promise). We *always* emit an event for trailers, | ||
| # so the absence of an event means this definitely isn't a trailer. | ||
| # Similarly, we also emit an event whenever reponse headers are |
alexwlchan
left a comment
There was a problem hiding this comment.
Overall looks pretty good to me! Just a few minor suggestions.
| ) | ||
|
|
||
| # If ':status' pseudo-header is not there in a response header, reject it | ||
| seen_status_field = ( |
There was a problem hiding this comment.
I wonder if it’s worth moving the evaluation of seen_status_field into a conditional block that only runs if this is a response header, i.e.,
if hdr_validation_flags.is_response_header:
seen_status_header = (...)
if not seen_status_field:
raise ProtocolError(...)which saves us two unnecessary set lookups on request headers.
| ] | ||
| hdr_validation_response_headers = list( | ||
| filter(lambda flags: flags.is_response_header, hdr_validation_combos) | ||
| ) |
There was a problem hiding this comment.
(Opinion) I’d prefer this as a list comprehension, as I think that’s easier to see at a glance what the condition is, i.e.,
hdr_validation_response_headers = [
flags for flags in hdr_validation_combos
if flags.is_response_header
]and
hdr_validation_response_headers = [
flags for flags in hdr_validation_combos
if not (flags.is_trailer or flags.is_response_header)
]but if @Lukasa is happy with list(filter(lambda(...))), I’ll shut up about it.
There was a problem hiding this comment.
I have no problem with using a list comprehension.
| seen_pseudo_header_fields | ||
| ) | ||
|
|
||
| # If ':status' pseudo-header is not there in a response header, reject it |
There was a problem hiding this comment.
It would be nice if this comment had a reference to the exact RFC section – I know we‘ve not been super consistent on that point, but I think it’s helpful.
To save you looking it up again: RFC 7540 § 8.1.2.4.
| events[0], (_TrailersSent, TrailersReceived) | ||
| ) | ||
| is_response_header = isinstance( | ||
| events[0], (_ResponseHeadersSent, ResponseReceived) |
There was a problem hiding this comment.
(Trivial) Seeing these side-by-side, I wonder if we should drop Headers from the name of this event, i.e., _ResponseSent. Better symmetry, and matches what I did for _TrailerSent.
There was a problem hiding this comment.
Rather than deal with this in this ticket, let's open a new one related to this issue and #314 that refactors the event names.
|
@sunu I'm aware that you're probably just taking a break, but as an FYI I'd like you to address @alexwlchan's reviews before I do another review. =) |
|
@Lukasa @alexwlchan PR updated! |
alexwlchan
left a comment
There was a problem hiding this comment.
Okay, all looks good to me!
| events[0], (_TrailersSent, TrailersReceived) | ||
| ) | ||
| is_response_header = isinstance( | ||
| events[0], (_ResponseHeadersSent, ResponseReceived) |
Lukasa
left a comment
There was a problem hiding this comment.
Excellent work! This looks great to me, I'm so delighted that you finished it up. ✨
|
Can you please merge in the latest master branch? I'd like to confirm that the tests still pass with it in place. |
|
@Lukasa Done! :) |
Fix for #290