Web3 proposal: Response Metadata

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Web3 proposal: Response Metadata

Gustavo Narea
Hello, everybody.

I just got the time to read PEP-444 and I wanted to propose the addition of a
feature: The ability for servers, gateways or middleware to get metadata about
the response.

>From time to time I find myself in situations where I wish there was a way to
pass arguments to WSGI middleware on egress, and HTTP response headers (e.g.,
"X-My-Argument") are the only option but they can only take strings.

I know some people don't like "mandatory" middleware because they believe that
applications must be able to work without them, but the truth is that they are
pretty common, and without a way to segregate our response's metadata and HTTP
response headers, the former would make it to the client in the absence of the
expected middleware.

The third disadvantage of this approach is that the middleware has to iterate
over all the HTTP headers until it finds the one it's looking for -- if it's
present.

The environ dict can't be used. First, it's semantically incorrect as it's
meant to represent the request. And second, a middleware could have replaced
it.

The following two examples come to mind, and a third one in coming in a
separate email to this mailing list:


Example 1: repoze.who's X-Authorization-Failure-Reason
======================================================

One of the repoze.who built-in plugins ("form") allows applications to pass an
argument on egress. This argument is a user-visible message on why he's been
asked to log in (e.g., the session expired, he's attempting to access
sensitive information anonymously), and it's expected to be in the HTTP
response header "X-Authorization-Failure-Reason".

When the application asks the user to authenticate (e.g., returning a 401),
this plugin intercepts that response and redirects the user to the login form
and, if a reason was set by the application, it's put in the query string so
that the message can be displayed next to the login form (for example).


Example 2: wsgi.file_wrapper
============================

In the current draft for Web3, file wrappers are left out because "the old
system of in-band signalling is broken if it does not provide a way to figure
out as a middleware in the process if the response is a file wrapper".

This problem would be solved with response metadata.


=============================

The application callable's signature would then look like this:

  status, headers, body, meta = application(environ)

And "meta" would be a dict object.

What do you think?

Cheers.
--
Gustavo Narea <xri://=Gustavo>.
| Tech blog: =Gustavo/(+blog)/tech  ~  About me: =Gustavo/about |
_______________________________________________
Web-SIG mailing list
[hidden email]
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: http://mail.python.org/mailman/options/web-sig/lists%40nabble.com
Reply | Threaded
Open this post in threaded view
|

Re: Web3 proposal: Response Metadata

Tres Seaver
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 09/28/2010 05:39 PM, Gustavo Narea wrote:

> I just got the time to read PEP-444 and I wanted to propose the addition of a
> feature: The ability for servers, gateways or middleware to get metadata about
> the response.
>
>>From time to time I find myself in situations where I wish there was a way to
> pass arguments to WSGI middleware on egress, and HTTP response headers (e.g.,
> "X-My-Argument") are the only option but they can only take strings.
>
> I know some people don't like "mandatory" middleware because they believe that
> applications must be able to work without them, but the truth is that they are
> pretty common, and without a way to segregate our response's metadata and HTTP
> response headers, the former would make it to the client in the absence of the
> expected middleware.
>
> The third disadvantage of this approach is that the middleware has to iterate
> over all the HTTP headers until it finds the one it's looking for -- if it's
> present.
>
> The environ dict can't be used. First, it's semantically incorrect as it's
> meant to represent the request.

I pretty much disagree here:  if two consenting plugins, or the
application endpoint and a plugin, want to communicate using private
keys in the environ, even on egress, then more power two them.  To be
really responsible, such usage should be wrapped in an API, and the
"consumer" of the information has to be prepared for the information to
be absent.

> And second, a middleware could have replaced  it.

That's an "iced tea spoon" problem ("Doctor!  Doctor!  I get a cold
stabbing pain in my eye when I drink iced tea!").  The choice to use any
particular middleware has to be governed by whether it is suitable for
the given deployment of the application:  if you need middleware layers
to communicate with the app via the environ, then don't use a middleware
layer which bogarts it.

> The following two examples come to mind, and a third one in coming in a
> separate email to this mailing list:
>
>
> Example 1: repoze.who's X-Authorization-Failure-Reason
> ======================================================
>
> One of the repoze.who built-in plugins ("form") allows applications to pass an
> argument on egress. This argument is a user-visible message on why he's been
> asked to log in (e.g., the session expired, he's attempting to access
> sensitive information anonymously), and it's expected to be in the HTTP
> response header "X-Authorization-Failure-Reason".

> When the application asks the user to authenticate (e.g., returning a 401),
> this plugin intercepts that response and redirects the user to the login form
> and, if a reason was set by the application, it's put in the query string so
> that the message can be displayed next to the login form (for example).

Ouch!  I really wish you wouldn't hold that up as a motivating example:
 the pattern of having the middleware render the login form is the
single most wrong thing about repoze.who 1.x.  That version of the
plugin will be deprecated in repoze.who 2.0, and removed in 2.1:  in the
future, the plugin will *only* handle redirects to a configured URL.

The "correct" place for that kind of between-request information is in a
session or a cookie.  Stashing it in a query string is a common hackaround.


> Example 2: wsgi.file_wrapper
> ============================
>
> In the current draft for Web3, file wrappers are left out because "the old
> system of in-band signalling is broken if it does not provide a way to figure
> out as a middleware in the process if the response is a file wrapper".
>
> This problem would be solved with response metadata.

I don't understand this use case, so the solution doesn't motivate me,
I'm afraid.

> =============================
>
> The application callable's signature would then look like this:
>
>   status, headers, body, meta = application(environ)
>
> And "meta" would be a dict object.
>
> What do you think?




Tres.
- --
===================================================================
Tres Seaver          +1 540-429-0999          [hidden email]
Palladion Software   "Excellence by Design"    http://palladion.com
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkyibGcACgkQ+gerLs4ltQ5MAwCcCWgxOD1s3WrXazMQrHqgjTCE
Jc8An3sCi4AN7KqeKv0B7uxCGh4e7nUn
=k2Hd
-----END PGP SIGNATURE-----

_______________________________________________
Web-SIG mailing list
[hidden email]
Web SIG: http://www.python.org/sigs/web-sig
Unsubscribe: http://mail.python.org/mailman/options/web-sig/lists%40nabble.com