JSGI Level 0 Proposal

44 views
Skip to first unread message

Dean Landolt

unread,
Sep 9, 2009, 1:54:58 PM9/9/09
to comm...@googlegroups.com
In the interest of Wes' Modesty Proposal and Tom's Level 0 idea, I figured I'd put together a first sketch of JSGI Level 0. If we can address the core issues and keep it simple, we can bikeshed the hell out of Level 1 without stalling development of current JSGI middleware.


Request Environment

It sounds like most people prefer hash namespacing in the env, but Tom, as an implementer, would need to be on board. However he did propose headers in their own hash -- so it may not be too presumptuous to put jsgi keys in their own hash, like so:

{
  headers: {
    ACCEPT: ...
    ...
  },
  jsgi: {
    version: ...
    input: ...
    errors: ...
    ...
  },
  REQUEST_METHOD: ...
  ...
}


Another change to the env that was suggested: moving jsgi.url_scheme to the top level, perhaps as PROTOCOL. It certainly seems to belong there.

It was also suggested to camelCase jsgi keys (if we move url_scheme all that's left is jsgi.runOnce).

As for library authors and where to put their keys, this should probably remain unspecified. Some authors may prefer to throw everything in the top level: if we do use hash namespacing some of us may consider this bad form. If you don't like it you can either patch the library or find another. But this should probably out of the purview of the spec.

Tom -- if this sketch doesn't jibe with your notion of a Level 0 request environment feel free to chime in and smack me down.


Response

Response as an object has widespread agreement and has already been implemented in the two JSGI implementations I'm aware of (jack & persevere -- are there any others)? Status as an int, headers as an object and body as a forEach-capable object containing toByteString-capable objects. The only open issue is the header hash case-sensitivity. I firmly believe we have to standardize on a Level 0 case to aid interop between Level 0 middlewares (Level 1 can fix this issue with a case-insensitive hash but if left unspecified it will cause problems at Level 0).

Thus I would suggest that JSGI Level 0 specify that response hash keys SHOULD be set as uppercase. In addition, should a non-conforming middleware set a mixed-case key and a corresponding uppercase key exists, the uppercase key SHOULD win. (it can be left up to the implementation whether to respect non-colliding mixed-case keys at all).

I suggested uppercase for the env and response headers because it corresponds to what we have now, but frankly I'm mostly indifferent between it and lowercase. But I'm -1 on any mixed-case notions -- it will just get too complicated with edge cases and X headers.

Thoughts?

The sooner we can iron out the Level 0 issues the better.

Daniel Friesen

unread,
Sep 9, 2009, 2:16:50 PM9/9/09
to comm...@googlegroups.com
Dean Landolt wrote:
> ...

> Response
>
> Response as an object has widespread agreement and has already been
> implemented in the two JSGI implementations I'm aware of (jack &
> persevere -- are there any others)? Status as an int, headers as an
> object and body as a forEach-capable object containing
> toByteString-capable objects. The only open issue is the header hash
> case-sensitivity. I firmly believe we have to standardize on a Level 0
> case to aid interop between Level 0 middlewares (Level 1 can fix this
> issue with a case-insensitive hash but if left unspecified it *will*
> cause problems at Level 0).
>
> Thus I would suggest that JSGI Level 0 specify that response hash keys
> SHOULD be set as uppercase. In addition, should a non-conforming
> middleware set a mixed-case key and a corresponding uppercase key
> exists, the uppercase key SHOULD win. (it can be left up to the
> implementation whether to respect non-colliding mixed-case keys at all).
>
> I suggested uppercase for the env and response headers because it
> corresponds to what we have now, but frankly I'm mostly indifferent
> between it and lowercase. But I'm -1 on any mixed-case notions -- it
> will just get too complicated with edge cases and X headers.
>
> Thoughts?
>
> The sooner we can iron out the Level 0 issues the better.
Someone else also pointed out css style conversion:
Content-Type -> contentType
Content-Length -> contentLength
ETag -> etag
X-Powered-By -> xPoweredBy

(^_^ I can achieve this myself using .toLowerCase().toCamelCase(); heh)

~Daniel Friesen (Dantman, Nadir-Seen-Fire) [http://daniel.friesen.name]

Dean Landolt

unread,
Sep 9, 2009, 2:25:32 PM9/9/09
to comm...@googlegroups.com

Are you suggesting this for the request or response headers, or both?

This is just another form of name mangling, which I thought we were moving away from. At least this kind of mangling should be 100% reversible. But it might be confusing to those users intimately familiar with HTTP. Also, it would be a fairly significant change to JSGI-as-is.

It strikes me as the kind of things that would better be debated within the context of a Level 1 spec.

Dean Landolt

unread,
Sep 9, 2009, 2:35:58 PM9/9/09
to comm...@googlegroups.com
On Wed, Sep 9, 2009 at 1:54 PM, Dean Landolt <de...@deanlandolt.com> wrote:
In the interest of Wes' Modesty Proposal and Tom's Level 0 idea, I figured I'd put together a first sketch of JSGI Level 0. If we can address the core issues and keep it simple, we can bikeshed the hell out of Level 1 without stalling development of current JSGI middleware.


Request Environment

It sounds like most people prefer hash namespacing in the env, but Tom, as an implementer, would need to be on board. However he did propose headers in their own hash -- so it may not be too presumptuous to put jsgi keys in their own hash, like so:

{
  headers: {
    ACCEPT: ...
    ...
  },
  jsgi: {
    version: ...
    input: ...
    errors: ...
    ...
  },
  REQUEST_METHOD: ...
  ...
}


Another change to the env that was suggested: moving jsgi.url_scheme to the top level, perhaps as PROTOCOL. It certainly seems to belong there.

As Daniel pointed out in another thread, scheme rather than protocol seems to be the standard. In the interest of staying as true as possible to current JSGI, I would propose using the same key but moving it to the top level and uppercasing it:

env['URL_SCHEME']

Mike Wilson

unread,
Sep 10, 2009, 7:16:44 PM9/10/09
to comm...@googlegroups.com
Dean Landolt wrote:

Request Environment

It sounds like most people prefer hash namespacing in the env, but Tom, as an implementer, would need to be on board. However he did propose headers in their own hash -- so it may not be too presumptuous to put jsgi keys in their own hash, like so:

{
  headers: {
    ACCEPT: ...
    ...
  },
  jsgi: {
    version: ...
    input: ...
    errors: ...
    ...
  },
  REQUEST_METHOD: ...
  ...
}
Comments:
 
1) Main direction / principle
A critical question on the direction of the work is if the designed data structure is supposed to mirror a CGI environment variable structure, or a request object. I prefer the latter. The former implies uppercased stuff in a flat list, and my interpretation is that most people wants to move away from that. The following comments will be in the direction of a minimal request object. It also provides symmetry with the response object (or should that otherwise be renamed output environment?).
 
2) Camel case
Most people voted for camel-case properties wholesale (apart from headers) so REQUEST_METHOD should be requestMethod, or maybe just method.
 
3) Stream symmetry
The response object names its body contents stream "body" and puts it in the root. Request should do the same (or response should rename body to output - I'm suggesting body here but both are ok I think).
[Stream API likeness could be discussed in a different thread]
 
4) Putting the important stuff in first row
The input stream "jsgi.input" shouldn't be tucked away under jsgi (as already suggested) as this whole structure is a JSGI request. All main request data properties should be put in the root, or have its own top-level namespace if it's a collection (like headers).
 
5) Headers
This seems to be mostly agreed, but if doing case shifting I would propose lowercase instead of uppercase as the latter may cause expectations that dashes should also be converted to underscores a la CGI (which they shouldn't).
 
6) Separate place for unspecified stuff
The root of the structure should be kept clean from user-added stuff, so we don't get name collisions with existing code if future revisions of the API adds new properties. User code-added properties should go into a separate collection. I'm writing "env" here, but maybe that is too overloaded. The Java world uses "attributes".
 
With the comments so far we would then have:
{
    requestMethod
    headers
        "content-type": ...
        ...
    body
    jsgi
        ...
}
Still there are a few things missing:
 
7) URL properties
The request should probably contain data about the full URL. This can be done according to three different principles; (a) URL, (b) HTTP spec, or (c) CGI variable names:
 
   http://abc.org:80  /basepath  /funcpath /extrapath ?p=1
a) scheme   host port    path       path       path    query
b) scheme   host port requestUri requestUri requestUri query
c) https=on host port scriptName scriptName pathInfo queryStr
c)                    requestUri requestUri requestUri
 
To keep things minimal, it would probably be good to choose one main principle, and then maybe fill in a few missing pieces. (If going with CGI then scriptName shouldn't be used for the server+mount path.)
What's everybody's opinion here?
 
8) Other namespaces
There could be additional standard namespaces, f ex for physical server information. Opinions?
 
9) Mount path
Related to the URL properties; should there be properties on the request that divide the path into where the application is mounted and extra pathInfo, or should there just be the total path?
 
What do you all think?

Response

[...] The only open issue is the header hash case-sensitivity. I firmly believe we have to standardize on a Level 0 case to aid interop between Level 0 middlewares (Level 1 can fix this issue with a case-insensitive hash but if left unspecified it will cause problems at Level 0).


Thus I would suggest that JSGI Level 0 specify that response hash keys SHOULD be set as uppercase. In addition, should a non-conforming middleware set a mixed-case key and a corresponding uppercase key exists, the uppercase key SHOULD win. (it can be left up to the implementation whether to respect non-colliding mixed-case keys at all).
 
To me, this is the worst option as it will force developers to mangle their headers to have a decent chance getting it output.
My priority would be:
1) Provide something like setHeader()/getHeader() methods that matches headers case-insensitively, but persists user code's first casing.
2) Duck the problem and output everything that is set, duplicates and all.
3) -"-
4) -"-
...
99) Specify "SHOULD convert header casing".
;-)
 
Best regards
Mike Wilson

Kris Zyp

unread,
Sep 10, 2009, 7:23:41 PM9/10/09
to comm...@googlegroups.com

> be in the direction of a minimal /request/ object. It also provides


> symmetry with the response object (or should that otherwise be

> renamed /output environment/?).


>
> 2) Camel case
> Most people voted for camel-case properties wholesale (apart from
> headers) so REQUEST_METHOD should be requestMethod, or maybe just method.
>
> 3) Stream symmetry
> The response object names its body contents stream "body" and puts it
> in the root. Request should do the same (or response should rename
> body to output - I'm suggesting body here but both are ok I think).
> [Stream API likeness could be discussed in a different thread]
>
> 4) Putting the important stuff in first row
> The input stream "jsgi.input" shouldn't be tucked away under jsgi (as
> already suggested) as this whole structure is a JSGI request. All main
> request data properties should be put in the root, or have its own
> top-level namespace if it's a collection (like headers).
>

+1 to all this, it sounds great to me, except:

> 6) Separate place for unspecified stuff
> The root of the structure should be kept clean from user-added stuff,
> so we don't get name collisions with existing code if future revisions
> of the API adds new properties. User code-added properties should go
> into a separate collection. I'm writing "env" here, but maybe that is
> too overloaded. The Java world uses "attributes".

Why shouldn't users add stuff to the top level? Why would there be less
chances of collisions in a sub-object vs the root? If anything we should
be trying to reserve room for user information at the top level.

Kris

Tom Robinson

unread,
Sep 10, 2009, 9:41:38 PM9/10/09
to comm...@googlegroups.com
On Sep 10, 2009, at 4:16 PM, Mike Wilson wrote:

Dean Landolt wrote:

Request Environment

It sounds like most people prefer hash namespacing in the env, but Tom, as an implementer, would need to be on board. However he did propose headers in their own hash -- so it may not be too presumptuous to put jsgi keys in their own hash, like so:

{
  headers: {
    ACCEPT: ...
    ...
  },
  jsgi: {
    version: ...
    input: ...
    errors: ...
    ...
  },
  REQUEST_METHOD: ...
  ...
}
Comments:
 
1) Main direction / principle
A critical question on the direction of the work is if the designed data structure is supposed to mirror a CGI environment variable structure, or a request object. I prefer the latter. The former implies uppercased stuff in a flat list, and my interpretation is that most people wants to move away from that. The following comments will be in the direction of a minimal request object. It also provides symmetry with the response object (or should that otherwise be renamed output environment?).

The intention of the two "levels" was to keep level 0 as a simple gateway interface, and level 1 can have the additional things you would expect from a "request object".

 2) Camel case
Most people voted for camel-case properties wholesale (apart from headers) so REQUEST_METHOD should be requestMethod, or maybe just method.

If we go the camel case route I would prefer a straight mapping from the CGI-ish names to camelCase. I still believe there's value in using a well understood naming convention for this sort of thing. So "requestMethod" not "method".

 3) Stream symmetry
The response object names its body contents stream "body" and puts it in the root. Request should do the same (or response should rename body to output - I'm suggesting body here but both are ok I think).
[Stream API likeness could be discussed in a different thread]

4) Putting the important stuff in first row
The input stream "jsgi.input" shouldn't be tucked away under jsgi (as already suggested) as this whole structure is a JSGI request. All main request data properties should be put in the root, or have its own top-level namespace if it's a collection (like headers).
 
5) Headers
This seems to be mostly agreed, but if doing case shifting I would propose lowercase instead of uppercase as the latter may cause expectations that dashes should also be converted to underscores a la CGI (which they shouldn't).

I don't really have an opinion. Are there any other precedents for this besides CGI?


6) Separate place for unspecified stuff
The root of the structure should be kept clean from user-added stuff, so we don't get name collisions with existing code if future revisions of the API adds new properties. User code-added properties should go into a separate collection. I'm writing "env" here, but maybe that is too overloaded. The Java world uses "attributes".
 
With the comments so far we would then have:
{
    requestMethod
    headers
        "content-type": ...
        ...
    body
    jsgi
        ...
}
Still there are a few things missing:
 
7) URL properties
The request should probably contain data about the full URL. This can be done according to three different principles; (a) URL, (b) HTTP spec, or (c) CGI variable names:
 
   http://abc.org:80  /basepath  /funcpath /extrapath ?p=1
a) scheme   host port    path       path       path    query
b) scheme   host port requestUri requestUri requestUri query
c) https=on host port scriptName scriptName pathInfo queryStr
c)                    requestUri requestUri requestUri
 
To keep things minimal, it would probably be good to choose one main principle, and then maybe fill in a few missing pieces. (If going with CGI then scriptName shouldn't be used for the server+mount path.)
What's everybody's opinion here?

C. See my response to #2.

8) Other namespaces
There could be additional standard namespaces, f ex for physical server information. Opinions?
 
9) Mount path
Related to the URL properties; should there be properties on the request that divide the path into where the application is mounted and extra pathInfo, or should there just be the total path

Absolutely. In many cases SCRIPT_NAME may start out empty and routing middleware will split PATH_INFO apart for downstream apps. It's critical for things like URLMap middleware.

We could invent another way of doing this, but why?

What do you all think?

Response

[...] The only open issue is the header hash case-sensitivity. I firmly believe we have to standardize on a Level 0 case to aid interop between Level 0 middlewares (Level 1 can fix this issue with a case-insensitive hash but if left unspecified it will cause problems at Level 0).

Thus I would suggest that JSGI Level 0 specify that response hash keys SHOULD be set as uppercase. In addition, should a non-conforming middleware set a mixed-case key and a corresponding uppercase key exists, the uppercase key SHOULD win. (it can be left up to the implementation whether to respect non-colliding mixed-case keys at all).
 
To me, this is the worst option as it will force developers to mangle their headers to have a decent chance getting it output.
My priority would be:
1) Provide something like setHeader()/getHeader() methods that matches headers case-insensitively, but persists user code's first casing.
2) Duck the problem and output everything that is set, duplicates and all.
3) -"-
4) -"-
...
99) Specify "SHOULD convert header casing".
;-)

setHeader/getHeader is fine for the level 1 response object (Jack's Response has it) but level 0 middleware should be able to assume headers is a plain JS Object.

-tom

Dean Landolt

unread,
Sep 10, 2009, 10:34:05 PM9/10/09
to comm...@googlegroups.com
On Thu, Sep 10, 2009 at 7:16 PM, Mike Wilson <mik...@hotmail.com> wrote:
Dean Landolt wrote:

Request Environment

It sounds like most people prefer hash namespacing in the env, but Tom, as an implementer, would need to be on board. However he did propose headers in their own hash -- so it may not be too presumptuous to put jsgi keys in their own hash, like so:

{
  headers: {
    ACCEPT: ...
    ...
  },
  jsgi: {
    version: ...
    input: ...
    errors: ...
    ...
  },
  REQUEST_METHOD: ...
  ...
}
Comments:
 
1) Main direction / principle
A critical question on the direction of the work is if the designed data structure is supposed to mirror a CGI environment variable structure, or a request object. I prefer the latter. The former implies uppercased stuff in a flat list, and my interpretation is that most people wants to move away from that. The following comments will be in the direction of a minimal request object. It also provides symmetry with the response object (or should that otherwise be renamed output environment?).

Yes, I agree and understand that most people would prefer more of a request object (including myself). But Level 0 was intended to be a compromise -- a bridge between the current JSGI (that yes, resembles CGI, but hopefully without the warts you've mentioned). Tom's idea was that all of this request object stuff could easily fit into a Level 1 spec, but the work to define that spec is a long time coming, and Level 0 would mean everything that works today stays.

Of course if Kris is on board with many of these recommendations, that's one half of the JSGI implementers, a good way to the kind of buy-in that'd be needed to implement the kind of request obj you're suggesting. But if we can't the rest of the way with buy-in, Level 0 makes a very good staging area.

 
2) Camel case
Most people voted for camel-case properties wholesale (apart from headers) so REQUEST_METHOD should be requestMethod, or maybe just method.

Agreed -- if we agree to go that route with JSGI-proper (meaning, no Level 0/1) I'd say we might as well stick as close as possible to something like java's servlet interface.
 
3) Stream symmetry
The response object names its body contents stream "body" and puts it in the root. Request should do the same (or response should rename body to output - I'm suggesting body here but both are ok I think).
[Stream API likeness could be discussed in a different thread]

+1 to either suggestion (though I prefer body -- it's perfectly descriptive and symetrical^2)
 
4) Putting the important stuff in first row
The input stream "jsgi.input" shouldn't be tucked away under jsgi (as already suggested) as this whole structure is a JSGI request. All main request data properties should be put in the root, or have its own top-level namespace if it's a collection (like headers).

+1 -- that's a nice general principle.
 
5) Headers
This seems to be mostly agreed, but if doing case shifting I would propose lowercase instead of uppercase as the latter may cause expectations that dashes should also be converted to underscores a la CGI (which they shouldn't).

I agree about the mangling (and apparently didn't make it explicit enough that it SHOULD be spec'd that we should never do any changing of hyphens to underscores). I proposed UPPER-CASE because it's what we have now (in the env) and it fixes the warts you've specified. But again, +0 to lower-case.
 
6) Separate place for unspecified stuff
The root of the structure should be kept clean from user-added stuff, so we don't get name collisions with existing code if future revisions of the API adds new properties. User code-added properties should go into a separate collection. I'm writing "env" here, but maybe that is too overloaded. The Java world uses "attributes".

I'm with Kris on this -- it's not JSGI's place to specify where unspecified stuff should go.
 
With the comments so far we would then have:
{
    requestMethod
    headers
        "content-type": ...
        ...
    body
    jsgi
        ...
}
Still there are a few things missing:
 
7) URL properties
The request should probably contain data about the full URL. This can be done according to three different principles; (a) URL, (b) HTTP spec, or (c) CGI variable names:
 
   http://abc.org:80  /basepath  /funcpath /extrapath ?p=1
a) scheme   host port    path       path       path    query
b) scheme   host port requestUri requestUri requestUri query
c) https=on host port scriptName scriptName pathInfo queryStr
c)                    requestUri requestUri requestUri
 
To keep things minimal, it would probably be good to choose one main principle, and then maybe fill in a few missing pieces. (If going with CGI then scriptName shouldn't be used for the server+mount path.)
What's everybody's opinion here?

No opinion per se, but +1 to picking one principle and running with it.
 
8) Other namespaces
There could be additional standard namespaces, f ex for physical server information. Opinions?

None in particular, but if we start going down this route we ought to have a very good reason.
 
9) Mount path
Related to the URL properties; should there be properties on the request that divide the path into where the application is mounted and extra pathInfo, or should there just be the total path?

We certainly need the total, undecoded path. But as Tom noted, it's up to middleware to molest the path and script name stuff.
 
What do you all think?

Response

[...] The only open issue is the header hash case-sensitivity. I firmly believe we have to standardize on a Level 0 case to aid interop between Level 0 middlewares (Level 1 can fix this issue with a case-insensitive hash but if left unspecified it will cause problems at Level 0).


Thus I would suggest that JSGI Level 0 specify that response hash keys SHOULD be set as uppercase. In addition, should a non-conforming middleware set a mixed-case key and a corresponding uppercase key exists, the uppercase key SHOULD win. (it can be left up to the implementation whether to respect non-colliding mixed-case keys at all).
 
To me, this is the worst option as it will force developers to mangle their headers to have a decent chance getting it output.

Please explain what you mean by mangle. I don't think we have the same defintion. Headers are case insensitive -- case is irrelevant. I'm with you on the mangling of hyphens and underscores, but we need case consistency somehow -- and rather than forcefully specifying a case-insensitive hash, something like Level 0 could just specify a case.

I think you may have missed the point of the Level 0 proposal.

My priority would be:
1) Provide something like setHeader()/getHeader() methods that matches headers case-insensitively, but persists user code's first casing.
2) Duck the problem and output everything that is set, duplicates and all.
3) -"-
4) -"-
...
99) Specify "SHOULD convert header casing".
;-)

Again, you may have misunderstood the intent of Level 0. It's not to preclude some future Level 1 that could specify getters and setters on the headers and all the other weirdness that could occur. But please understand that some of us are on the cusp of production software dependent on the JSGI spec -- we can't sit on our hands while we bikeshed the hell out of some request object...

Now, I (and almost everybody) agrees we should. But we can have it both ways by defining a minimal Level 0.

Daniel Friesen

unread,
Sep 10, 2009, 11:10:34 PM9/10/09
to comm...@googlegroups.com
Kris Zyp wrote:
>
> Mike Wilson wrote:
>
> ...

>> 6) Separate place for unspecified stuff
>> The root of the structure should be kept clean from user-added stuff,
>> so we don't get name collisions with existing code if future revisions
>> of the API adds new properties. User code-added properties should go
>> into a separate collection. I'm writing "env" here, but maybe that is
>> too overloaded. The Java world uses "attributes".
>>
> Why shouldn't users add stuff to the top level? Why would there be less
> chances of collisions in a sub-object vs the root? If anything we should
> be trying to reserve room for user information at the top level.
>
> Kris
>
Might this be something to do with Level 1 objects implemented in a way
that level 0 code is able to work with them?
It's easy to have an .x = {} property on one of those, but perhaps not
as easy if the top level contains unexpected things.

Dean Landolt

unread,
Sep 11, 2009, 8:04:43 AM9/11/09
to comm...@googlegroups.com


What's the problem with the top level containing unexpected things? It's how it's designed now, and seems to work fine for all the other *SGIs. That's the point of requiring keys -- everything else is added by the implementation or user. This should be irrelevant between Level 0 and N -- it's not something that has to be specified.

Again, my primary gripe is if we try to move too far away from what we have now, it may never stabilize. Level 0 is a means by which everyone can be on the same page _now_ while we bikeshed higher-level operations of the request object. If you want to skip this proposed notion of Level 0 entirely, at the very least I'd suggest it'd need buy-in from both Tom and George.

Mike Wilson

unread,
Sep 11, 2009, 11:39:33 AM9/11/09
to comm...@googlegroups.com
Kris Zyp wote:
> Mike Wilson wrote:
> > [...]

> +1 to all this, it sounds great to me

Great! :-)

> , except:
> > 6) Separate place for unspecified stuff
> > The root of the structure should be kept clean from
> > user-added stuff, so we don't get name collisions
> > with existing code if future revisions of the API
> > adds new properties. User code-added properties
> > should go into a separate collection. I'm writing
> > "env" here, but maybe that is too overloaded. The
> > Java world uses "attributes".
>
> Why shouldn't users add stuff to the top level? Why
> would there be less chances of collisions in a sub-
> object vs the root? If anything we should be trying
> to reserve room for user information at the top level.

Daniel Friesen wrote:
> Kris Zyp wrote:
> > [...]


> >
> Might this be something to do with Level 1 objects
> implemented in a way that level 0 code is able to work
> with them?
> It's easy to have an .x = {} property on one of those,
> but perhaps not as easy if the top level contains
> unexpected things.

Dean Landolt wrote:
> What's the problem with the top level containing
> unexpected things? It's how it's designed now, and
> seems to work fine for all the other *SGIs. That's the
> point of requiring keys -- everything else is added by
> the implementation or user. This should be irrelevant
> between Level 0 and N -- it's not something that has
> to be specified.

My reasoning here is three-fold, and based on the
following assumptions (but maybe they are broken, please
comment):

1) Level 1 compatible with Level 0

Like Daniel says, I interpreted earlier discussion as
Level 1 should be a strict superset of Level 0, so a
"Level 0 middleware" could use a Level 1 request object
without noticing the difference.

This means we cannot use different naming schemes or
structures in Level 0 and Level 1. Specifically, our
decision about if the <handler function parameter> is
a request object or an environment variable list should
apply to both Level 0 and Level 1.

Also, as Level 1 would have more properties on the root
level, these could collide with Level 0 middleware that
add their own root-level properties with conflicting
names.

2) Separating container-added data from user-added data

With my proposal everything added by user code or user
configuration is put in a separate collection, and the
container "owns" the root of the data structure. I also
include data set by middleware in the "user data" term,
as this is a result of configuring the container with
software not active "off the shelf" in the container.

In itself, this principle is just about staying
organized, but for other features this can make a
difference, as in (3).

3) Being able to wrap requests in a deterministic way

Going forward, adding more semantics to the request and
response objects, I could envision starting to use
data freezing and immutable objects. Something along
the lines of that an incoming request object is frozen
and cannot have f ex its headers changed. If a
middleware wants to change headers it uses a platform
mechanism to wrap/extend/replace the request object
with one that inherits all values but is writable.
Changing this "new" object doesn't affect the caller's
immutable version, and the new object is writable until
it is passed on to the next level, when it becomes
immutable.

Making the new writable request could be as simple as:
var writeableReq = cloneRequest(immutableReq);
but I'm not suggesting any specific pattern here.

Though, to be able to wrap/extend/replace a request in
a deterministic way, the container needs to clone the
data itself "owns" according to its own algorithms, and
then probably just do a plain copy of user data to the
new object. With my proposal this means simply copying
the user data collection, which solely consists of user
data. With a more free principle it would be necessary
to recurse the whole object, having to know what
container-defined props to exclude from the copy.

An alternative way of solving this would be to put all
container-managed properties in its own namespace, such
as in:
{
request: {
requestMethod
headers: {...}
...
}
jsgi: {
...
}
...
}
so that the only container-managed root-level properties
are request and jsgi (and middleware is forbidden to
augment them).

Yet another way (taking the level 0/1 discussion above
into account) is to provide the two projections in
parallel:
{
level0: {
requestMethod
serverProtocol
headers: {"CONTENT-TYPE": ...}
...
}
level1: {
method
scheme
headers: {"Content-Type": ...}
...
}
jsgi: {
...
}
...
}
though personally I'm no fan of this.

Again, if these assumptions are wrong, or not of primary
interest to JSGI, then I have no problem with using the
root as a general container per se.

Best regards
Mike

Mike Wilson

unread,
Sep 11, 2009, 11:40:56 AM9/11/09
to comm...@googlegroups.com
Tom Robinson wrote:

On Sep 10, 2009, at 4:16 PM, Mike Wilson wrote:

Dean Landolt wrote:

Request Environment

It sounds like most people prefer hash namespacing in the env, but Tom, as an implementer, would need to be on board. However he did propose headers in their own hash -- so it may not be too presumptuous to put jsgi keys in their own hash, like so:

{
  headers: {
    ACCEPT: ...
    ...
  },
  jsgi: {
    version: ...
    input: ...
    errors: ...
    ...
  },
  REQUEST_METHOD: ...
  ...
}
Comments:
 
1) Main direction / principle
A critical question on the direction of the work is if the designed data structure is supposed to mirror a CGI environment variable structure, or a request object. I prefer the latter. The former implies uppercased stuff in a flat list, and my interpretation is that most people wants to move away from that. The following comments will be in the direction of a minimal request object. It also provides symmetry with the response object (or should that otherwise be renamed output environment?).
The intention of the two "levels" was to keep level 0 as a simple gateway interface, and level 1 can have the additional things you would expect from a "request object". 
Yes, and I think that is a good idea. But as I wrote in another post, if both projections are going to be compatible with Level 0 middleware, then this decision has to be taken together for both.
 2) Camel case
Most people voted for camel-case properties wholesale (apart from headers) so REQUEST_METHOD should be requestMethod, or maybe just method.
If we go the camel case route I would prefer a straight mapping from the CGI-ish names to camelCase. I still believe there's value in using a well understood naming convention for this sort of thing. So "requestMethod" not "method". 
That's fine.
5) Headers
This seems to be mostly agreed, but if doing case shifting I would propose lowercase instead of uppercase as the latter may cause expectations that dashes should also be converted to underscores a la CGI (which they shouldn't).
I don't really have an opinion. Are there any other precedents for this besides CGI? 
FWIW, Apache Tomcat does lowercase. 
7) URL properties
The request should probably contain data about the full URL. This can be done according to three different principles; (a) URL, (b) HTTP spec, or (c) CGI variable names:
 
   http://abc.org:80  /basepath  /funcpath /extrapath ?p=1
a) scheme   host port    path       path       path    query
b) scheme   host port requestUri requestUri requestUri query
c) https=on host port scriptName scriptName pathInfo queryStr
c)                    requestUri requestUri requestUri
 
To keep things minimal, it would probably be good to choose one main principle, and then maybe fill in a few missing pieces. (If going with CGI then scriptName shouldn't be used for the server+mount path.)
What's everybody's opinion here?
C. See my response to #2. 
Today I realized there are probably two more URL schemes that should be mentioned for completeness; (d) the Location object in browsers, and (e) putting everything in one "full url" string. The latter could be an idea for Level 0, to then provide the chopped-up fields in Level 1.
 
   http://abc.org:80  /basepath  /funcpath /extrapath ?p=1
a) scheme   host port    path       path       path    query
b) scheme   host port requestUri requestUri requestUri query
c) https=on host port scriptName scriptName pathInfo queryStr
c)                    requestUri requestUri requestUri   
d) protocol host host  pathname   pathname  pathname  search
d)       hostname port
e)  url     url  url      url        url       url      url
 
Btw, wrt (d) I don't think it has been mentioned here at this mailing list, but it is actually possible that JSGI could be implemented inside browsers in the future, for offline webapps that practically upload a simple server to the client. So maybe some thinking should be put into if CommonJS should have its own "URL" class, or try to bridge it with the browser Location class.
9) Mount path
Related to the URL properties; should there be properties on the request that divide the path into where the application is mounted and extra pathInfo, or should there just be the total path
Absolutely. In many cases SCRIPT_NAME may start out empty and routing middleware will split PATH_INFO apart for downstream apps. It's critical for things like URLMap middleware.
Interesting, it would be good to hear more about different ways this could be used?
 
In my mind, this subject also connects to application deployment. Let's say we have a web server at:
    myserv.com
where we configure a virtual host with a SpiderMonkey runtime at:
Then, in this SpiderMonkey runtime we deploy two CommonJS package files to distinct paths, each representing a webapp:
and app1 has one handler function mapped to /list and one mapped to /item:
 
Then when browsing:
we probably all agree that:
    pathInfo=/more/stuff
but what other path segments should be possible to identify?
We could invent another way of doing this, but why? 
The only thing bothering me is that:
    scriptName=/js/app1/list
in the example above is not such an intuitive name. My gut feeling says that this should be named <something>Path, and maybe be divided into something like:
    serverPath=/js
    appPath=/app1
    scriptPath=/list
but then again, maybe using scriptName in this way is fine when you have more of a CGI background than I have.
 
Best regards
Mike

Mike Wilson

unread,
Sep 11, 2009, 12:12:03 PM9/11/09
to comm...@googlegroups.com
Dean Landolt wrote:

On Thu, Sep 10, 2009 at 7:16 PM, Mike Wilson <mik...@hotmail.com> wrote:
1) Main direction / principle
A critical question on the direction of the work is if the designed data structure is supposed to mirror a CGI environment variable structure, or a request object. I prefer the latter. The former implies uppercased stuff in a flat list, and my interpretation is that most people wants to move away from that. The following comments will be in the direction of a minimal request object. It also provides symmetry with the response object (or should that otherwise be renamed output environment?).

Yes, I agree and understand that most people would prefer more of a request object (including myself). But Level 0 was intended to be a compromise -- a bridge between the current JSGI (that yes, resembles CGI, but hopefully without the warts you've mentioned). Tom's idea was that all of this request object stuff could easily fit into a Level 1 spec, but the work to define that spec is a long time coming, and Level 0 would mean everything that works today stays.

Of course if Kris is on board with many of these recommendations, that's one half of the JSGI implementers, a good way to the kind of buy-in that'd be needed to implement the kind of request obj you're suggesting. But if we can't the rest of the way with buy-in, Level 0 makes a very good staging area. 
What I am attempting to do (though maybe it isn't showing ;-) is to define a Level 0 request object which is as simple as possible, but builds a good ground for an extended Level 1 request object.
I've discussed the reasons for having a Level 0 request object, and not an "environment" in the spirit of current JSGI, in a mail I just posted. If my assumptions there are not valid, it could probably make sense to stay more on the current API for Level 0, as you suggest.
2) Camel case
Most people voted for camel-case properties wholesale (apart from headers) so REQUEST_METHOD should be requestMethod, or maybe just method.

Agreed -- if we agree to go that route with JSGI-proper (meaning, no Level 0/1) I'd say we might as well stick as close as possible to something like java's servlet interface.  
Personally, I would like to have requestMethod if requestURI is also included, as both point to names in the HTTP spec. If only one of them makes it, I'm less concerned about keeping the "request" prefix on the remaining one ;-).
9) Mount path
Related to the URL properties; should there be properties on the request that divide the path into where the application is mounted and extra pathInfo, or should there just be the total path?

We certainly need the total, undecoded path. But as Tom noted, it's up to middleware to molest the path and script name stuff.  
Yes, and as mentioned earlier it would be possible to have just the full URL on Level 0. But that does change things from current JSGI.
Response

[...] The only open issue is the header hash case-sensitivity. I firmly believe we have to standardize on a Level 0 case to aid interop between Level 0 middlewares (Level 1 can fix this issue with a case-insensitive hash but if left unspecified it will cause problems at Level 0).


Thus I would suggest that JSGI Level 0 specify that response hash keys SHOULD be set as uppercase. In addition, should a non-conforming middleware set a mixed-case key and a corresponding uppercase key exists, the uppercase key SHOULD win. (it can be left up to the implementation whether to respect non-colliding mixed-case keys at all).
 
To me, this is the worst option as it will force developers to mangle their headers to have a decent chance getting it output.

Please explain what you mean by mangle. I don't think we have the same defintion. Headers are case insensitive -- case is irrelevant. I'm with you on the mangling of hyphens and underscores, but we need case consistency somehow -- and rather than forcefully specifying a case-insensitive hash, something like Level 0 could just specify a case. 
You're right, that was a sloppy use of "mangle" :-P. What I meant to say is that if we specify it the way you suggested, we will force all Level 0 and Level 1 software to uppercase all headers, and this will result in headers being sent uppercased to clients (there is no way to correctly case correct headers on the way out, as Wes and Daniel has pointed out). Now this is perfectly acceptable as headers are case insensitive, but I bet parts of the userbase would complain about the "ugliness" of uppercasing all headers on the wire.
 
In theory, Level 1 software could output case-correct headers, but as long as the platform declares a preference for uppercase (giving uppercased headers priority when building the response) I think all software will in practice feel forced to uppercase.
 
Finishing off with some process: after most bullets have been debated a bit, I can volunteer to summarize the competing suggestions for each bullet, and organize a show of hands. Does that sound good?
 
Best regards
Mike

Dean Landolt

unread,
Sep 11, 2009, 12:22:00 PM9/11/09
to comm...@googlegroups.com

That's not how I interpreted it -- I interpreted it as a Level 1 request could use a Level 1 request object, or drop into Level 0 if it wanted. In order to be backward compatible Level 1 just needs to avoid changing anything Level 0 specifies and Level 0 middleware will remain happy all the way through the chain.
 

This means we cannot use different naming schemes or
structures in Level 0 and Level 1. Specifically, our
decision about if the <handler function parameter> is
a request object or an environment variable list should
apply to both Level 0 and Level 1.

Also, as Level 1 would have more properties on the root
level, these could collide with Level 0 middleware that
add their own root-level properties with conflicting
names.

I was convinced by this last argument, but then later you unconvinced me -- it looks as though one of your proposals was 'request' as top level env key with all the requisite usefulness of Level 1. I'm picturing this Level 1 "request" object just acting as a proxy to all the junk Level 0 puts in the env. If that's what you're thinking too, I think that would be ideal. I don't care where this Level 0 stuff goes, but the most compelling argument for why it should be nested falls away when you think of Level 1 as the "request" object key (which could be "reserved" by a Level 0 spec).

What you're proposing is a significant change to the status quo. I think it'd be helpful if Tom and George (and any other heavy jsgi users/devs who haven't spoken up) weighed in.
 

2) Separating container-added data from user-added data

With my proposal everything added by user code or user
configuration is put in a separate collection, and the
container "owns" the root of the data structure. I also
include data set by middleware in the "user data" term,
as this is a result of configuring the container with
software not active "off the shelf" in the container.

In itself, this principle is just about staying
organized, but for other features this can make a
difference, as in (3).

3) Being able to wrap requests in a deterministic way

Going forward, adding more semantics to the request and
response objects, I could envision starting to use
data freezing and immutable objects. Something along
the lines of that an incoming request object is frozen
and cannot have f ex its headers changed. If a
middleware wants to change headers it uses a platform
mechanism to wrap/extend/replace the request object
with one that inherits all values but is writable.
Changing this "new" object doesn't affect the caller's
immutable version, and the new object is writable until
it is passed on to the next level, when it becomes
immutable.

This makes me uneasy, and I imagine I'm not alone. Middleware owns the request just as much as the app server. When a middleware receives a request, it is the server as far as its child app is concerned (and so on, on down the chain). There's no reason I can think of for a distinction.


This is where I'm on board -- stick the level 1 in request, have the implementation act as proxy to the Level 0 keys (whereever they're specified) and everyone's happy, right?

Yet another way (taking the level 0/1 discussion above
into account) is to provide the two projections in
parallel:
 {
   level0: {
     requestMethod
     serverProtocol
     headers: {"CONTENT-TYPE": ...}
     ...
   }
   level1: {
     method
     scheme
     headers: {"Content-Type": ...}
     ...
   }
   jsgi: {
     ...
   }
   ...
 }
though personally I'm no fan of this.

Same here -- the level need not be explicit.

Again, if these assumptions are wrong, or not of primary
interest to JSGI, then I have no problem with using the
root as a general container per se.

I agree with much of your argument (except for freezing and such -- that seems superfluous at best, and against the grain of JSGI and js).

What I don't see is a good reason to break with so far from status quo for seemingly cosmetic reasons -- especially when we can clean up those warts in a Level 1 spec that defines a known, structured request object (and "request" key in the env).

Dean Landolt

unread,
Sep 11, 2009, 12:36:02 PM9/11/09
to comm...@googlegroups.com
On Fri, Sep 11, 2009 at 12:12 PM, Mike Wilson <mik...@hotmail.com> wrote:
Dean Landolt wrote:

On Thu, Sep 10, 2009 at 7:16 PM, Mike Wilson <mik...@hotmail.com> wrote:
1) Main direction / principle
A critical question on the direction of the work is if the designed data structure is supposed to mirror a CGI environment variable structure, or a request object. I prefer the latter. The former implies uppercased stuff in a flat list, and my interpretation is that most people wants to move away from that. The following comments will be in the direction of a minimal request object. It also provides symmetry with the response object (or should that otherwise be renamed output environment?).

Yes, I agree and understand that most people would prefer more of a request object (including myself). But Level 0 was intended to be a compromise -- a bridge between the current JSGI (that yes, resembles CGI, but hopefully without the warts you've mentioned). Tom's idea was that all of this request object stuff could easily fit into a Level 1 spec, but the work to define that spec is a long time coming, and Level 0 would mean everything that works today stays.

Of course if Kris is on board with many of these recommendations, that's one half of the JSGI implementers, a good way to the kind of buy-in that'd be needed to implement the kind of request obj you're suggesting. But if we can't the rest of the way with buy-in, Level 0 makes a very good staging area. 
What I am attempting to do (though maybe it isn't showing ;-) is to define a Level 0 request object which is as simple as possible, but builds a good ground for an extended Level 1 request object.

Fair enough. I'm just acting as a devil's advocate about why we need change. It seems like we can have the best of both worlds -- nobody would need to change much in their current code and JSGI development wouldn't grind to a halt as everyone sits on their hands while we bikeshed a spec, and we can spend the time to craft and specify a much nicer request object that future JSGI middleware could be written to count on.

 
I've discussed the reasons for having a Level 0 request object, and not an "environment" in the spirit of current JSGI, in a mail I just posted. If my assumptions there are not valid, it could probably make sense to stay more on the current API for Level 0, as you suggest.
2) Camel case
Most people voted for camel-case properties wholesale (apart from headers) so REQUEST_METHOD should be requestMethod, or maybe just method.

Agreed -- if we agree to go that route with JSGI-proper (meaning, no Level 0/1) I'd say we might as well stick as close as possible to something like java's servlet interface.  
Personally, I would like to have requestMethod if requestURI is also included, as both point to names in the HTTP spec. If only one of them makes it, I'm less concerned about keeping the "request" prefix on the remaining one ;-).

+1 (again, with the stipulation that we dump the notion of Level-0-as-a-good-enough-crutch) and work toward defining a full-on request spec.

9) Mount path
Related to the URL properties; should there be properties on the request that divide the path into where the application is mounted and extra pathInfo, or should there just be the total path?

We certainly need the total, undecoded path. But as Tom noted, it's up to middleware to molest the path and script name stuff.  
Yes, and as mentioned earlier it would be possible to have just the full URL on Level 0. But that does change things from current JSGI.

How? The only thing that remains to be specified is whether it should or should not be decoded by the server.

Response

[...] The only open issue is the header hash case-sensitivity. I firmly believe we have to standardize on a Level 0 case to aid interop between Level 0 middlewares (Level 1 can fix this issue with a case-insensitive hash but if left unspecified it will cause problems at Level 0).


Thus I would suggest that JSGI Level 0 specify that response hash keys SHOULD be set as uppercase. In addition, should a non-conforming middleware set a mixed-case key and a corresponding uppercase key exists, the uppercase key SHOULD win. (it can be left up to the implementation whether to respect non-colliding mixed-case keys at all).
 
To me, this is the worst option as it will force developers to mangle their headers to have a decent chance getting it output.

Please explain what you mean by mangle. I don't think we have the same defintion. Headers are case insensitive -- case is irrelevant. I'm with you on the mangling of hyphens and underscores, but we need case consistency somehow -- and rather than forcefully specifying a case-insensitive hash, something like Level 0 could just specify a case. 
You're right, that was a sloppy use of "mangle" :-P. What I meant to say is that if we specify it the way you suggested, we will force all Level 0 and Level 1 software to uppercase all headers, and this will result in headers being sent uppercased to clients (there is no way to correctly case correct headers on the way out, as Wes and Daniel has pointed out). Now this is perfectly acceptable as headers are case insensitive, but I bet parts of the userbase would complain about the "ugliness" of uppercasing all headers on the wire.

I was envisioning Level 1 specifying a HashP as part of the response object, but I now realize this would not be backward compatible with Level 0. We could certainly define an algorithm for JSGI server implementations to optionally case-normalize headers. That'd be easy and would solve the user problem. As for middleware devs whom want to specify the exact case of any custom headers they set -- well, too bad :) ...but the headers could come out "pretty" quite easily.

 
In theory, Level 1 software could output case-correct headers, but as long as the platform declares a preference for uppercase (giving uppercased headers priority when building the response) I think all software will in practice feel forced to uppercase.

Yup. My bad.
 
Finishing off with some process: after most bullets have been debated a bit, I can volunteer to summarize the competing suggestions for each bullet, and organize a show of hands. Does that sound good?

Sounds great.

Mike Wilson

unread,
Sep 12, 2009, 4:47:51 PM9/12/09
to comm...@googlegroups.com
Dean Landolt wrote:

On Fri, Sep 11, 2009 at 11:39 AM, Mike Wilson <mik...@hotmail.com> wrote:
 
Dean Landolt wrote:
> What's the problem with the top level containing
> unexpected things? It's how it's designed now, and
> seems to work fine for all the other *SGIs. That's the
> point of requiring keys -- everything else is added by
> the implementation or user. This should be irrelevant
> between Level 0 and N -- it's not something that has
> to be specified.

My reasoning here is three-fold, and based on the
following assumptions (but maybe they are broken, please
comment):

1) Level 1 compatible with Level 0

Like Daniel says, I interpreted earlier discussion as
Level 1 should be a strict superset of Level 0, so a
"Level 0 middleware" could use a Level 1 request object
without noticing the difference.

That's not how I interpreted it -- I interpreted it as a Level 1 request could use a Level 1 request object, or drop into Level 0 if it wanted. In order to be backward compatible Level 1 just needs to avoid changing anything Level 0 specifies and Level 0 middleware will remain happy all the way through the chain. 
Ok, so there would be two distinct sets of properties, and some properties would be projected in two places? Wouldn't that lead to inconsistency if a Level 0 middleware just changes a Level 0 property and later in the chain someone uses the (unchanged) Level 1 prop?
Also, as Level 1 would have more properties on the root
level, these could collide with Level 0 middleware that
add their own root-level properties with conflicting
names.

I was convinced by this last argument, but then later you unconvinced me -- it looks as though one of your proposals was 'request' as top level env key with all the requisite usefulness of Level 1. I'm picturing this Level 1 "request" object just acting as a proxy to all the junk Level 0 puts in the env. If that's what you're thinking too, I think that would be ideal. I don't care where this Level 0 stuff goes, but the most compelling argument for why it should be nested falls away when you think of Level 1 as the "request" object key (which could be "reserved" by a Level 0 spec). 
Or when you say "proxy", do you mean that the Level 1 stuff is really just methods or accessors that target the Level 0 properties, but with a nicer API? That would solve the inconsistency problem, but require either a method API or ES5 property accessors.
 
Btw, the "request" sub-key version is not a personal favourite of mine, but I try to keep suggesting slightly alternative versions to see if we can find some design that is attractive to as many as possible ;-).
What you're proposing is a significant change to the status quo. I think it'd be helpful if Tom and George (and any other heavy jsgi users/devs who haven't spoken up) weighed in.  
Certainly. I was thinking that as part of summarizing the different alternatives I would also take note of what people we really want to hear votes from. Twist arms etc. Personally I will probably be quick to vote but I cannot really ask any of the long-time participants to base priorities on my opinion.
3) Being able to wrap requests in a deterministic way

Going forward, adding more semantics to the request and
response objects, I could envision starting to use
data freezing and immutable objects. Something along
the lines of that an incoming request object is frozen
and cannot have f ex its headers changed. If a
middleware wants to change headers it uses a platform
mechanism to wrap/extend/replace the request object
with one that inherits all values but is writable.
Changing this "new" object doesn't affect the caller's
immutable version, and the new object is writable until
it is passed on to the next level, when it becomes
immutable.

This makes me uneasy, and I imagine I'm not alone. Middleware owns the request just as much as the app server. When a middleware receives a request, it is the server as far as its child app is concerned (and so on, on down the chain). There's no reason I can think of for a distinction. 
Ironically, I'm suggesting this as I also think a middleware is the server with respect to its children :-). 
My rationales are a) fast failure when operations are done out-of-sequence, and b) avoid data leakage backwards in the call chain.
 
Further details on this:
 
a) Why I think a request object should be frozen when handing it over to the next level in the call chain, is because it can't be expected that the callee will repeatedly be examining the request object to see if the caller changes data in it after initial submission. We can only expect that the callee examines the request data at the time of invocation, thus later doing changes to it from the caller side should be considered an error. I used the term freezing, but any other mechanism that causes an exception for a (too) late assignment is fine.
 
b) The reason for making the request object immutable when submitted to the next level is also not to inadvertendly pass information back up the call chain. If it is the same mutable request object being passed all the way down, and a middleware makes changes, these changes will be visible both upwards and downwards the call chain, and may pull the rug from under the feet of code up the call chain that thought it could reuse the information it set previously in its request object.
 
So, to summarize, these two factors would protect the "app vs server" (or middleware) relation by a) not letting the server change anything in the request object after handing it over to the app, and b) not letting the app change any request data that could be relied upon by the server. My suggested solution is to pass along an immutable request object that may be passed unchanged through several call levels, but that need to be wrapped/extended/replaced to make changes, and these changes will only be visible downwards the call chain.
I'm suggesting this for predictability and "good order" in general, but surely I could be missing something that makes this kind of security net uninteresting or downright harmful :-P.
 
Best regards
Mike

Mike Wilson

unread,
Sep 12, 2009, 5:08:33 PM9/12/09
to comm...@googlegroups.com
Dean Landolt wrote:

On Fri, Sep 11, 2009 at 12:12 PM, Mike Wilson <mik...@hotmail.com> wrote:
 
Dean Landolt wrote:

We certainly need the total, undecoded path. But as Tom noted, it's up to middleware to molest the path and script name stuff.  
Yes, and as mentioned earlier it would be possible to have just the full URL on Level 0. But that does change things from current JSGI.

How? The only thing that remains to be specified is whether it should or should not be decoded by the server.  
I meant if we would have a minimal Level 0 API with only the full URL exposed and no other url-related properties, ie taking away SERVER_NAME, QUERY_STRING, etc.
We could certainly define an algorithm for JSGI server implementations to optionally case-normalize headers. That'd be easy and would solve the user problem. As for middleware devs whom want to specify the exact case of any custom headers they set -- well, too bad :) ...but the headers could come out "pretty" quite easily. 
As Wes and Daniel discussed, there is no easy algorithm for case normalization as some headers use two capital letters in a row (ETag and others).
Finishing off with some process: after most bullets have been debated a bit, I can volunteer to summarize the competing suggestions for each bullet, and organize a show of hands. Does that sound good?

Sounds great.
Goodie. I'll probably wait until a few more of the long-timers bless this initiative before proceeding. Hopefully we can get this going through the first half of next week.
 
Btw, I was wondering about what spec we are actually defining here. JSGI belongs to Jack, and could in theory define extensions to the CommonJS API. Should there be a "CommonJS JSGI", or is "Jack JSGI" equivalent to that?
 
Best regards
Mike

Kris Kowal

unread,
Sep 12, 2009, 5:27:44 PM9/12/09
to comm...@googlegroups.com
> Btw, I was wondering about what spec we are actually defining here.
> JSGI belongs to Jack, and could in theory define extensions to the CommonJS
> API. Should there be a "CommonJS JSGI", or is "Jack JSGI" equivalent to
> that?
>
> Best regards
> Mike

JSGI is a CommonJS specification. Jack is a Narwhal implementation of
the JSGI CommonJS specification. It was not always this way, but this
is the target separation.

A word on the development history: Jack came first of all these things
and included a module loader in itself, Narwhal was pared out of Jack
to separate the platform from the server handlers, and then JSGI was
factored out of Jack. Such is programming.

I recommend creating a JSGI/Proposals/B on the wiki. I've not even
been lurking this topic personally, so it would be great to see your
ideas codified so others can evaluate them properly, and so we have
something semi-formal to show hands about. I think boiling the
changes down to the ones you care most about, or making several
proposals with varying levels of change would greatly increase the
likelihood that one of them will be generally appealing.

Kris Kowal

Ash Berlin

unread,
Sep 12, 2009, 5:39:54 PM9/12/09
to comm...@googlegroups.com

Ditto, I've not been following this thread either. And the Jack->JSGI
thing was partly my fault, I got confused by the Jack app vs the Jack
interface, and thus JCGI was born. Oh and also for those of you who
don't know the addage: "A spec isn't a spec until there is more than
one implementation".

Mike Wilson

unread,
Sep 13, 2009, 3:22:24 AM9/13/09
to comm...@googlegroups.com
Kris Kowal wrote:
> JSGI is a CommonJS specification. Jack is a Narwhal implementation of
> the JSGI CommonJS specification. It was not always this way, but this
> is the target separation.

Thanks. I was confused by the JSGI document being hosted and
updated on the Jack site, and CommonJS or ServerJS not being
mentioned on the page.

> I recommend creating a JSGI/Proposals/B on the wiki. I've not even
> been lurking this topic personally, so it would be great to see your
> ideas codified so others can evaluate them properly, and so we have
> something semi-formal to show hands about. I think boiling the
> changes down to the ones you care most about, or making several
> proposals with varying levels of change would greatly increase the
> likelihood that one of them will be generally appealing.

Yes, I was planning to use the wiki. Initially, I've been
trying different ideas to get feedback on the list, and was
planning to document these different alternatives on the
wiki to then base the voting off.
This means that at this stage, the wiki page will specify
alternatives on a number of changes to the JSGI spec, and
not one single complete replacement spec. After the voting
is completed the resulting diffs can be applied to create
a new spec version, preferrably on the CommonJS wiki.

On some subjects there have been a fair amount of discussion
on the list already, and while these subjects will be
visible on the wiki as voting questions, I was not planning
to compile all opinions expressed on the list, but was
assuming that the list discussion would be read for
background.
From yours and Ash's response it seems there might be a
number of people that haven't followed the list but are
still interested in having their say. I hope it will be ok
for these people to read back on the list when necessary.

Best regards
Mike

Reply all
Reply to author
Forward
0 new messages