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.
to check for `:' you can use strchr(). i believe you need an ap_pstrdup()
for:

+               cmd->server->server_hostname = arg;

the strtonum() is wrong. it should be 65535 (the value is inclusive)
but you could replace that bit just calling server_port().
you need to update the documentation as well.

f.-

> 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)" },

Reply via email to