You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Michael Douglass <mi...@texas.net> on 1998/01/22 06:06:53 UTC

solution to 'mod_rewrite.c wierdness' => mod_dir.c

Okay, after spending more time than I should have folloing Brian's
suggestions I finally read what Dead said right here:

> > That redirect isn't going away ... that's the one that makes directories
> > work, it's generated by mod_dir.  Why do you think that redirect is in

In fact, I read this as I was getting ready to ask for a kind finger
pointing me to the offending file that was generating this redirect...
Then I found it. :)  Now, here is what I've done to fix problem I
was having with this redirect--note that it required modifying
mod_dir.c, mod_imap.c, util.c, and httpd.h.

The first thing I had to do was locate the offending redirect.
After I found that I discovered that it was not going to be as
simple as changing that one section of code; but I had to change
a function it was calling.

Now, I'll leave it up to the apache people to decide if this is
worthy of adding to the base; but basically I took the construct_url
function and made it slightly more intelligent so that it will use
r->hostname over r->servername if it is available.  In order to do
this, I had to make construct_url take a request_rec instead of a
server_rec; this wasn't too big of a biggie as only mod_dir and
mod_imap was employing this functionality.

Here's my patch; If anyone can spot anything that they think will
break I'd be very appreciative to know.  And if Dean (et al) would
give it a once over, this is a 'feature' that I really would like
to see incorporated into the mainstream apache.

===================================================================
RCS file: RCS/httpd.h,v
retrieving revision 1.1
diff -c -r1.1 httpd.h
*** /tmp/T0Th2TH_       Wed Jan 21 23:06:20 1998
--- httpd.h     Wed Jan 21 22:55:56 1998
***************
*** 681,687 ****
  #define escape_uri(ppool,path) os_escape_path(ppool,path,1)
  extern char *escape_html(pool *p, const char *s);
  char *construct_server(pool *p, const char *hostname, unsigned port);
! char *construct_url (pool *p, const char *path, const server_rec *s);
  char *escape_shell_cmd (pool *p, const char *s);

  int count_dirs(const char *path);
--- 681,687 ----
  #define escape_uri(ppool,path) os_escape_path(ppool,path,1)
  extern char *escape_html(pool *p, const char *s);
  char *construct_server(pool *p, const char *hostname, unsigned port);
! char *construct_url (pool *p, const char *path, const request_rec *r);
  char *escape_shell_cmd (pool *p, const char *s);

  int count_dirs(const char *path);
===================================================================
RCS file: RCS/mod_dir.c,v
retrieving revision 1.1
diff -c -r1.1 mod_dir.c
*** /tmp/T0Th2TH_       Wed Jan 21 23:06:20 1998
--- mod_dir.c   Wed Jan 21 22:51:52 1998
***************
*** 810,816 ****
                         "/", NULL);

        table_set (r->headers_out, "Location",
!                  construct_url(r->pool, ifile, r->server));
        return HTTP_MOVED_PERMANENTLY;
      }

--- 810,816 ----
                         "/", NULL);

        table_set (r->headers_out, "Location",
!                  construct_url(r->pool, ifile, r));
        return HTTP_MOVED_PERMANENTLY;
      }

===================================================================
RCS file: RCS/mod_imap.c,v
retrieving revision 1.1
diff -c -r1.1 mod_imap.c
*** /tmp/T0Th2TH_       Wed Jan 21 23:06:21 1998
--- mod_imap.c  Wed Jan 21 22:52:25 1998
***************
*** 381,387 ****
      char *my_base;

      if (!strcasecmp(value, "map") || !strcasecmp(value, "menu")) {
!       return construct_url(r->pool, r->uri, r->server);
      }

      if (!strcasecmp(value, "nocontent") || !strcasecmp(value, "error")) {
--- 381,387 ----
      char *my_base;

      if (!strcasecmp(value, "map") || !strcasecmp(value, "menu")) {
!       return construct_url(r->pool, r->uri, r);
      }

      if (!strcasecmp(value, "nocontent") || !strcasecmp(value, "error")) {
***************
*** 417,423 ****
            return pstrdup(r->pool, value); /* no base: use what is given */
          }
        /* no base, no value: pick a simple default */
!       return construct_url(r->pool, "/", r->server);
      }

      /* must be a relative URL to be combined with base */
--- 417,423 ----
            return pstrdup(r->pool, value); /* no base: use what is given */
          }
        /* no base, no value: pick a simple default */
!       return construct_url(r->pool, "/", r);
      }

      /* must be a relative URL to be combined with base */
===================================================================
RCS file: RCS/util.c,v
retrieving revision 1.1
diff -c -r1.1 util.c
*** /tmp/T0Th2TH_       Wed Jan 21 23:06:21 1998
--- util.c      Wed Jan 21 22:51:22 1998
***************
*** 808,816 ****
      }
  }

! char *construct_url(pool *p, const char *uri, const server_rec *s) {
      return pstrcat (p, "http://",
!                   construct_server(p, s->server_hostname, s->port),
                    uri, NULL);
  }

--- 808,818 ----
      }
  }

! char *construct_url(pool *p, const char *uri, const request_rec *r) {
      return pstrcat (p, "http://",
!                   construct_server(p, r->hostname ? r->hostname :
!                                      r->server->server_hostname,
!                                      r->server->port),
                    uri, NULL);
  }


-- 
Michael Douglass
Texas Networking, Inc.

<tnet admin> anyway, I'm off, perl code is making me [a] crosseyed toady

Re: solution to 'mod_rewrite.c wierdness' => mod_dir.c

Posted by Michael Douglass <mi...@texas.net>.
On Thu, Jan 22, 1998 at 03:45:34PM -0800, Dean Gaudet said:

> Note the latter is a slight anomaly, but it's actually the way the vhost
> code works -- we believe the port the request came in on rather than
> the port specified in the Host: header, and you can see the logic for
> that in check_hostalias() in main/http_vhost.c.
> 
> We have a few PRs that mention that SERVER_PORT isn't set to the port
> the user came in on.  I'm not sure what to do about that at the moment.

Agreed; though while I can make apache sing and dance, I'm still pretty
virgin on understanding the complete core code.

> And we should emphasize that this does change the default behaviour --
> and there may be compatibility problems... but I'm having a hard time
> imagining them right now.  It would not be much more effort to have
> a per-server core setting which controls whether all responses are
> "canonical" or "adaptive".

It actually changes two things.  First, it changes the parameters to
construct_url; Second, it does change the behaviour of the construct_url.
However, I too am having a hard time imagining them.

Hrmm... Perhaps a per-server core setting would be a good idea,
but that is probably beyond the scope of 'my' assistance.  :)

-- 
Michael Douglass
Texas Networking, Inc.

<tnet admin> anyway, I'm off, perl code is making me [a] crosseyed toady

Re: solution to 'mod_rewrite.c wierdness' => mod_dir.c

Posted by Michael Douglass <mi...@texas.net>.
On Wed, Jan 21, 1998 at 11:06:53PM -0600, Michael Douglass said:

> worthy of adding to the base; but basically I took the construct_url
> function and made it slightly more intelligent so that it will use
> r->hostname over r->servername if it is available.  In order to do

Correction: r->servername above should be r->server->servername.

-- 
Michael Douglass
Texas Networking, Inc.

<tnet admin> anyway, I'm off, perl code is making me [a] crosseyed toady

Re: construct_url hardcoding "http" [was: solution to 'mod_rewrite.c wierdness' => mod_dir.c]

Posted by Ben Laurie <be...@algroup.co.uk>.
Michael Douglass wrote:
> 
> On Fri, Jan 23, 1998 at 11:06:52AM +0000, Ben Laurie said:
> 
> > Well, the way Apache-SSL does this is it assumes that appropriate type
> > can be deduced from the request_rec. This means (if memory serves, but
> > feel free to check the code) that construct_url takes the wrong
> > arguments.
> 
> Well, the current version of construct_url does; my modified version (which
> was submitted to new-httpd) and dean's subsequent 'suggested' version takes
> the request_rec in place of the server_rec (the request_rec holds a pointer
> to the current server_rec).

Which, as it happens, is what Apache-SSL does. What a coincidence :-)

Cheers,

Ben.

-- 
Ben Laurie            |Phone: +44 (181) 735 0686|Apache Group member
Freelance Consultant  |Fax:   +44 (181) 735 0689|http://www.apache.org
and Technical Director|Email: ben@algroup.co.uk |Apache-SSL author
A.L. Digital Ltd,     |http://www.algroup.co.uk/Apache-SSL
London, England.      |"Apache: TDG" http://www.ora.com/catalog/apache

Re: construct_url hardcoding "http" [was: solution to 'mod_rewrite.c wierdness' => mod_dir.c]

Posted by Michael Douglass <mi...@texas.net>.
On Fri, Jan 23, 1998 at 11:06:52AM +0000, Ben Laurie said:

> Well, the way Apache-SSL does this is it assumes that appropriate type
> can be deduced from the request_rec. This means (if memory serves, but
> feel free to check the code) that construct_url takes the wrong
> arguments.

Well, the current version of construct_url does; my modified version (which
was submitted to new-httpd) and dean's subsequent 'suggested' version takes
the request_rec in place of the server_rec (the request_rec holds a pointer
to the current server_rec).

So this is doable. :)

-- 
Michael Douglass
Texas Networking, Inc.

<tnet admin> anyway, I'm off, perl code is making me [a] crosseyed toady

Re: construct_url hardcoding "http" [was: solution to 'mod_rewrite.c wierdness' => mod_dir.c]

Posted by Ben Laurie <be...@algroup.co.uk>.
Michael Douglass wrote:
> 
> On Thu, Jan 22, 1998 at 07:51:44AM -0500, Jim Jagielski said:
> 
> > The "official" Apache source has to be stupidly safe about the US's
> > export control laws wrt SSL and encryption :/
> 
> Okay....  can it be sneaky by storing the connection time in the
> request_rec (or does it already do so?) so you could just do
> something like:
> 
> pstrcat( p, r->connection_protocol, "://", construct_server ... );
> 
> This way you are simply duplicating the incoming protocol. :)

Well, the way Apache-SSL does this is it assumes that appropriate type
can be deduced from the request_rec. This means (if memory serves, but
feel free to check the code) that construct_url takes the wrong
arguments.

Cheers,

Ben.

-- 
Ben Laurie            |Phone: +44 (181) 735 0686|Apache Group member
Freelance Consultant  |Fax:   +44 (181) 735 0689|http://www.apache.org
and Technical Director|Email: ben@algroup.co.uk |Apache-SSL author
A.L. Digital Ltd,     |http://www.algroup.co.uk/Apache-SSL
London, England.      |"Apache: TDG" http://www.ora.com/catalog/apache

Re: construct_url hardcoding "http" [was: solution to 'mod_rewrite.c wierdness' => mod_dir.c]

Posted by Michael Douglass <mi...@texas.net>.
On Thu, Jan 22, 1998 at 07:51:44AM -0500, Jim Jagielski said:


> The "official" Apache source has to be stupidly safe about the US's
> export control laws wrt SSL and encryption :/

Okay....  can it be sneaky by storing the connection time in the
request_rec (or does it already do so?) so you could just do
something like:

pstrcat( p, r->connection_protocol, "://", construct_server ... );

This way you are simply duplicating the incoming protocol. :)

-- 
Michael Douglass
Texas Networking, Inc.

<tnet admin> anyway, I'm off, perl code is making me [a] crosseyed toady

Re: construct_url hardcoding "http" [was: solution to 'mod_rewrite.c wierdness' => mod_dir.c]

Posted by Michael Douglass <mi...@texas.net>.
On Wed, Jan 21, 1998 at 10:30:51PM -0700, Marc Slemko said:

> It isn't ifdefed in other places.  Well, mod_rewrite is the only place and
> it is somewhat modern.  The reason for this is that the US gov't is
> moronic.  Such code could be considered hooks for encryption and be export
> restricted.

*eyes rolling to back of head*...  Tell me about it, I sincerely
wish the US government would get it's head out of it's arse.  :)
It's not like the encryption schemes are not _ALREADY_ outside of
the US...  I'm so confused by our governement sometimes until I
think about how the whole world runs....  It's all run by people
who haven't got a friggen clue one as to how this stuff even works...
*sigh*

For those Monty Python lovers out there:
  "Help, help!  I'm being repressed!!!"

-- 
Michael Douglass
Texas Networking, Inc.

<tnet admin> anyway, I'm off, perl code is making me [a] crosseyed toady

Re: construct_url hardcoding "http" [was: solution to 'mod_rewrite.c wierdness' => mod_dir.c]

Posted by Marc Slemko <ma...@worldgate.com>.
On Wed, 21 Jan 1998, Michael Douglass wrote:

> On Wed, Jan 21, 1998 at 11:06:53PM -0600, Michael Douglass said:
> 
> > ! char *construct_url(pool *p, const char *uri, const request_rec *r) {
> >       return pstrcat (p, "http://",
> > !                   construct_server(p, r->hostname ? r->hostname :
> > !                                      r->server->server_hostname,
> > !                                      r->server->port),
> >                     uri, NULL);
> >   }
> 
> Oh, and I meant to raise a question about the way construct_url hardcoded
> http:// into the string.  I've noted throughtout the source in other
> locations that this piece is #ifdef(ed) for SSL use, etc.  Should it not
> be the case here?

It isn't ifdefed in other places.  Well, mod_rewrite is the only place and
it is somewhat modern.  The reason for this is that the US gov't is
moronic.  Such code could be considered hooks for encryption and be export
restricted.

Now, the current way of the world is somewhat less anal about such things
so they would probably be ok, but...

How about everyone moves up here to Canada then we can do real SSL support
as a part of the base distribution and avoid all the crap.


construct_url hardcoding "http" [was: solution to 'mod_rewrite.c wierdness' => mod_dir.c]

Posted by Michael Douglass <mi...@texas.net>.
On Wed, Jan 21, 1998 at 11:06:53PM -0600, Michael Douglass said:

> ! char *construct_url(pool *p, const char *uri, const request_rec *r) {
>       return pstrcat (p, "http://",
> !                   construct_server(p, r->hostname ? r->hostname :
> !                                      r->server->server_hostname,
> !                                      r->server->port),
>                     uri, NULL);
>   }

Oh, and I meant to raise a question about the way construct_url hardcoded
http:// into the string.  I've noted throughtout the source in other
locations that this piece is #ifdef(ed) for SSL use, etc.  Should it not
be the case here?

-- 
Michael Douglass
Texas Networking, Inc.

<tnet admin> anyway, I'm off, perl code is making me [a] crosseyed toady

Re: solution to 'mod_rewrite.c wierdness' => mod_dir.c

Posted by Marc Slemko <ma...@worldgate.com>.
On Thu, 22 Jan 1998, Dean Gaudet wrote:

> I've changed my mind somewhat on this topic... and I'm for this
> functionality now.  But I think you're going to have to remind everyone
> just why you need it -- it's for the cool "virtual" vhosts right?  vhosts
> which not only are name-based, but don't even have a <VirtualHost>
> definition. 

And this also fixes the double-auth on directory redirect problem.


Re: solution to 'mod_rewrite.c wierdness' => mod_dir.c

Posted by Dean Gaudet <dg...@arctic.org>.
I've changed my mind somewhat on this topic... and I'm for this
functionality now.  But I think you're going to have to remind everyone
just why you need it -- it's for the cool "virtual" vhosts right?  vhosts
which not only are name-based, but don't even have a <VirtualHost>
definition. 

I think you've got one glitch still.  I think construct_url should look
like this: 

char *construct_url(pool *p, const char *uri, const request_rec *r)
{
    return pstrcat (p, "http://",
	construct_server(p, r->hostname ? r->hostname
					: r->server->server_hostname,
			    r->hostname
				? ntohs(r->connection->local_addr.sin_port)
				: r->server->port),
			uri, NULL);
}

My reasoning for the port logic there goes like this: if the client
didn't send a Host: header then we want to use the "canonical" name
for the server (which is r->server->server_hostname:r->server->port).
If the client did specify a Host: header then we should give them back
the Host: header and the port they came in on.

Note the latter is a slight anomaly, but it's actually the way the vhost
code works -- we believe the port the request came in on rather than
the port specified in the Host: header, and you can see the logic for
that in check_hostalias() in main/http_vhost.c.

We have a few PRs that mention that SERVER_PORT isn't set to the port
the user came in on.  I'm not sure what to do about that at the moment.

And we should emphasize that this does change the default behaviour --
and there may be compatibility problems... but I'm having a hard time
imagining them right now.  It would not be much more effort to have
a per-server core setting which controls whether all responses are
"canonical" or "adaptive".

So in short, this is a great start.

Dean