From: wessels <> Date: Tue, 16 Apr 1996 10:23:12 +0000 (+0000) Subject: develop urlParse() and request_t structure to avoid sscanf'ing the URL X-Git-Tag: SQUID_3_0_PRE1~6159 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7111c86aa02f9cf3c802e6dff6749ad0148aa161;p=thirdparty%2Fsquid.git develop urlParse() and request_t structure to avoid sscanf'ing the URL too frequently. --- diff --git a/src/http.cc b/src/http.cc index 216bf8ae20..ad69daafbf 100644 --- a/src/http.cc +++ b/src/http.cc @@ -1,4 +1,4 @@ -/* $Id: http.cc,v 1.47 1996/04/15 23:02:26 wessels Exp $ */ +/* $Id: http.cc,v 1.48 1996/04/16 04:23:12 wessels Exp $ */ /* * DEBUG: Section 11 http: HTTP @@ -11,11 +11,8 @@ typedef struct _httpdata { StoreEntry *entry; - char host[SQUIDHOSTNAMELEN + 1]; - int port; - int method; + request_t *REQ; char *req_hdr; - char request[MAX_URL + 1]; char *icp_page_ptr; /* Used to send proxy-http request: * put_free_8k_page(me) if the lifetime * expires */ @@ -24,6 +21,7 @@ typedef struct _httpdata { * icpReadWriteData */ char *reply_hdr; int reply_hdr_state; + int free_request; } HttpData; static void httpCloseAndFree(fd, data) @@ -43,44 +41,15 @@ static void httpCloseAndFree(fd, data) } if (data->icp_rwd_ptr) safe_free(data->icp_rwd_ptr); + if (data->free_request) + safe_free(data->REQ); xfree(data); } } -static int http_url_parser(url, host, port, request) - char *url; - char *host; - int *port; - char *request; -{ - static char hostbuf[MAX_URL]; - static char proto[MAX_URL]; - int t; - char *s = NULL; - - /* initialize everything */ - (*port) = urlDefaultPort(PROTO_HTTP); - proto[0] = hostbuf[0] = request[0] = host[0] = '\0'; - - t = sscanf(url, "%[a-zA-Z]://%[^/]%s", proto, hostbuf, request); - if (t < 2) - return -1; - if (strcasecmp(proto, "http") != 0) { - return -1; - } else if (t == 2) - strcpy(request, "/"); - if ((s = strchr(hostbuf, ':')) && *(s + 1)) { - *s = '\0'; - *port = atoi(s + 1); - } - strncpy(host, hostbuf, SQUIDHOSTNAMELEN); - return 0; -} - -int httpCachable(url, method, req_hdr) +int httpCachable(url, method) char *url; int method; - char *req_hdr; { wordlist *p = NULL; @@ -421,15 +390,16 @@ static void httpSendRequest(fd, data) int len = 0; int buflen; int cfd = -1; - char *Method = RequestMethodStr[data->method]; + request_t *req = data->REQ; + char *Method = RequestMethodStr[req->method]; debug(11, 5, "httpSendRequest: FD %d: data %p.\n", fd, data); - buflen = strlen(Method) + strlen(data->request); + buflen = strlen(Method) + strlen(req->urlpath); if (data->req_hdr) buflen += strlen(data->req_hdr); buflen += 512; /* lots of extra */ - if (data->method == METHOD_POST && data->req_hdr) { + if (req->method == METHOD_POST && data->req_hdr) { if ((t = strstr(data->req_hdr, "\r\n\r\n"))) { post_buf = xstrdup(t + 4); *(t + 4) = '\0'; @@ -444,7 +414,7 @@ static void httpSendRequest(fd, data) } memset(buf, '\0', buflen); - sprintf(buf, "%s %s HTTP/1.0\r\n", Method, data->request); + sprintf(buf, "%s %s HTTP/1.0\r\n", Method, req->urlpath); len = strlen(buf); if (data->req_hdr) { /* we have to parse the request header */ xbuf = xstrdup(data->req_hdr); @@ -504,10 +474,11 @@ static void httpConnInProgress(fd, data) HttpData *data; { StoreEntry *entry = data->entry; + request_t *req = data->REQ; debug(11, 5, "httpConnInProgress: FD %d data=%p\n", fd, data); - if (comm_connect(fd, data->host, data->port) != COMM_OK) { + if (comm_connect(fd, req->host, req->port) != COMM_OK) { debug(11, 5, "httpConnInProgress: FD %d errno=%d\n", fd, errno); switch (errno) { case EINPROGRESS: @@ -539,19 +510,23 @@ int proxyhttpStart(e, url, entry) int sock; int status; HttpData *data = NULL; + request_t *request = NULL; - debug(11, 3, "proxyhttpStart: \n", url); + debug(11, 3, "proxyhttpStart: \"%s %s\"\n", + RequestMethodStr[request->method], url); debug(11, 10, "proxyhttpStart: HTTP request header:\n%s\n", entry->mem_obj->mime_hdr); data = (HttpData *) xcalloc(1, sizeof(HttpData)); data->entry = entry; - - strncpy(data->request, url, sizeof(data->request) - 1); - data->method = entry->method; - data->port = e->ascii_port; data->req_hdr = entry->mem_obj->mime_hdr; - strncpy(data->host, e->host, sizeof(data->host) - 1); + request = (request_t *) xcalloc (1, sizeof(request_t)); + data->free_request = 1; + data->REQ = request; + + strncpy(request->host, e->host, SQUIDHOSTNAMELEN); + request->port = e->ascii_port; + strncpy(request->urlpath, url, MAX_URL); if (e->proxy_only) storeStartDeleteBehind(entry); @@ -567,14 +542,14 @@ int proxyhttpStart(e, url, entry) /* check if IP is already in cache. It must be. * It should be done before this route is called. * Otherwise, we cannot check return code for connect. */ - if (!ipcache_gethostbyname(data->host)) { + if (!ipcache_gethostbyname(request->host)) { debug(11, 4, "proxyhttpstart: Called without IP entry in ipcache. OR lookup failed.\n"); cached_error_entry(entry, ERR_DNS_FAIL, dns_error_message); httpCloseAndFree(sock, data); return COMM_ERROR; } /* Open connection. */ - if ((status = comm_connect(sock, data->host, data->port))) { + if ((status = comm_connect(sock, request->host, request->port))) { if (status != EINPROGRESS) { cached_error_entry(entry, ERR_CONNECT_FAIL, xstrerror()); httpCloseAndFree(sock, data); @@ -597,13 +572,12 @@ int proxyhttpStart(e, url, entry) comm_set_select_handler(sock, COMM_SELECT_WRITE, (PF) httpSendRequest, (void *) data); return COMM_OK; - } -int httpStart(unusedfd, url, method, req_hdr, entry) +int httpStart(unusedfd, url, request, req_hdr, entry) int unusedfd; char *url; - int method; + request_t *request; char *req_hdr; StoreEntry *entry; { @@ -611,20 +585,15 @@ int httpStart(unusedfd, url, method, req_hdr, entry) int sock, status; HttpData *data = NULL; - debug(11, 3, "httpStart: %s \n", RequestMethodStr[method], url); + debug(11, 3, "httpStart: \"%s %s\"\n", + RequestMethodStr[request->method], url); debug(11, 10, "httpStart: req_hdr '%s'\n", req_hdr); data = (HttpData *) xcalloc(1, sizeof(HttpData)); data->entry = entry; - data->method = method; data->req_hdr = req_hdr; + data->REQ = request; - /* Parse url. */ - if (http_url_parser(url, data->host, &data->port, data->request)) { - cached_error_entry(entry, ERR_INVALID_URL, NULL); - safe_free(data); - return COMM_ERROR; - } /* Create socket. */ sock = comm_open(COMM_NONBLOCKING, 0, 0, url); if (sock == COMM_ERROR) { @@ -636,14 +605,14 @@ int httpStart(unusedfd, url, method, req_hdr, entry) /* check if IP is already in cache. It must be. * It should be done before this route is called. * Otherwise, we cannot check return code for connect. */ - if (!ipcache_gethostbyname(data->host)) { + if (!ipcache_gethostbyname(request->host)) { debug(11, 4, "httpstart: Called without IP entry in ipcache. OR lookup failed.\n"); cached_error_entry(entry, ERR_DNS_FAIL, dns_error_message); httpCloseAndFree(sock, data); return COMM_ERROR; } /* Open connection. */ - if ((status = comm_connect(sock, data->host, data->port))) { + if ((status = comm_connect(sock, request->host, request->port))) { if (status != EINPROGRESS) { cached_error_entry(entry, ERR_CONNECT_FAIL, xstrerror()); httpCloseAndFree(sock, data); diff --git a/src/main.cc b/src/main.cc index 1687500978..6af0e1644b 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,4 +1,4 @@ -/* $Id: main.cc,v 1.33 1996/04/15 22:53:35 wessels Exp $ */ +/* $Id: main.cc,v 1.34 1996/04/16 04:23:14 wessels Exp $ */ /* DEBUG: Section 1 main: startup and main loop */ @@ -220,6 +220,7 @@ static void mainInitialize() if (first_time) { first_time = 0; /* module initialization */ + urlInitialize(); disk_init(); stat_init(&CacheInfo, getAccessLogFile()); storeInit(); diff --git a/src/neighbors.cc b/src/neighbors.cc index 8ad856ecb9..55782c5c71 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -1,4 +1,4 @@ -/* $Id: neighbors.cc,v 1.19 1996/04/15 22:53:46 wessels Exp $ */ +/* $Id: neighbors.cc,v 1.20 1996/04/16 04:23:15 wessels Exp $ */ /* TODO: * - change 'neighbor' to 'sibling' @@ -341,7 +341,7 @@ int neighborsUdpPing(proto) protodispatch_data *proto; { char *t = NULL; - char *host = proto->host; + char *host = proto->request->host; char *url = proto->url; StoreEntry *entry = proto->entry; struct hostent *hep = NULL; @@ -532,7 +532,7 @@ void neighborsUdpAck(fd, url, header, from, entry) inet_ntoa(from->sin_addr)); BIT_SET(entry->flag, ENTRY_DISPATCHED); entry->ping_status = DONE; - getFromOrgSource(0, entry); + getFromCache(0, entry, NULL, entry->mem_obj->request); } return; } @@ -552,7 +552,7 @@ void neighborsUdpAck(fd, url, header, from, entry) } BIT_SET(entry->flag, ENTRY_DISPATCHED); entry->ping_status = DONE; - getFromCache(0, entry, e); + getFromCache(0, entry, e, entry->mem_obj->request); e->hits++; return; } else if ((header->opcode == ICP_OP_MISS) || (header->opcode == ICP_OP_DECHO)) { @@ -600,7 +600,7 @@ void neighborsUdpAck(fd, url, header, from, entry) debug(15, 6, "Receive MISSes from all neighbors and parents\n"); /* pass in fd=0 here so getFromCache() looks up the real FD * and resets the timeout handler */ - getFromDefaultSource(0, entry); + getFromCache(0, entry, NULL, entry->mem_obj->request); return; } } else { diff --git a/src/url.cc b/src/url.cc index 1e95be1c49..bf9c2e492f 100644 --- a/src/url.cc +++ b/src/url.cc @@ -1,4 +1,4 @@ -/* $Id: url.cc,v 1.16 1996/04/16 01:51:20 wessels Exp $ */ +/* $Id: url.cc,v 1.17 1996/04/16 04:23:17 wessels Exp $ */ /* * DEBUG: Section 23 url @@ -29,7 +29,6 @@ char *ProtocolStr[] = }; static int url_acceptable[256]; -static int url_acceptable_init = 0; static char hex[17] = "0123456789abcdef"; /* convert %xx in url string to a character @@ -67,7 +66,7 @@ char *url_convert_hex(org_url, allocate) /* INIT Acceptable table. * Borrow from libwww2 with Mosaic2.4 Distribution */ -static void init_url_acceptable() +void urlInitialize() { unsigned int i; char *good = @@ -76,7 +75,6 @@ static void init_url_acceptable() url_acceptable[i] = 0; for (; *good; good++) url_acceptable[(unsigned int) *good] = 1; - url_acceptable_init = 1; } @@ -88,9 +86,6 @@ char *url_escape(url) char *p, *q; char *tmpline = xcalloc(1, MAX_URL); - if (!url_acceptable_init) - init_url_acceptable(); - q = tmpline; for (p = url; *p; p++) { if (url_acceptable[(int) (*p)]) @@ -128,6 +123,10 @@ protocol_t urlParseProtocol(s) return PROTO_HTTP; if (strncasecmp(s, "ftp", 3) == 0) return PROTO_FTP; +#ifndef NO_FTP_FOR_FILE + if (strncasecmp(s, "file", 4) == 0) + return PROTO_FTP; +#endif if (strncasecmp(s, "gopher", 6) == 0) return PROTO_GOPHER; if (strncasecmp(s, "cache_object", 12) == 0) @@ -156,9 +155,80 @@ int urlDefaultPort(p) return CACHE_HTTP_PORT; #ifdef NEED_PROTO_CONNECT case PROTO_CONNECT: - return 443; + return CONNECT_PORT; #endif default: return 0; } } + +request_t *urlParse(method, url) + method_t method; + char *url; +{ + static char proto[MAX_URL+1]; + static char host[MAX_URL+1]; + static char urlpath[MAX_URL+1]; + request_t *request = NULL; + char *t = NULL; + int port; + protocol_t protocol = PROTO_NONE; + proto[0] = host[0] = urlpath[0] = '\0'; + + if (method == METHOD_CONNECT) { + port = CONNECT_PORT; + if (sscanf(url, "%[^:]:%d", host, &port) < 1) + return NULL; + if (!aclMatchInteger(connect_port_list, port)) + return NULL; + } else { + if (sscanf(url, "%[^:]://%[^/]%s", proto, host, urlpath) < 2) + return NULL; + protocol = urlParseProtocol(proto); + port = urlDefaultPort(protocol); + if ((t = strchr(host, ':')) && *(t+1) != '\0') { + *t = '\0'; + port = atoi(t + 1); + } + } + for (t = host; *t; t++) + *t = tolower(*t); + if (port == 0) { + debug(23,0,"urlParse: Invalid port == 0\n"); + return NULL; + } + + request = (request_t *) xcalloc (1, sizeof(request_t)); + request->method = method; + request->protocol = protocol; + strncpy(request->host, host, SQUIDHOSTNAMELEN); + request->port = port; + strncpy(request->urlpath, urlpath, MAX_URL); + return request; +} + +char *urlCanonical (request, buf) + request_t *request; + char *buf; +{ + static char urlbuf[MAX_URL+1]; + static char portbuf[32]; + if (buf == NULL) + buf = urlbuf; + switch (request->method) { + case METHOD_CONNECT: + sprintf(buf, "%s:%d", request->host, request->port); + break; + default: + portbuf[0] = '\0'; + if (request->port != urlDefaultPort(request->protocol)) + sprintf(portbuf, ":%d", request->port); + sprintf(buf, "%s://%s%s%s", + ProtocolStr[request->protocol], + request->host, + portbuf, + request->urlpath); + break; + } + return buf; +} diff --git a/src/wais.cc b/src/wais.cc index 8d74b56c50..023027bc95 100644 --- a/src/wais.cc +++ b/src/wais.cc @@ -1,4 +1,4 @@ -/* $Id: wais.cc,v 1.24 1996/04/12 21:41:44 wessels Exp $ */ +/* $Id: wais.cc,v 1.25 1996/04/16 04:23:18 wessels Exp $ */ /* * DEBUG: Section 24 wais @@ -10,9 +10,9 @@ typedef struct _waisdata { StoreEntry *entry; - char host[SQUIDHOSTNAMELEN + 1]; - int port; - int method; + method_t method; + char *relayhost; + int relayport; char *mime_hdr; char request[MAX_URL]; } WAISData; @@ -26,20 +26,6 @@ static void waisCloseAndFree(fd, data) xfree(data); } - -static int wais_url_parser(url, host, port, request) - char *url; - char *host; - int *port; - char *request; -{ - strcpy(host, getWaisRelayHost()); - *port = getWaisRelayPort(); - strcpy(request, url); - - return 0; -} - /* This will be called when timeout on read. */ static void waisReadReplyTimeout(fd, data) int fd; @@ -239,7 +225,7 @@ void waisSendRequest(fd, data) int waisStart(unusedfd, url, method, mime_hdr, entry) int unusedfd; char *url; - int method; + method_t method; char *mime_hdr; StoreEntry *entry; { @@ -247,11 +233,16 @@ int waisStart(unusedfd, url, method, mime_hdr, entry) int sock, status; WAISData *data = NULL; - debug(24, 3, "waisStart - url:%s, type:%s\n", url, RequestMethodStr[method]); + debug(24, 3, "waisStart: \"%s %s\"\n", + RequestMethodStr[method], url); debug(24, 4, " header: %s\n", mime_hdr); data = (WAISData *) xcalloc(1, sizeof(WAISData)); data->entry = entry; + data->method = method; + data->relayhost = getWaisRelayHost(); + data->relayport = getWaisRelayPort(); + data->mime_hdr = mime_hdr; if (!getWaisRelayHost()) { debug(24, 0, "waisStart: Failed because no relay host defined!\n"); @@ -259,10 +250,6 @@ int waisStart(unusedfd, url, method, mime_hdr, entry) safe_free(data); return COMM_ERROR; } - /* Parse url. */ - (void) wais_url_parser(url, data->host, &data->port, data->request); - data->method = method; - data->mime_hdr = mime_hdr; /* Create socket. */ sock = comm_open(COMM_NONBLOCKING, 0, 0, url); @@ -275,20 +262,20 @@ int waisStart(unusedfd, url, method, mime_hdr, entry) /* check if IP is already in cache. It must be. * It should be done before this route is called. * Otherwise, we cannot check return code for connect. */ - if (!ipcache_gethostbyname(data->host)) { + if (!ipcache_gethostbyname(data->relayhost)) { debug(24, 4, "waisstart: Called without IP entry in ipcache. OR lookup failed.\n"); cached_error_entry(entry, ERR_DNS_FAIL, dns_error_message); waisCloseAndFree(sock, data); return COMM_ERROR; } /* Open connection. */ - if ((status = comm_connect(sock, data->host, data->port))) { + if ((status = comm_connect(sock, data->relayhost, data->relayport))) { if (status != EINPROGRESS) { cached_error_entry(entry, ERR_CONNECT_FAIL, xstrerror()); waisCloseAndFree(sock, data); return COMM_ERROR; } else { - debug(24, 5, "waisStart - conn %d EINPROGRESS\n", sock); + debug(24, 5, "waisStart: FD %d EINPROGRESS\n", sock); } } /* Install connection complete handler. */