noone has an opinion? would anyone get upset if i committed this?
dlg On 14/07/2011, at 1:40 PM, David Gwynne wrote: > in my environment i have nginx in front of apache to offload ssl > and to let me easily point different parts of the uri namespace at > all crazy backends we have. this works fine except if the apache > wants to canonicalise something on the "ssl" backends. because the > ssl is done in nginx, apache doesnt know that it should use https > as the scheme rather than just http and redirects the user to the > wrong port. > > this diff models the newer apache behaviour of letting you specify > the scheme/method as part of the ServerName directive. > > i can set virtualhosts up like this now: > > # nginx has an ssl listener on 443 that proxies to this backend > # using plain http. > <VirtualHost _default_:280> > ServerName https://internal.eait.uq.edu.au > > # other shizz > > </VirtualHost> > > with this diff apache canonicalises with https at the start of the > url instead of the default of http. > > please note i dont like userland (too many strings), and im generally > unfamiliar with apache internals, so i would appreciate both eyes > and tests. > > ok? > > Index: src/include/http_core.h > =================================================================== > RCS file: /cvs/src/usr.sbin/httpd/src/include/http_core.h,v > retrieving revision 1.12 > diff -u -p -r1.12 http_core.h > --- src/include/http_core.h 24 Aug 2007 11:31:29 -0000 1.12 > +++ src/include/http_core.h 14 Jul 2011 03:33:02 -0000 > @@ -138,6 +138,8 @@ API_EXPORT(const char *) ap_get_remote_l > API_EXPORT(char *) ap_construct_url(pool *p, const char *uri, request_rec *r); > API_EXPORT(const char *) ap_get_server_name(request_rec *r); > API_EXPORT(unsigned) ap_get_server_port(const request_rec *r); > +API_EXPORT(const char *) ap_get_server_method(const request_rec *r); > +API_EXPORT(unsigned) ap_get_default_port(const request_rec *r); > API_EXPORT(unsigned long) ap_get_limit_req_body(const request_rec *r); > API_EXPORT(void) ap_custom_response(request_rec *r, int status, char *string); > API_EXPORT(int) ap_exists_config_define(char *name); > Index: src/include/httpd.h > =================================================================== > RCS file: /cvs/src/usr.sbin/httpd/src/include/httpd.h,v > retrieving revision 1.30 > diff -u -p -r1.30 httpd.h > --- src/include/httpd.h 25 Feb 2010 07:49:53 -0000 1.30 > +++ src/include/httpd.h 14 Jul 2011 03:33:02 -0000 > @@ -141,12 +141,8 @@ extern "C" { > #define DEFAULT_HTTP_PORT 80 > #define DEFAULT_HTTPS_PORT 443 > #define ap_is_default_port(port,r) ((port) == ap_default_port(r)) > -#define ap_http_method(r) (((r)->ctx != NULL && ap_ctx_get((r)->ctx, \ > - "ap::http::method") != NULL) ? ((char *)ap_ctx_get((r)->ctx, \ > - "ap::http::method")) : "http") > -#define ap_default_port(r) (((r)->ctx != NULL && ap_ctx_get((r)->ctx, \ > - "ap::default::port") != NULL) ? atoi((char *)ap_ctx_get((r)->ctx, \ > - "ap::default::port")) : DEFAULT_HTTP_PORT) > +#define ap_http_method(r) ap_get_server_method(r) > +#define ap_default_port(r) ap_get_default_port(r) > > /* --------- Default user name and group name running standalone ---------- */ > /* --- These may be specified as numbers by placing a # before a number --- */ > Index: src/main/http_core.c > =================================================================== > RCS file: /cvs/src/usr.sbin/httpd/src/main/http_core.c,v > retrieving revision 1.27 > diff -u -p -r1.27 http_core.c > --- src/main/http_core.c 10 May 2010 02:00:50 -0000 1.27 > +++ src/main/http_core.c 14 Jul 2011 03:33:02 -0000 > @@ -804,6 +804,42 @@ ap_get_server_port(const request_rec *r) > : port; > } > > +API_EXPORT(const char *) > +ap_get_server_method(const request_rec *r) > +{ > + const char *method; > + > + if (r->ctx != NULL) { > + method = ap_ctx_get(r->ctx, "ap::http::method"); > + if (method != NULL) > + return (method); > + } > + > + if (r->server->ctx != NULL) { > + method = ap_ctx_get(r->server->ctx, "ap::http::method"); > + if (method != NULL) > + return (method); > + } > + > + return ("http"); > +} > + > +API_EXPORT(unsigned) > +ap_get_default_port(const request_rec *r) > +{ > + const char *v = NULL; > + > + if (r->ctx != NULL) > + v = ap_ctx_get(r->ctx, "ap::default::port"); > + if (v == NULL && r->server->ctx != NULL) > + v = ap_ctx_get(r->server->ctx, "ap::default::port"); > + > + if (v == NULL) > + return (DEFAULT_HTTP_PORT); > + > + return (atoi(v)); > +} > + > API_EXPORT(char *) > ap_construct_url(pool *p, const char *uri, request_rec *r) > { > @@ -1751,6 +1787,43 @@ static const char *set_server_string_slo > return NULL; > } > > +static const char * > +set_server_name(cmd_parms *cmd, void *dummy, char *arg) > +{ > + const char *err = ap_check_cmd_context(cmd, > + NOT_IN_DIR_LOC_FILE|NOT_IN_LIMIT); > + const char *part; > + int port; > + > + if (err != NULL) > + return (err); > + > + if (strncmp("https://", arg, 8) == 0) { > + ap_ctx_set(cmd->server->ctx, "ap::http::method", "https"); > + ap_ctx_set(cmd->server->ctx, "ap::default::port", "443"); > + arg += 8; > + } else if (strncmp("http://", arg, 7) == 0) { > + /* defaults are fine */ > + arg += 7; > + } else if (strstr(arg, "://") != NULL) > + return ("unsupported scheme"); > + > + part = strstr(arg, ":"); > + if (part != NULL) { > + port = (int)strtonum(part + 1, 1, 65536, &err); > + if (err != NULL) { > + return ap_pstrcat(cmd->temp_pool, > + "The port number \"", part + 1, "\" is ", err, > NULL); > + } > + cmd->server->port = port; > + cmd->server->server_hostname = ap_pstrndup(cmd->pool, arg, > + part - arg); > + } else > + cmd->server->server_hostname = arg; > + > + return (NULL); > +} > + > static const char *server_type(cmd_parms *cmd, void *dummy, char *arg) > { > const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); > @@ -3152,8 +3225,7 @@ static const command_rec core_cmds[] = { > { "ServerAdmin", set_server_string_slot, > (void *)XtOffsetOf (server_rec, server_admin), RSRC_CONF, TAKE1, > "The email address of the server administrator" }, > -{ "ServerName", set_server_string_slot, > - (void *)XtOffsetOf (server_rec, server_hostname), RSRC_CONF, TAKE1, > +{ "ServerName", set_server_name, NULL, RSRC_CONF, TAKE1, > "The hostname of the server" }, > { "ServerSignature", set_signature_flag, NULL, OR_ALL, TAKE1, > "En-/disable server signature (on|off|email)" },