httpd-bugs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bugzi...@apache.org
Subject DO NOT REPLY [Bug 8882] - [PATCH] mod_rewrite communicates with external rewrite engine over TCP/IP
Date Wed, 08 May 2002 14:28:50 GMT
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=8882>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=8882

[PATCH] mod_rewrite communicates with external rewrite engine over TCP/IP





------- Additional Comments From JTait@wyrddreams.demon.co.uk  2002-05-08 14:28 -------
OK, I've spent some time coming up with a better solution.  The following patch
is much more elegant, and allows Apache to talk to another server altogether
(what TCP/IP was designed for, right?).  It doesn't ensure that the external
rewrite engine is started, but it's a small price to pay for a potentially large
increase in performance.

The new format is:

RewriteMap tcp:ipaddr.or.dnsname.of.host:port

The port does not have a default value, so it must be specified.

--- src/modules/standard/mod_rewrite.c  Sat Mar 16 23:44:20 2002
+++ /home/jtait/src/apache_1.3.24/src/modules/standard/mod_rewrite.c    Wed May
 8 15:18:36 2002
@@ -507,6 +507,11 @@
                               a2+4, NULL);
         }
     }
+    else if (strncmp(a2, "tcp:", 4) == 0) {
+        new->type      = MAPTYPE_TCP;
+        new->datafile  = a2+4;
+        new->checkfile = NULL;
+    }
     else {
         new->type      = MAPTYPE_TXT;
         new->datafile  = a2;
@@ -2751,6 +2756,17 @@
                 return NULL;
 #endif
             }
+            else if (s->type == MAPTYPE_TCP) {
+                if ((value = lookup_map_tcp(r, s->datafile, key)) != NULL) {
+                    rewritelog(r, 5, "map lookup OK: map=%s(%s) key=%s -> val=%s",
+                               s->name, s->datafile, key, value);
+                    return value;
+                }
+                else {
+                    rewritelog(r, 5, "map lookup FAILED: map=%s(%s), key=%s",
+                               s->name, s->datafile, key);
+                }
+            }
             else if (s->type == MAPTYPE_PRG) {
                 if ((value =
                      lookup_map_program(r, s->fpin, s->fpout, key)) != NULL) {
@@ -2945,6 +2961,126 @@
     }
 }

+static char *lookup_map_tcp(request_rec *r, const char *hoststr, char *key)
+{
+    char buf[LONG_STRING_LEN];
+    char c;
+    int i, sock;
+
+    /* create a socket connection to the external program */
+    sock = make_socket_connection(r, hoststr);
+    if (sock == -1) {
+        return NULL;
+    }
+
+    ap_hard_timeout("Send external rewrite request", r);
+    /* write out the request key */
+    i = send(sock, key, strlen(key), 0);
+    if (i != strlen(key)) {
+        ap_kill_timeout(r);
+        return NULL;
+    }
+    ap_reset_timeout(r);
+
+    i = send(sock, "\n", 1, 0);
+    if (i != 1) {
+        ap_kill_timeout(r);
+        return NULL;
+    }
+    ap_kill_timeout(r);
+
+    /* read in the response value */
+    ap_hard_timeout("Receive external rewrite response", r);
+    i = 0;
+    while (recv(sock, &c, 1, 0) == 1 && (i < LONG_STRING_LEN - 1)) {
+        if (c == '\n') {
+            break;
+        }
+        buf[i++] = c;
+    }
+    buf[i] = '\0';
+    ap_pclosesocket(r->pool, sock);
+    ap_kill_timeout(r);
+
+    if (strcasecmp(buf, "NULL") == 0) {
+        return NULL;
+    }
+    else {
+        return ap_pstrdup(r->pool, buf);
+    }
+}
+
+static int make_socket_connection(request_rec *r, const char *hoststr)
+{
+    struct hostent *server_hp;
+    struct sockaddr_in addr;
+    int i, sock, port;
+    char *host;
+    char *portstr;
+
+    memset(&addr, '\0', sizeof(addr));
+    addr.sin_family = AF_INET;
+
+    host = ap_pstrdup(r->pool, hoststr);
+    rewritelog(r, 5, "Extracting port from string: [%s]", host);
+
+    port = 0;
+    portstr = strchr(host, ':');
+    if (portstr != NULL) {
+        *(portstr++) = '\0';
+        rewritelog(r, 5, "Port found: [%s]", portstr);
+        if (ap_isdigit(*portstr)) {
+            port = atoi(portstr);
+        }
+    }
+
+    addr.sin_port = htons(port);
+
+    for (i = 0; host[i] != '\0'; i++) {
+        if(!ap_isdigit(host[i]) && host[i] != '.') {
+            break;
+        }
+    }
+    if (host[i] == '\0') {
+        rewritelog(r, 3, "External rewrite host IP: %s:%d", host, port);
+        addr.sin_addr.s_addr = inet_addr(host);
+    }
+    else {
+        rewritelog(r, 3, "External rewrite hostname: %s:%d", host, port);
+        server_hp = gethostbyname(host);
+        if (host == NULL) {
+            addr.sin_addr.s_addr = 0;
+        }
+        else {
+            addr.sin_addr.s_addr = ((struct in_addr
*)server_hp->h_addr_list[0])->s_addr;
+        }
+    }
+
+    sock = ap_psocket(r->pool, PF_INET, SOCK_STREAM, IPPROTO_TCP);
+    if (sock == -1) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, r, "Unable to create socket");
+        return -1;
+    }
+
+    ap_hard_timeout("External rewriter connect", r);
+    do {
+        i = connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in));
+#if defined(WIN32) || defined(NETWARE)
+        if (i == SOCKET_ERROR) {
+            errno = WSAGetLastError();
+        }
+#endif /* WIN32 */
+    } while (i == -1 && errno == EINTR);
+    if (i == -1) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, r,
+                      "Unable to connect to external rewriter on %s:%d",
+                      inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
+        sock = -1;
+    }
+    ap_kill_timeout(r);
+    return sock;
+}
+
 static char *lookup_map_internal(request_rec *r,
                                  char *(*func)(request_rec *, char *),
                                  char *key)
--- src/modules/standard/mod_rewrite.h  Wed Mar 13 21:05:34 2002
+++ /home/jtait/src/apache_1.3.24/src/modules/standard/mod_rewrite.h    Wed May
 8 15:00:22 2002
@@ -220,6 +220,7 @@
 #define MAPTYPE_PRG                 1<<2
 #define MAPTYPE_INT                 1<<3
 #define MAPTYPE_RND                 1<<4
+#define MAPTYPE_TCP                 1<<5

 #define ENGINE_DISABLED             1<<0
 #define ENGINE_ENABLED              1<<1
@@ -441,6 +442,8 @@
 #endif
 static char *lookup_map_program(request_rec *r, int fpin,
                                 int fpout, char *key);
+static char *lookup_map_tcp(request_rec *r, const char *hoststr, char *key);
+static int make_socket_connection(request_rec *r, const char *hoststr);
 static char *lookup_map_internal(request_rec *r,
                                  char *(*func)(request_rec *r, char *key),
                                  char *key);

---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org


Mime
View raw message