Re: Inviting feedback on my proposed "ASGI" spec

Cory Benfield <[email protected]> Fri, 11 Mar 2016 10:28:35 +0000
Newsgroups gmane.comp.python.web
Message-ID <[email protected]>
--===============2930808262947970338==
Content-Type: multipart/signed; boundary="Apple-Mail=_071B95DE-06D3-4F25-82F9-0FDE80939E86"; protocol="application/pgp-signature"; micalg=pgp-sha256


--Apple-Mail=_071B95DE-06D3-4F25-82F9-0FDE80939E86
Content-Type: multipart/alternative;
	boundary="Apple-Mail=_49507510-F7A1-4F27-A487-BEE4413F7C14"


--Apple-Mail=_49507510-F7A1-4F27-A487-BEE4413F7C14
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain;
	charset=utf-8


> On 10 Mar 2016, at 23:56, Andrew Godwin <[email protected]> wrote:
>=20
> 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 =
means 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 one =
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=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 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 semantically 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=99=
re willing to lose. That=E2=80=99s why I=E2=80=99d advocate for =E2=80=9Cl=
ist of 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=99=
s 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 =
definitely 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.

Cory

--Apple-Mail=_49507510-F7A1-4F27-A487-BEE4413F7C14
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html;
	charset=utf-8

<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html =
charset=3Dutf-8"></head><body style=3D"word-wrap: break-word; =
-webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" =
class=3D""><br class=3D""><div><blockquote type=3D"cite" class=3D""><div =
class=3D"">On 10 Mar 2016, at 23:56, Andrew Godwin &lt;<a =
href=3D"mailto:[email protected]" class=3D"">[email protected]</a>&gt;=
 wrote:</div><div class=3D""><div dir=3D"ltr" style=3D"font-family: =
Helvetica; font-size: 12px; font-style: normal; font-variant-caps: =
normal; font-weight: normal; letter-spacing: normal; orphans: auto; =
text-align: start; text-indent: 0px; text-transform: none; white-space: =
normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: =
0px;" class=3D""><div class=3D"gmail_extra"><div =
class=3D"gmail_quote"><div class=3D""><br class=3D""></div><div =
class=3D"">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 means applications only have to deal with one kind of =
multi-header!</div></div></div></div></div></blockquote><div><br =
class=3D""></div><div>Wellllll=E2=80=A6.kinda?</div><div><br =
class=3D""></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 class=3D""></div><div>I had this discussion recently =
with Brian Smith: while there is only one 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=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 rules, and requiring that they be folded =
is not terrible.</div><div><br class=3D""></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 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 =
semantically equivalent to the unfolded representation, there is =
nonetheless some information implicit in those headers being =
separate.</div><div><br class=3D""></div><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 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 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><br class=3D""><blockquote type=3D"cite" class=3D""><div =
class=3D""><div dir=3D"ltr" style=3D"font-family: Helvetica; font-size: =
12px; font-style: normal; font-variant-caps: normal; font-weight: =
normal; letter-spacing: normal; orphans: auto; text-align: start; =
text-indent: 0px; text-transform: none; white-space: normal; widows: =
auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=3D""><div =
class=3D"gmail_extra"><div class=3D"gmail_quote"><div =
class=3D"">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 definitely want to force servers to concat headers together (unless =
I find any examples of that screwing things =
up)</div></div></div></div></div></blockquote><br =
class=3D""></div><div>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.</div><div><br =
class=3D""></div><div>Cory</div></body></html>=

--Apple-Mail=_49507510-F7A1-4F27-A487-BEE4413F7C14--

--Apple-Mail=_071B95DE-06D3-4F25-82F9-0FDE80939E86
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename=signature.asc
Content-Type: application/pgp-signature;
	name=signature.asc
Content-Description: Message signed with OpenPGP using GPGMail

-----BEGIN PGP SIGNATURE-----

iQIcBAEBCAAGBQJW4p3TAAoJEHD+F/imQ+Fb17wP/1bg2KuFK8j/sxdxbLLpiQ8M
EI78QVdNZ14dCN/6xBVG8HgUNKm4w7V2LWoH3i4vh0hjjmcA6qBJaAw/3RPszdm5
OsbIqda17PXSYb/XKJdGFwZpdYqdQBZFvsMpiGqsgmnVT9lUGoZ/HQ8G0g0GKwoP
fYc7IMWxELd2hmkqTAUfspoT24S1sU3AAgTfzMNV+ECawF3OoAQB/skHB22Z62sA
mrES7y/u2pn4pcivCBul64hxiUdQdDA12pAwUyDw13VayfPGQfaN6AmCAMFDKJDo
qAk4ph1MBYhr/CuniZW6S7UXcaxCdLIUgyiTddcXDvw9dVXKV3n5+eamwp0tc+hb
yLq5qqCBUHDAOPKTC4y5UQF1cO7ZuJy449Ava0jjjj+DkW4w/5FagHLuw98zfwhp
k0uYxNgUx7hEbLJ+/wAFfCtEmvoTNsjieW4yT1TGXyJY2q3SojnyuiSSMhQWUxof
h+BUfNztksvyRt7+Nd4QJh1WEySj0Gypb7QIUw4NavdzGaag8XXrRBV3aw5VsaWZ
/s8w2bx/YJ/pl0sBaimn4w3TAy0csG0SoL7feKiQlcFpqrweqMspoFbkDgeDfjcy
KDCBF19NHHw8fZAv3nyMagZpim21AXgqusr7gpPIM9fKCIwT9/jR0cyAI8KdVK+h
JAMIQ+EL1hPJYmCN1rEl
=m5ZD
-----END PGP SIGNATURE-----

--Apple-Mail=_071B95DE-06D3-4F25-82F9-0FDE80939E86--

--===============2930808262947970338==
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

--===============2930808262947970338==--