On Thu, Jul 14, 2011 at 4:40 AM, David Gwynne <[email protected]> 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)" },