Return-Path: Delivered-To: apmail-httpd-bugs-archive@httpd.apache.org Received: (qmail 61051 invoked by uid 500); 8 May 2002 14:28:50 -0000 Mailing-List: contact bugs-help@httpd.apache.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: Reply-To: "Apache HTTPD Bugs Notification List" Delivered-To: mailing list bugs@httpd.apache.org Received: (qmail 61040 invoked from network); 8 May 2002 14:28:50 -0000 Date: 8 May 2002 14:28:50 -0000 Message-ID: <20020508142850.3561.qmail@nagoya.betaversion.org> From: bugzilla@apache.org To: bugs@httpd.apache.org Cc: Subject: DO NOT REPLY [Bug 8882] - [PATCH] mod_rewrite communicates with external rewrite engine over TCP/IP X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT . 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