Re: support specifying scheme/method in apache server configs
On Thu, Jul 21, 2011 at 02:21:19PM +0100, Federico Schwindt wrote: On Thu, Jul 14, 2011 at 4:40 AM, David Gwynne l...@animata.net 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. [..] ok? no as it is. please don't use atoi, use ap_strtol. it seems a bit unfair of you to hold me to a higher standard than the rest of the apache codebase, but ill live :) to check for `:' you can use strchr(). i believe you need an ap_pstrdup() for: + cmd-server-server_hostname = arg; other stuff stores arg directly, so i assumed that was ok. again, i'll live :) the strtonum() is wrong. it should be 65535 (the value is inclusive) cool. but you could replace that bit just calling server_port(). but then id be calling atoi... you need to update the documentation as well. true. here's an update diff to the code: 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 - 1.12 +++ src/include/http_core.h 25 Jul 2011 06:45:38 - @@ -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 - 1.30 +++ src/include/httpd.h 25 Jul 2011 06:45:38 - @@ -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.c10 May 2010 02:00:50 - 1.27 +++ src/main/http_core.c25 Jul 2011 06:45:38 - @@ -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 ((unsigned)ap_strtol(v, NULL, 10)); +} + 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
Re: support specifying scheme/method in apache server configs
2011/7/14 David Gwynne l...@animata.net: 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. I used to have something like: VirtualHost _default_80 ServerName internal.my.domain SetEnv HTTPS On /VirtualHost And that was enough to get apache to tact https in front of every link, even though it is serving plan http to the front end (e.g. nginx.) That is now commented out because I tweaked my CMS to manage the links. Just thought that it might work for you too. -- g):g.1e/h2/g )cf71h07e/e.9f04 sunnz.org
Re: support specifying scheme/method in apache server configs
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 - 1.12 +++ src/include/http_core.h 14 Jul 2011 03:33:02 - @@ -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 - 1.30 +++ src/include/httpd.h 14 Jul 2011 03:33:02 - @@ -141,12 +141,8 @@ extern C { #define DEFAULT_HTTP_PORT 80 #define DEFAULT_HTTPS_PORT443 #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 - 1.27 +++ src/main/http_core.c 14 Jul 2011 03:33:02 - @@ -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
Re: support specifying scheme/method in apache server configs
On 2011-07-19 08.29, David Gwynne wrote: noone has an opinion? I like it. I was about to run into exactly the same problem on a similar setup in a few days myself, so it couldn't have come in more handy. :-) would anyone get upset if i committed this? I've tried the patch briefly, and it seems to work. I'll run it for a while on a production system (who dares wins :-) ) and see if I find any regressions, but so far it looks good. Regards, /Benny 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 - 1.12 +++ src/include/http_core.h 14 Jul 2011 03:33:02 - @@ -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 - 1.30 +++ src/include/httpd.h 14 Jul 2011 03:33:02 - @@ -141,12 +141,8 @@ extern C { #define DEFAULT_HTTP_PORT80 #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 - 1.27 +++ src/main/http_core.c 14 Jul 2011 03:33:02 - @@ -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,
Re: support specifying scheme/method in apache server configs
Benny Lofgren wrote: On 2011-07-19 08.29, David Gwynne wrote: noone has an opinion? I like it. I was about to run into exactly the same problem on a similar setup in a few days myself, so it couldn't have come in more handy. :-) would anyone get upset if i committed this? I've tried the patch briefly, and it seems to work. I'll run it for a while on a production system (who dares wins :-) ) and see if I find any regressions, but so far it looks good. Regards, /Benny Someone to hack SNI? :) http://wiki.apache.org/httpd/NameBasedSSLVHostsWithSNI Alexey
support specifying scheme/method in apache server configs
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 - 1.12 +++ src/include/http_core.h 14 Jul 2011 03:33:02 - @@ -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 - 1.30 +++ src/include/httpd.h 14 Jul 2011 03:33:02 - @@ -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.c10 May 2010 02:00:50 - 1.27 +++ src/main/http_core.c14 Jul 2011 03:33:02 - @@ -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); +