Skip to content

Add section on HTTP/2 features, including push. #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions proposal.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1242,6 +1242,23 @@ components, thus freeing both server and application authors from
implementing the same features over and over again.


HTTP/2 Features
---------------

From the perspective of WSGI applications and servers, HTTP/2 is not handled
differently from HTTP/1.1. Because the semantics of HTTP/2 requests and
responses are identical to the semantics of HTTP/1.1 requests and responses,
there is no requirement for servers to treat them differently in WSGI.

Servers that support both HTTP/1.1 and HTTP/2 **may** provide support for
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i'm not sure how the "preload" spec is related to the server... The server has not access to the "link" information, it's rather an hint for the client that may be sent via the link header or not to the server. However, we need to introduce a way to tell to the application it can place such events on the server that support it.

Something like

environ['wsgi.preload'].push(id, Stream)

where stream would be a fileobject like.

Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sever does have access to the Link information in the only way that matters.

HTTP/2 push works by constructing a "fake" request that is used to correlate with a single response. The way this would work in this case is that that application would send the Link header, which the server would catch. The server would generate this fake request, send it back to the application, then push the application's response.

Let me sketch this out below:

  1. The server receives the following request and passes it to the application in the standard WSGI manner (needing to construct the WSGI environ dict and so on):

    :path: /index.html
    :authority: example.com
    :scheme: https
    :method: GET
    host: example.com
    accept: */*
    
  2. The application sends a 200 response that contains the header Link: </static/style.css>; rel=preload; as=style.

  3. The server catches that header. It supports HTTP/2 server push by this extension, and so it immediately generates a new "fake" request for that resource, which looks like this:

    :path: /static/style.css
    :authority: example.com
    :scheme: https
    :method: GET
    host: example.com
    accept: */*
    
  4. The server then does two things with this virtual request. Firstly, it pushes it to the client in a PUSH_PROMISE frame. Secondly, it sends it to the application exactly like it received it from the real client: in a brand new WSGI function call.

  5. The application responds as normal to the new request, despite the fact that this request was actually initiated by the server.

In this model, the complexities of pushing resources are handled entirely within the server. This allows for some neat optimisations: for example, servers that can be both WSGI servers and serve static files (such as Apache) can potentially run the pushed request through their complete request routing logic, allowing for the application to push static files directly. It also allows us to maintain the standard WSGI interface while opening the possibility for the application to provide push hints to the server.

Finally, the push hint here is also of use to the client in the case where pushing is not possible. Servers that do not opt in or do not support HTTP/2 still function correctly, and clients behave as expected.

Does that make sense?

applications to request HTTP/2 Server Push [8]_ using the "preload" tag in Link
headers. This is discussed in more depth in the W3C's Preload draft [9]_.

Applications **may** always send a preload Link header, regardless of whether
the server supports HTTP/2 Server Push: there are no adverse affects if that
header reaches the user-agent.


Thread Support
--------------

Expand Down Expand Up @@ -1751,6 +1768,12 @@ References
.. [7] SVN revision history for PEP \3333, showing differences from PEP 333
(http://svn.python.org/view/peps/trunk/pep-3333.txt?r1=84854&r2=HEAD)

.. [8] "Server Push" -- Hypertext Transfer Protocol Version 2 (HTTP/2), Section 8.2
(https://tools.ietf.org/html/rfc7540#section-8.2)

.. [9] "Server Push (HTTP/2)" -- Preload, W3C Editor's Draft, Section 2.3
(https://w3c.github.io/preload/#server-push-http-2)

Copyright
=========

Expand Down