Re: Inviting feedback on my proposed "ASGI" spec

Andrew Godwin <[email protected]> Thu, 10 Mar 2016 10:36:54 -0800
Newsgroups gmane.comp.python.web
Message-ID <CAFwN1up_cK_QVtxkw29WOjUOsUx0RZjvo2iTEAo_OD_oYFMjHQ@mail.gmail.com>
--===============3852473878475785157==
Content-Type: multipart/alternative; boundary=001a11c2017a692c15052db61a10

--001a11c2017a692c15052db61a10
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Thu, Mar 10, 2016 at 1:59 AM, Cory Benfield <[email protected]> wrote:

>
> > On 10 Mar 2016, at 00:34, Andrew Godwin <[email protected]> wrote:
> >
> > To that end, I did some work to make the underlying mechanism Django
> Channels uses into more of a standard, which I have codenamed ASGI; while
> initially I intended for it to be a Django documented API, as I've gone
> further with the project I've come to believe it could be useful to the
> Python community at large.
> >
>
> Andrew,
>
> Thanks for this work! I=E2=80=99ve provided some proposed changes as pull=
 requests
> against the channels repository. I=E2=80=99ll ignore those for the rest o=
f the
> email: we can discuss them on GitHub.
>
> I also have a few more general notes. I didn=E2=80=99t make PRs for these=
, mostly
> because they=E2=80=99re too =E2=80=9Cvague=E2=80=9D as feedback goes to b=
e concretely handled by me.
>
> First, your HTTP section has request headers serialized to a dict and
> response headers serialized to a list of tuples. I=E2=80=99m not sure how=
 I feel
> about that asymmetry: it might be cleaner just to use lists-of-tuples in
> both places and allow application frameworks to handle translation to
> dictionary if they require it.
>

I think you're right, and I've just been stubbornly trying to use a dict as
it's slightly "nicer". I honestly considered making both sides dict and
cookies the separate thing as they're the only special case, but I suspect
that multiple headers are one of those things that might turn out to be
useful for some broken client/new feature someday.


>
> Second, if it were me I=E2=80=99d remove the `status_text` field on the `=
Response`
> object. Custom status text is a terrible misfeature (especially as HTTP/2
> doesn=E2=80=99t support it), and in 99% of cases you=E2=80=99re just wast=
ing data by
> repeatedly sending the default phrase that the server already knows.
>

Well, it IS optional; you only need to send it if you're changing it from
the default or providing an unusual new value (e.g. 418). We could change
the spec to say servers don't have to abide by it, too. I have done a
project in the past with custom reason phrases, that's all :)


>
> Third, you=E2=80=99re currently sending header fields with unicode names =
and byte
> string values. That=E2=80=99s understandable, but I wonder if it=E2=80=99=
s worthwhile
> trying to limit the behaviour of compliant servers in encoding/decoding
> those header fields. For example, you could assert that the unicode heade=
r
> names will always use the Latin-1 codec when encoding/decoding. This is
> mostly me being paranoid about poorly written apps/servers issuing bad
> bytes onto the network. I should note that RFC 7230 strictly limits heade=
r
> names to US-ASCII, but Latin-1 would be the defensive choice against
> already-badly-written apps.
>

Yes, it's perhaps an unwritten understanding that they're meant to be
encoded/decoded only to latin1, and I believe this is what Daphne does;
they're unicode mostly as that makes keying into the header dictionary much
nicer in py3/unicode_literals land, and because there's a clear encoding
way to handle them.


>
> Your section on server push is great, whoever wrote that is clearly a
> genius. ;)
>
> You define web socket data frames with an incrementing counter from zero,
> but also note that the maximum integer size is Python=E2=80=99s sys.maxin=
t (you
> actually aren=E2=80=99t that clear about it, which might be a good idea).=
 While
> this is *probably* not a problem, you may want to note that really long
> running or active web socket connections are at risk of exhausting the
> =E2=80=98order=E2=80=99 counter, and define a behaviour if that happens.
>

Ah, good catch. I'll specify a very high maximum order number for any
protocol and say it rolls over to 0 for the next one, and then I can modify
channels' global_ordering to expect that - I think that's the most sensible
approach here.


>
> Otherwise, this is an interesting specification. I=E2=80=99m certainly op=
en to
> helping push it through the PEP process if you=E2=80=99d like assistance =
with that.
>
>
If we see some rough agreement on it, yes, I would love some help with that=
.

Andrew

--001a11c2017a692c15052db61a10
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><div class=3D"gmail_extra"><br><div class=3D"gmail_quo=
te">On Thu, Mar 10, 2016 at 1:59 AM, Cory Benfield <span dir=3D"ltr">&lt;<a=
 href=3D"mailto:[email protected]" target=3D"_blank">[email protected]</a>&=
gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 =
0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span><br>
&gt; On 10 Mar 2016, at 00:34, Andrew Godwin &lt;<a href=3D"mailto:andrew@a=
eracode.org" target=3D"_blank">[email protected]</a>&gt; wrote:<br>
&gt;<br>
&gt; To that end, I did some work to make the underlying mechanism Django C=
hannels uses into more of a standard, which I have codenamed ASGI; while in=
itially I intended for it to be a Django documented API, as I&#39;ve gone f=
urther with the project I&#39;ve come to believe it could be useful to the =
Python community at large.<br>
&gt;<br>
<br>
</span>Andrew,<br>
<br>
Thanks for this work! I=E2=80=99ve provided some proposed changes as pull r=
equests against the channels repository. I=E2=80=99ll ignore those for the =
rest of the email: we can discuss them on GitHub.<br>
<br>
I also have a few more general notes. I didn=E2=80=99t make PRs for these, =
mostly because they=E2=80=99re too =E2=80=9Cvague=E2=80=9D as feedback goes=
 to be concretely handled by me.<br>
<br>
First, your HTTP section has request headers serialized to a dict and respo=
nse headers serialized to a list of tuples. I=E2=80=99m not sure how I feel=
 about that asymmetry: it might be cleaner just to use lists-of-tuples in b=
oth places and allow application frameworks to handle translation to dictio=
nary if they require it.<br></blockquote><div><br></div><div>I think you&#3=
9;re right, and I&#39;ve just been stubbornly trying to use a dict as it&#3=
9;s slightly &quot;nicer&quot;. I honestly considered making both sides dic=
t and cookies the separate thing as they&#39;re the only special case, but =
I suspect that multiple headers are one of those things that might turn out=
 to be useful for some broken client/new feature someday.</div><div>=C2=A0<=
/div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-le=
ft:1px #ccc solid;padding-left:1ex">
<br>
Second, if it were me I=E2=80=99d remove the `status_text` field on the `Re=
sponse` object. Custom status text is a terrible misfeature (especially as =
HTTP/2 doesn=E2=80=99t support it), and in 99% of cases you=E2=80=99re just=
 wasting data by repeatedly sending the default phrase that the server alre=
ady knows.<br></blockquote><div><br></div><div>Well, it IS optional; you on=
ly need to send it if you&#39;re changing it from the default or providing =
an unusual new value (e.g. 418). We could change the spec to say servers do=
n&#39;t have to abide by it, too. I have done a project in the past with cu=
stom reason phrases, that&#39;s all :)</div><div>=C2=A0</div><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex">
<br>
Third, you=E2=80=99re currently sending header fields with unicode names an=
d byte string values. That=E2=80=99s understandable, but I wonder if it=E2=
=80=99s worthwhile trying to limit the behaviour of compliant servers in en=
coding/decoding those header fields. For example, you could assert that the=
 unicode header names will always use the Latin-1 codec when encoding/decod=
ing. This is mostly me being paranoid about poorly written apps/servers iss=
uing bad bytes onto the network. I should note that RFC 7230 strictly limit=
s header names to US-ASCII, but Latin-1 would be the defensive choice again=
st already-badly-written apps.<br></blockquote><div><br></div><div>Yes, it&=
#39;s perhaps an unwritten understanding that they&#39;re meant to be encod=
ed/decoded only to latin1, and I believe this is what Daphne does; they&#39=
;re unicode mostly as that makes keying into the header dictionary much nic=
er in py3/unicode_literals land, and because there&#39;s a clear encoding w=
ay to handle them.</div><div>=C2=A0</div><blockquote class=3D"gmail_quote" =
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Your section on server push is great, whoever wrote that is clearly a geniu=
s. ;)<br>
<br>
You define web socket data frames with an incrementing counter from zero, b=
ut also note that the maximum integer size is Python=E2=80=99s sys.maxint (=
you actually aren=E2=80=99t that clear about it, which might be a good idea=
). While this is *probably* not a problem, you may want to note that really=
 long running or active web socket connections are at risk of exhausting th=
e =E2=80=98order=E2=80=99 counter, and define a behaviour if that happens.<=
br></blockquote><div><br></div><div>Ah, good catch. I&#39;ll specify a very=
 high maximum order number for any protocol and say it rolls over to 0 for =
the next one, and then I can modify channels&#39; global_ordering to expect=
 that - I think that&#39;s the most sensible approach here.</div><div>=C2=
=A0</div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde=
r-left:1px #ccc solid;padding-left:1ex">
<br>
Otherwise, this is an interesting specification. I=E2=80=99m certainly open=
 to helping push it through the PEP process if you=E2=80=99d like assistanc=
e with that.<br><span><font color=3D"#888888"><br></font></span></blockquot=
e><div><br></div><div>If we see some rough agreement on it, yes, I would lo=
ve some help with that.</div><div><br></div><div>Andrew=C2=A0</div></div><b=
r></div></div>

--001a11c2017a692c15052db61a10--

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

--===============3852473878475785157==--