too frequently.
-/* $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
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 */
* icpReadWriteData */
char *reply_hdr;
int reply_hdr_state;
+ int free_request;
} HttpData;
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;
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';
}
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);
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:
int sock;
int status;
HttpData *data = NULL;
+ request_t *request = NULL;
- debug(11, 3, "proxyhttpStart: <URL:%s>\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);
/* 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);
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;
{
int sock, status;
HttpData *data = NULL;
- debug(11, 3, "httpStart: %s <URL:%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) {
/* 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);
-/* $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 */
if (first_time) {
first_time = 0;
/* module initialization */
+ urlInitialize();
disk_init();
stat_init(&CacheInfo, getAccessLogFile());
storeInit();
-/* $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'
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;
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;
}
}
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)) {
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 {
-/* $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
};
static int url_acceptable[256];
-static int url_acceptable_init = 0;
static char hex[17] = "0123456789abcdef";
/* convert %xx in url string to a character
/* INIT Acceptable table.
* Borrow from libwww2 with Mosaic2.4 Distribution */
-static void init_url_acceptable()
+void urlInitialize()
{
unsigned int i;
char *good =
url_acceptable[i] = 0;
for (; *good; good++)
url_acceptable[(unsigned int) *good] = 1;
- url_acceptable_init = 1;
}
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)])
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)
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;
+}
-/* $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
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;
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;
int waisStart(unusedfd, url, method, mime_hdr, entry)
int unusedfd;
char *url;
- int method;
+ method_t method;
char *mime_hdr;
StoreEntry *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");
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);
/* 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. */