Http phase handler

Hi.

I’m interested in how HTTP phases handlers works in nginx.

I would like to add support, in mod_wsgi, to NGX_HTTP_PREACCESS_PHASE,
NGX_HTTP_ACCESS_PHASE and NGX_HTTP_CONTENT_PHASE.

I’m reading the sources but I’m not sure to understand how a phase
handler terminates.

With a request handler, the handler can return NGX_DONE and then call
ngx_http_finalize_request, but what about a phase handler?

Thanks Manlio P.

On Wed, Dec 05, 2007 at 06:32:23PM +0100, Manlio P. wrote:

I’m interested in how HTTP phases handlers works in nginx.

I would like to add support, in mod_wsgi, to NGX_HTTP_PREACCESS_PHASE,
NGX_HTTP_ACCESS_PHASE and NGX_HTTP_CONTENT_PHASE.

I’m reading the sources but I’m not sure to understand how a phase
handler terminates.

With a request handler, the handler can return NGX_DONE and then call
ngx_http_finalize_request, but what about a phase handler?

All phase handlers should simpy return value
NGX_OK/NGX_DECLINED/NGX_HTTP_FORBIDDEN/etc.

In the context phase there may run a single defined content handler
(perl,
proxy_pass, fastcgi_pass, memcached_pass, flv, empty_gif) or stack
of handlers: index, autoindex, dav, static.

If a defined handler calls finally
ngx_http_finalize_request(NGX_DECLINED),
then nginx goes to the stack of handlers. Now only perl can do this.

The preaccess phase is for generic handlers:
on NGX_OK it goes to a next phase,
on NGX_DECLINED it goes to a next handler in the same phase,
on NGX_AGAIN/NGX_DONE it simply return,
on NGX_ERROR or NGX_HTTP_… it calls ngx_http_finalize_request()

The access phase is special to handle NGX_OK/NGX_DECLINED depending on
satisfy_any. However, I’m going to change it, because now:

 location / {
     satisfy_any  on;
     auth_basic ...
     # no allow/deny rules
 }

does not ask username/password.

Igor S. ha scritto:

With a request handler, the handler can return NGX_DONE and then call
ngx_http_finalize_request, but what about a phase handler?

All phase handlers should simpy return value
NGX_OK/NGX_DECLINED/NGX_HTTP_FORBIDDEN/etc.

Ok.

In the context phase there may run a single defined content handler (perl,
proxy_pass, fastcgi_pass, memcached_pass, flv, empty_gif) or stack
of handlers: index, autoindex, dav, static.

If a defined handler calls finally ngx_http_finalize_request(NGX_DECLINED),
then nginx goes to the stack of handlers. Now only perl can do this.

Ok.
This should be possible with Python, too.
But I can’t see an useful application for this.

     satisfy_any  on;
     auth_basic ...
     # no allow/deny rules
 }

does not ask username/password.

Is it possible to return NGX_DONE/NGX_AGAIN from the access phase
handler and then call ngx_http_finalize_request(NGX_HTTP_…) when the
handler is done (as an example it may setup the events when doing an
asynchronous query to a database)?

The only module with a phase handler that does “interesting” things is
the autoindex module, but it uses sub requests (and I have yet to
understand how they works :)).

Thanks Manlio P.

Igor S. ha scritto:

But I can’t see an useful application for this.

For example, perl may handle POSTs and decline other to default stack.

What happens if the perl handler sends the headers and writes some data?

[…]

Is it possible to return NGX_DONE/NGX_AGAIN from the access phase
handler and then call ngx_http_finalize_request(NGX_HTTP_…) when the
handler is done (as an example it may setup the events when doing an
asynchronous query to a database)?

Yes. However, I could not say right how you should finalize processing
after second call: ngx_http_finalize_request() or return.

I will try to do some tests.

The only module with a phase handler that does “interesting” things is
the autoindex module, but it uses sub requests (and I have yet to
understand how they works :)).

The stock autoindex module does not use subrequests.

Oh, right!

Thanks Manlio P.

On Wed, Dec 05, 2007 at 07:54:54PM +0100, Manlio P. wrote:

proxy_pass, fastcgi_pass, memcached_pass, flv, empty_gif) or stack
of handlers: index, autoindex, dav, static.

If a defined handler calls finally ngx_http_finalize_request(NGX_DECLINED),
then nginx goes to the stack of handlers. Now only perl can do this.

Ok.
This should be possible with Python, too.
But I can’t see an useful application for this.

For example, perl may handle POSTs and decline other to default stack.

    satisfy_any  on;

handler is done (as an example it may setup the events when doing an
asynchronous query to a database)?

Yes. However, I could not say right how you should finalize processing
after second call: ngx_http_finalize_request() or return.

The only module with a phase handler that does “interesting” things is
the autoindex module, but it uses sub requests (and I have yet to
understand how they works :)).

The stock autoindex module does not use subrequests.

On Wed, Dec 05, 2007 at 08:27:56PM +0100, Manlio P. wrote:

Ok.
This should be possible with Python, too.
But I can’t see an useful application for this.

For example, perl may handle POSTs and decline other to default stack.

What happens if the perl handler sends the headers and writes some data?

Two responses: perl’s one and default’s one.