Re: Inviting feedback on my proposed "ASGI" spec
Collin Anderson <[email protected]> Fri, 11 Mar 2016 13:03:35 -0500
| Newsgroups | gmane.comp.python.web |
|---|---|
| Message-ID | <CAFO84S4WhX_iJTFiAw+vVMbaZyn95jNEcUfRMkSX3G1aCSKWUw@mail.gmail.com> |
--===============7350659520008711350== Content-Type: multipart/alternative; boundary=089e011604261e4e6f052dc9c1f3 --089e011604261e4e6f052dc9c1f3 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable http2 makes all header names lowercase On Fri, Mar 11, 2016 at 12:59 PM, Andrew Godwin <[email protected]> wrote= : > One thing I did want to ask - is it worth still squashing everything down > to the same case? Daphne already clears out headers with _ in them to avo= id > that CVE about it, and header case is never semantic, or so I thought? > > Andrew > > On Fri, Mar 11, 2016 at 9:56 AM, Andrew Godwin <[email protected]> > wrote: > >> >> >> On Fri, Mar 11, 2016 at 2:28 AM, Cory Benfield <[email protected]> wrote= : >> >>> >>> On 10 Mar 2016, at 23:56, Andrew Godwin <[email protected]> wrote: >>> >>> I would indeed want to require servers to always fold headers together >>> into a comma-separated list, as that's what the RFC says, and it then m= eans >>> applications only have to deal with one kind of multi-header! >>> >>> >>> Wellllll=E2=80=A6.kinda? >>> >>> The RFC says that multiple headers are *semantically equivalent* to the >>> joined form, but does not in any sense require that it be done. (The >>> normative language in RFC 7230 is MAY.) >>> >>> I had this discussion recently with Brian Smith: while there is only on= e >>> correct way to fold/unfold headers, anywhere on the spectrum between >>> completely folded and completely unfolded is a perfectly valid >>> representation of the HTTP header block. This means that there=E2=80=99= s no *rules* >>> about how a server is supposed to do it, at least from the IETF. ASGI i= s of >>> course totally allowed to add its own rules, and requiring that they be >>> folded is not terrible. >>> >>> FWIW, in my experience, I=E2=80=99ve found that =E2=80=9Clist of tuples= =E2=80=9D is really the >>> most likely to be correct way to represent a header block, because it >>> provides some assurances to the user that the header block has not been >>> aggressively transformed from how it was sent on the wire. While the >>> *rules* are that the folded representation is supposed to be semantical= ly >>> equivalent to the unfolded representation, there is nonetheless some >>> information implicit in those headers being separate. >>> >>> My intuition when writing this kind of thing is to pass applications >>> (like Django) the most meaningful representation I can, and then allow = the >>> application to make its own decisions about what meaning they=E2=80=99r= e willing to >>> lose. That=E2=80=99s why I=E2=80=99d advocate for =E2=80=9Clist of two-= tuples of bytestrings=E2=80=9D as >>> the representation. However, I don=E2=80=99t think there=E2=80=99s anyt= hing *wrong* with >>> forcing the headers to be joined by the server where possible: it=E2=80= =99s just >>> not how I=E2=80=99d do it. ;) >>> >>> Set-cookie is the annoying thing here, though. That's why it's dict >>> inbound and list of tuples outbound right now, and I just don't know if= I >>> want to make the inbound one a list of tuples too, given I do definitel= y >>> want to force servers to concat headers together (unless I find any >>> examples of that screwing things up) >>> >>> >>> You could make the inbound one a list of tuples but still require that >>> the servers concat headers. The rule then would be that it needs to be >>> possible for an application to say `dict(headers)` without any loss of >>> meaning. >>> >> >> Yes, I think this is a good argument - my worry has always been that the >> "no multiples" is more of a soft rule that some clients might break or s= ome >> apps might rely on the ordering/multiplicity of things, so preserving it= is >> _probably_ helpful (and as you say, it lets the header names go back to >> bytestrings). >> >> I'll modify the spec and then update Daphne and Channels to match; I can >> leave Channels parsing both types for a bit, at least. >> >> Collin's point about http2's handling of headers is on point, too - if >> the new spec is deliberately thinned down to that point but no further, >> it's probably wise to follow them since they know much more about it tha= n I >> do. >> >> Andrew >> > > > _______________________________________________ > Web-SIG mailing list > [email protected] > Web SIG: http://www.python.org/sigs/web-sig > Unsubscribe: > https://mail.python.org/mailman/options/web-sig/cmawebsite%40gmail.com > > --089e011604261e4e6f052dc9c1f3 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr">http2 makes all header names lowercase</div><div class=3D"= gmail_extra"><br><div class=3D"gmail_quote">On Fri, Mar 11, 2016 at 12:59 P= M, Andrew Godwin <span dir=3D"ltr"><<a href=3D"mailto:andrew-g6StKjQqr+wpug/[email protected]= g" target=3D"_blank">[email protected]</a>></span> wrote:<br><blockquo= te class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc so= lid;padding-left:1ex"><div dir=3D"ltr">One thing I did want to ask - is it = worth still squashing everything down to the same case? Daphne already clea= rs out headers with _ in them to avoid that CVE about it, and header case i= s never semantic, or so I thought?<span class=3D"HOEnZb"><font color=3D"#88= 8888"><div><br></div><div>Andrew</div></font></span></div><div class=3D"HOE= nZb"><div class=3D"h5"><div class=3D"gmail_extra"><br><div class=3D"gmail_q= uote">On Fri, Mar 11, 2016 at 9:56 AM, Andrew Godwin <span dir=3D"ltr"><= <a href=3D"mailto:[email protected]" target=3D"_blank">andrew-g6StKjQqr+wpug/[email protected]= g</a>></span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margi= n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">= <br><div class=3D"gmail_extra"><br><div class=3D"gmail_quote"><span>On Fri,= Mar 11, 2016 at 2:28 AM, Cory Benfield <span dir=3D"ltr"><<a href=3D"ma= ilto:[email protected]" target=3D"_blank">[email protected]</a>></span> = wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bord= er-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word= "><br><div><span><blockquote type=3D"cite"><div>On 10 Mar 2016, at 23:56, A= ndrew Godwin <<a href=3D"mailto:[email protected]" target=3D"_blank">a= [email protected]</a>> wrote:</div><div><div dir=3D"ltr" style=3D"font-= family:Helvetica;font-size:12px;font-style:normal;font-weight:normal;letter= -spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-= space:normal;word-spacing:0px"><div class=3D"gmail_extra"><div class=3D"gma= il_quote"><div><br></div><div>I would indeed want to require servers to alw= ays fold headers together into a comma-separated list, as that's what t= he RFC says, and it then means applications only have to deal with one kind= of multi-header!</div></div></div></div></div></blockquote><div><br></div>= </span><div>Wellllll=E2=80=A6.kinda?</div><div><br></div><div>The RFC says = that multiple headers are *semantically equivalent* to the joined form, but= does not in any sense require that it be done. (The normative language in = RFC 7230 is MAY.)</div><div><br></div><div>I had this discussion recently w= ith Brian Smith: while there is only one correct way to fold/unfold headers= , anywhere on the spectrum between completely folded and completely unfolde= d is a perfectly valid representation of the HTTP header block. This means = that there=E2=80=99s no *rules* about how a server is supposed to do it, at= least from the IETF. ASGI is of course totally allowed to add its own rule= s, and requiring that they be folded is not terrible.</div><div><br></div><= div>FWIW, in my experience, I=E2=80=99ve found that =E2=80=9Clist of tuples= =E2=80=9D is really the most likely to be correct way to represent a header= block, because it provides some assurances to the user that the header blo= ck has not been aggressively transformed from how it was sent on the wire. = While the *rules* are that the folded representation is supposed to be sema= ntically equivalent to the unfolded representation, there is nonetheless so= me information implicit in those headers being separate.</div><div><br></di= v><div>My intuition when writing this kind of thing is to pass applications= (like Django) the most meaningful representation I can, and then allow the= application to make its own decisions about what meaning they=E2=80=99re w= illing to lose. That=E2=80=99s why I=E2=80=99d advocate for =E2=80=9Clist o= f two-tuples of bytestrings=E2=80=9D as the representation. However, I don= =E2=80=99t think there=E2=80=99s anything *wrong* with forcing the headers = to be joined by the server where possible: it=E2=80=99s just not how I=E2= =80=99d do it. ;)</div><span><br><blockquote type=3D"cite"><div><div dir=3D= "ltr" style=3D"font-family:Helvetica;font-size:12px;font-style:normal;font-= weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-t= ransform:none;white-space:normal;word-spacing:0px"><div class=3D"gmail_extr= a"><div class=3D"gmail_quote"><div>Set-cookie is the annoying thing here, t= hough. That's why it's dict inbound and list of tuples outbound rig= ht now, and I just don't know if I want to make the inbound one a list = of tuples too, given I do definitely want to force servers to concat header= s together (unless I find any examples of that screwing things up)</div></d= iv></div></div></div></blockquote><br></span></div><div>You could make the = inbound one a list of tuples but still require that the servers concat head= ers. The rule then would be that it needs to be possible for an application= to say `dict(headers)` without any loss of meaning.</div></div></blockquot= e><div><br></div></span><div>Yes, I think this is a good argument - my worr= y has always been that the "no multiples" is more of a soft rule = that some clients might break or some apps might rely on the ordering/multi= plicity of things, so preserving it is _probably_ helpful (and as you say, = it lets the header names go back to bytestrings).</div><div><br></div><div>= I'll modify the spec and then update Daphne and Channels to match; I ca= n leave Channels parsing both types for a bit, at least.</div><div><br></di= v><div>Collin's point about http2's handling of headers is on point= , too - if the new spec is deliberately thinned down to that point but no f= urther, it's probably wise to follow them since they know much more abo= ut it than I do.</div><span><font color=3D"#888888"><div><br></div><div>And= rew=C2=A0</div></font></span></div></div></div> </blockquote></div><br></div> </div></div><br>_______________________________________________<br> Web-SIG mailing list<br> <a href=3D"mailto:[email protected]">[email protected]</a><br> Web SIG: <a href=3D"http://www.python.org/sigs/web-sig" rel=3D"noreferrer" = target=3D"_blank">http://www.python.org/sigs/web-sig</a><br> Unsubscribe: <a href=3D"https://mail.python.org/mailman/options/web-sig/cma= website%40gmail.com" rel=3D"noreferrer" target=3D"_blank">https://mail.pyth= on.org/mailman/options/web-sig/cmawebsite%40gmail.com</a><br> <br></blockquote></div><br></div> --089e011604261e4e6f052dc9c1f3-- --===============7350659520008711350== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Web-SIG mailing list [email protected] Web SIG: http://www.python.org/sigs/web-sig Unsubscribe: https://mail.python.org/mailman/options/web-sig/gcpw-web-sig%40m.gmane.org --===============7350659520008711350==--