[dev] how to send data to client
Manlio Perillo
manlio_perillo at libero.it
Wed Aug 22 16:17:38 MSD 2007
Hi again!
I'm here with another question.
I'm adding the [dev] tag to questions about internals of nginx.
Unfortunately I'm not good at writing documentation, but I hope that
someone will take note about all these discussions.
Igor, thanks for your help!
After the question on how to read data, the problem is now how to write
data.
Reading data is quite easy, since nginx will call my callback function
when all the data is available (and for now I'm not interested in how to
register callbacks that will be called when each chunk of data is read).
Writing data seems to be bit more tricky.
I have a lot of questions:
Body filters
============
Body filters are called by ngx_http_output_filter.
Is the chunked body filter enabled by default?
When the WSGI application does not set the Content-Lenght header, should
I set r->headers_out.content_length_n == -1 by hand, or is it
initialized by nginx?
Headers filters
===============
The WSGI application returns the headers in a list, so I can easily copy
the headers to the r->headers_out->headers list.
Does nginx have an header filter that process the
r->headers_out->headers list and fills the attributes on the
r->headers_out object?
I suspect that I must do the job by myself, parsing each header and
checking if it supported in the ngx_http_headers_out_t structure...
Does nginx at least fills missing headers like Server and Date?
Asyncronous writing
===================
The WSGI specification has some problems here.
Here is the text
http://www.python.org/dev/peps/pep-0333/#buffering-and-streaming:
WSGI servers, gateways, and middleware must not delay the transmission
of any block; they must either fully transmit the block to the client,
or guarantee that they will continue transmission even while the
application is producing its next block. A server/gateway or middleware
may provide this guarantee in one of three ways:
1. Send the entire block to the operating system (and request that
any O/S buffers be flushed) before returning control to the
application, OR
2. Use a different thread to ensure that the block continues to be
transmitted while the application produces the next block.
3. (Middleware only) send the entire block to its parent
gateway/server
By providing this guarantee, WSGI allows applications to ensure that
transmission will not become stalled at an arbitrary point in their
output data. This is critical for proper functioning of e.g. multipart
"server push" streaming, where data between multipart boundaries should
be transmitted in full to the client.
This is simply impossible for nginx, since it is fully asincronous and
does not uses threads to send available buffers.
buffers are sent to the client when the application returns from the
request handler, so that the nginx reactor (main loop) can check the events.
This means that no data is sent to the client until the WSGI application
has produced all of its data.
I'm planning to add an extension to enable true asyncronous support in WSGI.
End of request processing
=========================
I need to be able to register a callback that will be called when all
the response has been sent to the client.
The reason is that, to avoid to copy buffers, I want to send to the
chain buffers the content of:
size = PyString_GET_SIZE(object);
result = (u_char *) PyString_AsString(object);
PyString_AsString returns:
A pointer that refers to the internal buffer of string, not a copy.
This means that I must keep the String object alive, but I must
decrement its reference count when nginx has sent the entire content of
the chain buffer to the client.
Reading the nginx source, it seems that I can use the cleanup attribute
of the request object.
This is nice, since I can store in the "data" a list of all the Python
String objects returned by the WSGI application.
What is the right way to use the cleanup handler?
Should I search the entire linked list until I find a free next slot?
Thanks Manlio Perillo
More information about the nginx
mailing list