On Tue, Nov 17, 2015 at 1:34 PM, Jim Jagielski <[email protected]> wrote:
>
>> On Nov 16, 2015, at 12:38 PM, Yann Ylavic <[email protected]> wrote:
>>
>> +        case 'h':
>> +            if (strncasecmp(scheme + 1, "ttp", 4) == 0) {
>
> Should be 3, shouldn't it?

Yes, I corrected this already in a previous message.

>
>> +                int s4 = ap_tolower(scheme[4]);
>> +                if (!s4) {
>> +                    return APR_URI_HTTP_DEFAULT_PORT;
>>                 }
>> +                else if (s4 == 's' && !scheme[5]) {
>> +                    return APR_URI_HTTPS_DEFAULT_PORT;
>> +                }
>>             }
>
> If we are really trying to optimize the heck out of this, certainly
> we should not ap_tolower s4 until we know it's not '\0'.

Agreed, I have a final patch already which addresses this, just wanted
to see (quickly) if that was the real issue.

The patch I'd propose to commit is something like:

Index: modules/proxy/proxy_util.c
===================================================================
--- modules/proxy/proxy_util.c    (revision 1714617)
+++ modules/proxy/proxy_util.c    (working copy)
@@ -3663,37 +3663,61 @@ PROXY_DECLARE(int) ap_proxy_pass_brigade(apr_bucke
     return OK;
 }

-/* Fill in unknown schemes from apr_uri_port_of_scheme() */

-typedef struct proxy_schemes_t {
-    const char *name;
-    apr_port_t default_port;
-} proxy_schemes_t ;
-
-static proxy_schemes_t pschemes[] =
+PROXY_DECLARE(apr_port_t) ap_proxy_port_of_scheme(const char *scheme)
 {
-    {"fcgi",     8000},
-    {"ajp",      AJP13_DEF_PORT},
-    {"scgi",     SCGI_DEF_PORT},
-    { NULL, 0xFFFF }     /* unknown port */
-};
+    if (!scheme) {
+        return 0;
+    }

-PROXY_DECLARE(apr_port_t) ap_proxy_port_of_scheme(const char *scheme)
-{
-    if (scheme) {
-        apr_port_t port;
-        if ((port = apr_uri_port_of_scheme(scheme)) != 0) {
-            return port;
-        } else {
-            proxy_schemes_t *pscheme;
-            for (pscheme = pschemes; pscheme->name != NULL; ++pscheme) {
-                if (strcasecmp(scheme, pscheme->name) == 0) {
-                    return pscheme->default_port;
-                }
+    /* Fill in unknown schemes from apr_uri_port_of_scheme(),
+     * and try a fast path for common ones.
+     */
+    switch (*scheme) {
+    case 'a':
+    case 'A':
+        if (strcasecmp(scheme + 1, "jp") == 0) {
+            return AJP13_DEF_PORT;
+        }
+        break;
+
+    case 'f':
+    case 'F':
+        if (strcasecmp(scheme + 1, "cgi") == 0) {
+            return AP_FCGI_DEF_PORT;
+        }
+        if (strcasecmp(scheme + 1, "tp") == 0) {
+            return APR_URI_FTP_DEFAULT_PORT;
+        }
+        break;
+
+    case 'h':
+    case 'H':
+        if (strncasecmp(scheme + 1, "ttp", 3) == 0) {
+            if (!scheme[4]) {
+                return APR_URI_HTTP_DEFAULT_PORT;
             }
+            else if (ap_tolower(scheme[4]) == 's' && !scheme[5]) {
+                return APR_URI_HTTPS_DEFAULT_PORT;
+            }
         }
+        break;
+
+    case 'n':
+    case 'N':
+        if (strcasecmp(scheme + 1, "ntp") == 0) {
+            return APR_URI_NNTP_DEFAULT_PORT;
+        }
+        break;
+
+    case 's':
+    case 'S':
+        if (strcasecmp(scheme + 1, "cgi") == 0) {
+            return SCGI_DEF_PORT;
+        }
+        break;
     }
-    return 0;
+    return apr_uri_port_of_scheme(scheme);
 }

 void proxy_util_register_hooks(apr_pool_t *p)
Index: include/util_fcgi.h
===================================================================
--- include/util_fcgi.h    (revision 1714617)
+++ include/util_fcgi.h    (working copy)
@@ -72,6 +72,11 @@ typedef struct {
 #define AP_FCGI_VERSION_1 1

 /**
+ * Default port for FastCGI backends.
+ */
+#define AP_FCGI_DEF_PORT 8000
+
+/**
  * Possible values for the type field of ap_fcgi_header
  */
 #define AP_FCGI_BEGIN_REQUEST       1
Index: modules/proxy/mod_proxy_ajp.c
===================================================================
--- modules/proxy/mod_proxy_ajp.c    (revision 1714617)
+++ modules/proxy/mod_proxy_ajp.c    (working copy)
@@ -48,7 +48,7 @@ static int proxy_ajp_canon(request_rec *r, char *u
      * do syntactic check.
      * We break the URL into host, port, path, search
      */
-    port = def_port = ap_proxy_port_of_scheme("ajp");
+    port = def_port = AJP13_DEF_PORT;

     err = ap_proxy_canon_netloc(r->pool, &url, NULL, NULL, &host, &port);
     if (err) {
Index: modules/proxy/mod_proxy_fcgi.c
===================================================================
--- modules/proxy/mod_proxy_fcgi.c    (revision 1714617)
+++ modules/proxy/mod_proxy_fcgi.c    (working copy)
@@ -46,7 +46,7 @@ static int proxy_fcgi_canon(request_rec *r, char *
         return DECLINED;
     }

-    port = def_port = ap_proxy_port_of_scheme("fcgi");
+    port = def_port = AP_FCGI_DEF_PORT;

     ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                  "canonicalising URL %s", url);
Index: modules/proxy/mod_proxy_http.c
===================================================================
--- modules/proxy/mod_proxy_http.c    (revision 1714617)
+++ modules/proxy/mod_proxy_http.c    (working copy)
@@ -46,15 +46,16 @@ static int proxy_http_canon(request_rec *r, char *
     if (strncasecmp(url, "http:", 5) == 0) {
         url += 5;
         scheme = "http";
+        port = def_port = APR_URI_HTTP_DEFAULT_PORT;
     }
     else if (strncasecmp(url, "https:", 6) == 0) {
         url += 6;
         scheme = "https";
+        port = def_port = APR_URI_HTTPS_DEFAULT_PORT;
     }
     else {
         return DECLINED;
     }
-    port = def_port = ap_proxy_port_of_scheme(scheme);

     ap_log_rerror(APLOG_MARK, APLOG_TRACE1, 0, r,
                   "HTTP: canonicalising URL %s", url);
--

where we both optimize ap_proxy_port_of_scheme() and avoid unnessary calls...

Reply via email to