Re: support specifying scheme/method in apache server configs

2011-07-25 Thread David Gwynne
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-07-20 Thread Sunnz
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

2011-07-19 Thread David Gwynne
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

2011-07-19 Thread Benny Lofgren
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

2011-07-19 Thread Alexey Suslikov
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

2011-07-13 Thread David Gwynne
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);
+