httpd fastcgi diff

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

httpd fastcgi diff

Tim van der Molen-3
I'm using the hgweb.cgi Python script to serve Mercurial repositories
over HTTP. When served by httpd, hgweb.cgi does not work well with the
hg command-line utility. For example, this doesn't work:

$ hg clone http://example.org/hgweb.cgi/repo

The problem is that the hg utility sends an HTTP header with the name
"x-hgarg-1" which httpd translates to "HTTP_X_HGARG__" (i.e. the "1" is
lost).

The diff below fixes this (in the sense that it makes hg work again). I
know very little about CGI, so I hope it doesn't open Pandora's box.

Index: server_fcgi.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/server_fcgi.c,v
retrieving revision 1.52
diff -p -u -r1.52 server_fcgi.c
--- server_fcgi.c 23 Feb 2015 19:22:43 -0000 1.52
+++ server_fcgi.c 25 Mar 2015 20:45:17 -0000
@@ -655,7 +655,7 @@ server_fcgi_writeheader(struct client *c
  for (p = name; *p != '\0'; p++) {
  if (isalpha((unsigned char)*p))
  *p = toupper((unsigned char)*p);
- else
+ else if (!isdigit((unsigned char)*p))
  *p = '_';
  }
 

Reply | Threaded
Open this post in threaded view
|

Re: httpd fastcgi diff

Florian Obser-2
On Wed, Mar 25, 2015 at 10:20:53PM +0100, Tim van der Molen wrote:

> I'm using the hgweb.cgi Python script to serve Mercurial repositories
> over HTTP. When served by httpd, hgweb.cgi does not work well with the
> hg command-line utility. For example, this doesn't work:
>
> $ hg clone http://example.org/hgweb.cgi/repo
>
> The problem is that the hg utility sends an HTTP header with the name
> "x-hgarg-1" which httpd translates to "HTTP_X_HGARG__" (i.e. the "1" is
> lost).
>
> The diff below fixes this (in the sense that it makes hg work again). I
> know very little about CGI, so I hope it doesn't open Pandora's box.

Looks like I picked the wrong week to quit sniffing glue when I wrote
that...

We need to allow some more characters.

RFC 3875:
   Meta-variables with names beginning with "HTTP_" contain values read
   from the client request header fields, if the protocol used is HTTP.
   The HTTP header field name is converted to upper case, has all
   occurrences of "-" replaced with "_" and has "HTTP_" prepended to
   give the meta-variable name.

RFC 7230:
     header-field   = field-name ":" OWS field-value OWS

     field-name     = token

     token          = 1*tchar

     tchar          = "!" / "#" / "$" / "%" / "&" / "'" / "*"
                    / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
                    / DIGIT / ALPHA
                    ; any VCHAR, except delimiters

OK?

diff --git server_fcgi.c server_fcgi.c
index 33603a0..158dc0c 100644
--- server_fcgi.c
+++ server_fcgi.c
@@ -655,7 +655,10 @@ server_fcgi_writeheader(struct client *clt, struct kv *hdr, void *arg)
  for (p = name; *p != '\0'; p++) {
  if (isalpha((unsigned char)*p))
  *p = toupper((unsigned char)*p);
- else
+ else if (!(*p == '!' || *p == '#' || *p == '$' || *p == '%' ||
+    *p == '&' || *p == '\'' || *p == '*' || *p == '+' ||
+    *p == '.' || *p == '^' || *p == '`' || *p == '|' ||
+    *p == '~' || isdigit((unsigned char)*p)))
  *p = '_';
  }
 
--
I'm not entirely sure you are real.

Reply | Threaded
Open this post in threaded view
|

Re: httpd fastcgi diff

Stuart Henderson-6
OK, but would it be worth adding a comment referencing the RFC?

On 2015/03/25 22:58, Florian Obser wrote:

> On Wed, Mar 25, 2015 at 10:20:53PM +0100, Tim van der Molen wrote:
> > I'm using the hgweb.cgi Python script to serve Mercurial repositories
> > over HTTP. When served by httpd, hgweb.cgi does not work well with the
> > hg command-line utility. For example, this doesn't work:
> >
> > $ hg clone http://example.org/hgweb.cgi/repo
> >
> > The problem is that the hg utility sends an HTTP header with the name
> > "x-hgarg-1" which httpd translates to "HTTP_X_HGARG__" (i.e. the "1" is
> > lost).
> >
> > The diff below fixes this (in the sense that it makes hg work again). I
> > know very little about CGI, so I hope it doesn't open Pandora's box.
>
> Looks like I picked the wrong week to quit sniffing glue when I wrote
> that...
>
> We need to allow some more characters.
>
> RFC 3875:
>    Meta-variables with names beginning with "HTTP_" contain values read
>    from the client request header fields, if the protocol used is HTTP.
>    The HTTP header field name is converted to upper case, has all
>    occurrences of "-" replaced with "_" and has "HTTP_" prepended to
>    give the meta-variable name.
>
> RFC 7230:
>      header-field   = field-name ":" OWS field-value OWS
>
>      field-name     = token
>
>      token          = 1*tchar
>
>      tchar          = "!" / "#" / "$" / "%" / "&" / "'" / "*"
>                     / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
>                     / DIGIT / ALPHA
>                     ; any VCHAR, except delimiters
>
> OK?
>
> diff --git server_fcgi.c server_fcgi.c
> index 33603a0..158dc0c 100644
> --- server_fcgi.c
> +++ server_fcgi.c
> @@ -655,7 +655,10 @@ server_fcgi_writeheader(struct client *clt, struct kv *hdr, void *arg)
>   for (p = name; *p != '\0'; p++) {
>   if (isalpha((unsigned char)*p))
>   *p = toupper((unsigned char)*p);
> - else
> + else if (!(*p == '!' || *p == '#' || *p == '$' || *p == '%' ||
> +    *p == '&' || *p == '\'' || *p == '*' || *p == '+' ||
> +    *p == '.' || *p == '^' || *p == '`' || *p == '|' ||
> +    *p == '~' || isdigit((unsigned char)*p)))
>   *p = '_';
>   }
>  
> --
> I'm not entirely sure you are real.
>