mojo icon indicating copy to clipboard operation
mojo copied to clipboard

sorted headers

Open fayland opened this issue 2 years ago • 16 comments

  • Mojolicious version: ALL
  • Perl version: ALL
  • Operating system: ALL

Steps to reproduce the behavior

if you do with curl or Chrome or whatever browser, the headers are always sorted as typed. but in Perl since headers are hash, the order is somehow not desired

Expected behavior

header Host is before header Accept for example.

Actual behavior

Host might be the last in Mojo::Headers::to_string

we can try to add "sorted_headers" as ArrayRef and fix the return part for 'sub names' in Mojo::Headers

if you need a patch, I can submit one. but first of all, please agree that's acceptable.

Thanks

fayland avatar Apr 12 '22 14:04 fayland

What is the problem you are trying to solve?

kraih avatar Apr 12 '22 15:04 kraih

references:

  • https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html "The order in which header fields with differing field names are received is not significant. However, it is "good practice" to send general-header fields first, followed by request-header or response- header fields, and ending with the entity-header fields. "

  • HTTP::Headers follows the "good practice" order: https://metacpan.org/pod/HTTP::Headers#$h-%3Eheader_field_names https://metacpan.org/dist/HTTP-Message/source/lib/HTTP/Headers.pm#L14-63

karenetheridge avatar Apr 12 '22 15:04 karenetheridge

@karenetheridge Ordering headers that way is very expensive, we are not going to do that.

kraih avatar Apr 12 '22 15:04 kraih

This could be enabled optionally (defaulting to off), so those who want the ordered headers at the expense of performance can have it.

karenetheridge avatar Apr 12 '22 16:04 karenetheridge

one of my issue is that CloudFlare actually detects the order of headers. and return 403 forbidden if the order is not correct. (I can provider example if you need it)

can make it optional like has 'ordered_headers'; or pass { Host => 'a', Referer => 'b', __sorted => ['Host', 'Referer'] } as headers.

Thanks

fayland avatar Apr 13 '22 00:04 fayland

Could this be done with a hook and therefore a plugin?

s1037989 avatar Apr 13 '22 02:04 s1037989

@fayland: In which case does it return a 403? I've been running my Mojo apps behind Cloudflare for many years and never experienced what you are saying.

jhthorsen avatar Apr 13 '22 06:04 jhthorsen

CODE REMOVED

Thanks

fayland avatar Apr 13 '22 07:04 fayland

@fayland: What I meant is that there's probably a some firewall rule (or another setting) in Cloudflare that has been enabled for this to happen, no..?

jhthorsen avatar Apr 13 '22 08:04 jhthorsen

not sure. I have to overwrite Mojo::Headers::to_string to make it working right now. thinking it might be good if we can do a feature to make header sortable. if it's not acceptable, it's alright as well since I can do it with *Mojo::Headers::to_string

Thanks

fayland avatar Apr 13 '22 08:04 fayland

It does sound a bit random though. Maybe just apply a role for this case?

# Make a custom to_string()
package Mojo::Headers::Role::Sorted;
use Mojo::Base -role, -signatures;
around to_string => sub ($next, $self) { ... };

# And then apply it to the user agent:
package main;
my $ua = Mojo::UserAgent->new;
$ua->on(start => sub ($ua, $tx) { $tx->req->headers->with_roles('+Sorted') });

jhthorsen avatar Apr 13 '22 10:04 jhthorsen

I can replicate the problem with the test case, it fails randomly based on header order. What i find interesting is that even just alphabetical order of headers makes it pass.

kraih avatar Apr 18 '22 17:04 kraih

does anyone know anyone at CloudFlare? This is such a flagrant violation of the RFCs, and it would actually take a lot of effort to fail like this; what on earth could the justification be for it??

karenetheridge avatar Apr 18 '22 18:04 karenetheridge

Could be WebSocket specific, given the test case. Handshakes are easy to get wrong given their relationship to HTTP 1.1. But anyway, i'm happy to try alphabetical headers to make our generated HTTP messages more canonical. https://github.com/mojolicious/mojo/commit/64354fac02f63a6cb023076080eaf5d6432d6562

kraih avatar Apr 18 '22 18:04 kraih

Alphabetical is not the "good practice" order though. https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html

karenetheridge avatar Apr 18 '22 18:04 karenetheridge

Alphabetical is not the "good practice" order though. https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html

It's canonical and fast though.

kraih avatar Apr 18 '22 18:04 kraih