You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Alexei Kosut <ak...@nueva.pvt.k12.ca.us> on 1996/06/03 04:33:50 UTC

more on ServerPath

Hi again...

I think I've finally got it. I've rewritten the ServerPath code about
five times now, it seems to now work as it should. I decided there was
no good way to make the ServerRedirect code work, so took it
out. Patch follows, as well as being in /httpd/incoming/spath.patch

It behaves exactly as described below:

1) In the <VirtualHost> section of a Host-header based virtual host,
you add a ServerPath directive. I'll use an example:

<VirtualHost www.apache.org>
ServerName www.apache.org
DocumentRoot /export/pub/apache
ServerPath /apache
</VirtualHost>

2) Now any request made to http://www.apache.org/apache/... is mapped
to /export/pub/apache/..., regardless of whether or not the Host:
header was sent. If the Host header *is* sent, then
http://www.apache.org/... will also be mapped to
/export/pub/apache.... Nothing but DocumentRoot-relative files are
mapped. Alias, UserDir, etc... still work normally. Obviously, this
would neccessitate, within the <VirtualHost>, for example:

ScriptAlias /cgi-bin/ /export/pub/apache/cgi-bin/
ScriptAlias /apache/cgi-bin/ /export/pub/apache/cgi-bin/

But it's better than nothing, IMO. And still better than just using
Alias, as I reccommend in host.html, because...

3) For a non-Host-sending browser, the server is switched to the
virtual host. This means that all the options therein apply. Redirects
go to the right host, logs go to the right place, etc... (this
includes the correct DOCUMENT_ROOT setting, btw, Brian).

The patch also includes one other thing that I think is important that
we get in Apache 1.1, because who knows when 1.2 will come out (at
this rate): If a HTTP/1.1 or later request comes in, without the
hostname sent as well, it sends back a 400 Bad Request, as per the
HTTP/1.1 spec. The reason for this requirement is to make sure that
browsers put Host: headers in their requests, and since we're the most
popular server, we should help out, yes? Because we're not yet
HTTP/1.1 compliant, and because the HTTP/1.1 spec isn't done yet, I
made it looser about checking than it might otherwise be; it can be
sent as either 1) a Host: header or 2) a full URI (I don't think http-wg has
decided really yet whether 1 is still required in the case of 2), and
it doesn't have to be a valid hostname. The client can send
"Host: brownies are cool", and it'll accept it. After all, in some
weird nameing scheme, that might translate to your server...

At any rate, here's the patch. If people might look at it, it could go
into the next beta (which will be released... when?):

Index: http_core.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_core.c,v
retrieving revision 1.12
diff -c -r1.12 http_core.c
*** http_core.c	1996/05/22 17:35:36	1.12
--- http_core.c	1996/06/03 02:17:03
***************
*** 684,689 ****
--- 684,695 ----
      return NULL;
  }
  
+ char *set_serverpath (cmd_parms *cmd, void *dummy, char *arg) {
+     cmd->server->path = pstrdup (cmd->pool, arg);
+     cmd->server->pathlen = strlen (arg);
+     return NULL;
+ }
+ 
  char *set_content_md5 (cmd_parms *cmd, core_dir_config *d, int arg) {
      d->content_md5 = arg;
      return NULL;
***************
*** 815,820 ****
--- 821,828 ----
  { "ServerAlias", set_server_string_slot,
     (void *)XtOffsetOf (server_rec, names), RSRC_CONF, RAW_ARGS,
     "a name or names alternately used to access the server" },
+ { "ServerPath", set_serverpath, NULL, RSRC_CONF, TAKE1,
+   "The pathname the server can be reached at" },
  { "Timeout", set_timeout, NULL, RSRC_CONF, TAKE1, "timeout duration (sec)"},
  { "KeepAliveTimeout", set_keep_alive_timeout, NULL, RSRC_CONF, TAKE1, "Keep-Alive timeout duration (sec)"},
  { "KeepAlive", set_keep_alive, NULL, RSRC_CONF, TAKE1, "Maximum Keep-Alive requests per connection (0 to disable)" },
***************
*** 850,856 ****
      if (r->proxyreq) return NOT_IMPLEMENTED;
      if (r->uri[0] != '/') return BAD_REQUEST;
      
!     r->filename = pstrcat (r->pool, conf->document_root, r->uri, NULL);
      return OK;
  }
  
--- 858,870 ----
      if (r->proxyreq) return NOT_IMPLEMENTED;
      if (r->uri[0] != '/') return BAD_REQUEST;
      
!     if (r->server->path &&
! 	!strncmp(r->uri, r->server->path, r->server->pathlen))
!       r->filename = pstrcat (r->pool, conf->document_root,
! 			     (r->uri + r->server->pathlen), NULL);
!     else
!       r->filename = pstrcat (r->pool, conf->document_root, r->uri, NULL);
! 
      return OK;
  }
  
Index: http_protocol.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_protocol.c,v
retrieving revision 1.20
diff -c -r1.20 http_protocol.c
*** http_protocol.c	1996/05/27 21:08:28	1.20
--- http_protocol.c	1996/06/03 02:17:08
***************
*** 310,315 ****
--- 310,316 ----
      char l[HUGE_STRING_LEN];
      char *ll = l, *uri;
      conn_rec *conn = r->connection;
+     int major = 1, minor = 0;	/* Assume HTTP/1.0 if non-"HTTP" protocol*/
      
      l[0] = '\0';
      if(!getline(l, HUGE_STRING_LEN, conn->client))
***************
*** 325,330 ****
--- 326,334 ----
      
      r->assbackwards = (ll[0] == '\0');
      r->protocol = ll[0] ? pstrdup (r->pool, ll) : "HTTP/0.9";
+     sscanf(r->protocol, "HTTP/%d.%d", &major, &minor);
+     r->proto_num = 1000*major + minor;
+ 
      return 1;
  }
  
***************
*** 387,392 ****
--- 391,410 ----
    }
  }
  
+ void check_serverpath (request_rec *r) {
+   server_rec *s;
+ 
+   /* This is in conjunction with the ServerPath code in
+    * http_core, so we get the right host attached to a non-
+    * Host-sending request.
+    */
+ 
+   for (s = r->server->next; s; s = s->next) {
+     if (s->path && !strncmp(r->uri, s->path, s->pathlen))
+       r->server = r->connection->server = s;
+   }
+ }
+ 
  request_rec *read_request (conn_rec *conn)
  {
      request_rec *r = (request_rec *)pcalloc (conn->pool, sizeof(request_rec));
***************
*** 427,432 ****
--- 445,452 ----
  
      if (r->hostname || (r->hostname = table_get(r->headers_in, "Host")))
        check_hostalias(r);
+     else
+       check_serverpath(r);
  
      kill_timeout (r);
      conn->keptalive = 0;   /* We now have a request - so no more short timeouts */
Index: http_request.c
===================================================================
RCS file: /export/home/cvs/apache/src/http_request.c,v
retrieving revision 1.7
diff -c -r1.7 http_request.c
*** http_request.c	1996/05/22 17:35:37	1.7
--- http_request.c	1996/06/03 02:17:12
***************
*** 678,683 ****
--- 678,694 ----
  	return;
      }
  
+     if (!r->hostname && (r->proto_num >= 1001)) {
+         /* Client sent us a HTTP/1.1 or later request without telling
+ 	 * us the hostname, either with a full URL or a Host: header.
+ 	 * We therefore need to (as per the spec) send an error
+ 	 */
+         log_reason ("client send HTTP/1.1 request without hostname",
+ 		    r->uri, r);
+ 	die (BAD_REQUEST, r);
+ 	return;
+     }
+ 
      if (!r->proxyreq)
      {
  	access_status = unescape_url(r->uri);
Index: httpd.h
===================================================================
RCS file: /export/home/cvs/apache/src/httpd.h,v
retrieving revision 1.21
diff -c -r1.21 httpd.h
*** httpd.h	1996/05/27 19:48:38	1.21
--- httpd.h	1996/06/03 02:17:15
***************
*** 315,320 ****
--- 315,321 ----
    int proxyreq;                 /* A proxy request */
    int header_only;		/* HEAD request, as opposed to GET */
    char *protocol;		/* Protocol, as given to us, or HTTP/0.9 */
+   int proto_num;		/* Number version of protocol; 1.1 = 1001 */
    char *hostname;		/* Host, as set by full URI or Host: */
    int hostlen;			/* Length of http://host:port in full URI */
  
***************
*** 461,466 ****
--- 462,470 ----
    int timeout;			/* Timeout, in seconds, before we give up */
    int keep_alive_timeout;	/* Seconds we'll wait for another request */
    int keep_alive;		/* Maximum requests per connection */
+ 
+   char *path;			/* Pathname for ServerPath */
+   int pathlen;			/* Length of path */
  
    char *names;			/* Wildcarded names for HostAlias servers */
    char *virthost;		/* The name given in <VirtualHost> */


-- 
________________________________________________________________________
Alexei Kosut <ak...@nueva.pvt.k12.ca.us>      The Apache HTTP Server
URL: http://www.nueva.pvt.k12.ca.us/~akosut/   http://www.apache.org/
 
      "War does not determine who is right, only who is left."



Re: more on ServerPath

Posted by Alexei Kosut <ak...@nueva.pvt.k12.ca.us>.
On Sat, 8 Jun 1996, Brian Behlendorf wrote:

> Okay, I'm now comfortable with this proposed system.  The only case which it
> doesn't address is when references are made to "/something" on the client
> side, like
> 
> <A HREF="/index.html">The home page</A>

Yes, this is true. But, as we've pointed out, split milk is already
spilt, and anyone building a new site would hopefully be smart enough
to either use all relative links, or just use links with the paths
(which works just as well). I mean, if you've already got an IP-based
virtual host, you're not likely to give it up, and if you don't, then you have
links to update *anyway*.

I take it, then, that you wouldn't mind if I committed the patch
(finally)? Anyone wants to raise an objection, please send mail
containing the words "I object to you committing this patch", just so
we're clear. Otherwise, I'll do so sometime Sunday (June 9, 1996)
afternoon (Pacific Daylight Time).

Thanks! Maybe we can get us a 1.1b3 out on Monday after all...

-- 
________________________________________________________________________
Alexei Kosut <ak...@nueva.pvt.k12.ca.us>      The Apache HTTP Server
URL: http://www.nueva.pvt.k12.ca.us/~akosut/   http://www.apache.org/
 
      "War does not determine who is right, only who is left."


Re: more on ServerPath

Posted by Brian Behlendorf <br...@organic.com>.
Okay, I'm now comfortable with this proposed system.  The only case which it
doesn't address is when references are made to "/something" on the client
side, like

<A HREF="/index.html">The home page</A>

The Apache site has had any references like that drilled out because it's 
mirrored in subdirectories all over the place, but I know things like 
this are in just about every site Organic has built, probably on every 
page. :)  The only solution to *that* is to modify mod_include to parse 
HTML references for HREF="/ or SRC="/, and add the serverpath before that 
/.  But I suppose if it's important to us we'll do the work.  Besides, 
sites as image-conscious as us will probably wait until we can tell 
people "upgrade yer browser" rather than have fun in URL-space, so for 
the other 99% this is probably a perfectly decent solution.

	Brian

--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
brian@organic.com  |  We're hiring!  http://www.organic.com/Home/Info/Jobs/