#
# Makefile for the Squid Object Cache server
#
-# $Id: Makefile.in,v 1.152 1998/06/03 22:32:59 rousskov Exp $
+# $Id: Makefile.in,v 1.153 1998/06/04 18:57:06 wessels Exp $
#
# Uncomment and customize the following to suit your needs:
#
event.o \
fd.o \
filemap.o \
+ forward.o \
fqdncache.o \
ftp.o \
globals.o \
pconn.o \
peer_digest.o \
peer_select.o \
- proto.o \
pump.o \
redirect.o \
refresh.o \
urn.o \
useragent.o \
wais.o \
+ whois.o \
$(XTRA_OBJS)
SNMP_OBJS = \
/*
- * $Id: asn.cc,v 1.38 1998/05/30 19:43:01 rousskov Exp $
+ * $Id: asn.cc,v 1.39 1998/06/04 18:57:07 wessels Exp $
*
* DEBUG: section 53 AS Number handling
* AUTHOR: Duane Wessels, Kostas Anagnostakis
/* Head for ip to asn radix tree */
struct radix_node_head *AS_tree_head;
-struct _whoisState {
- StoreEntry *entry;
- request_t *request;
-};
-
/*
* Structure for as number information. it could be simply
* an intlist but it's coded as a structure for future
typedef struct _ASState ASState;
typedef struct _as_info as_info;
-typedef struct _whoisState whoisState;
/* entry into the radix tree */
struct _rtentry {
static int asnAddNet(char *, int);
static void asnCacheStart(int as);
-static PF whoisClose;
-static PF whoisTimeout;
-static CNCB whoisConnectDone;
-static PF whoisReadReply;
static STCB asHandleReply;
static int destroyRadixNode(struct radix_node *rn, void *w);
static void asnAclInitialize(acl * acls);
if ((e = storeGet(k)) == NULL) {
e = storeCreateEntry(asres, asres, 0, METHOD_GET);
storeClientListAdd(e, asState);
- protoDispatch(-1, e, asState->request);
+ fwdStart(-1, e, asState->request);
} else {
storeLockObject(e);
storeClientListAdd(e, asState);
}
xfree(data);
}
-
-
-void
-whoisStart(request_t * request, StoreEntry * entry)
-{
- int fd;
- whoisState *p = xcalloc(1, sizeof(whoisState));
- p->request = request;
- p->entry = entry;
- cbdataAdd(p, MEM_NONE);
- storeLockObject(p->entry);
-
- fd = comm_open(SOCK_STREAM, 0, any_addr, 0, COMM_NONBLOCKING, "whois");
- if (fd == COMM_ERROR) {
- debug(53, 0) ("whoisStart: failed to open a socket\n");
- return;
- }
- comm_add_close_handler(fd, whoisClose, p);
- commConnectStart(fd, request->host, request->port, whoisConnectDone, p);
-}
-
-static void
-whoisConnectDone(int fd, int status, void *data)
-{
- whoisState *p = data;
- char buf[128];
- if (status != COMM_OK) {
- debug(53, 1) ("whoisConnectDone: connect: %s: %s\n",
- p->request->host, xstrerror());
- comm_close(fd);
- return;
- }
- snprintf(buf, sizeof(buf), "%s\r\n", strBuf(p->request->urlpath) + 1);
- debug(53, 3) ("whoisConnectDone: FD %d, '%s'\n", fd, strBuf(p->request->urlpath) + 1);
- comm_write(fd, xstrdup(buf), strlen(buf), NULL, p, xfree);
- commSetSelect(fd, COMM_SELECT_READ, whoisReadReply, p, 0);
- commSetTimeout(fd, Config.Timeout.read, whoisTimeout, p);
-}
-
-static void
-whoisTimeout(int fd, void *data)
-{
- whoisState *p = data;
- debug(53, 1) ("whoisTimeout: %s\n", storeUrl(p->entry));
- whoisClose(fd, p);
-}
-
-static void
-whoisReadReply(int fd, void *data)
-{
- whoisState *p = data;
- StoreEntry *entry = p->entry;
- char *buf = memAllocate(MEM_4K_BUF);
- int len;
-
- len = read(fd, buf, 4095);
- buf[len] = '\0';
- debug(53, 3) ("whoisReadReply: FD %d read %d bytes\n", fd, len);
- debug(53, 5) ("{%s}\n", buf);
- if (len <= 0) {
- storeComplete(entry);
- debug(53, 3) ("whoisReadReply: Done: %s\n", storeUrl(entry));
- comm_close(fd);
- memFree(MEM_4K_BUF, buf);
- return;
- }
- storeAppend(entry, buf, len);
- memFree(MEM_4K_BUF, buf);
- fd_bytes(fd, len, FD_READ);
- commSetSelect(fd, COMM_SELECT_READ, whoisReadReply, p, Config.Timeout.read);
-}
-
-static void
-whoisClose(int fd, void *data)
-{
- whoisState *p = data;
- debug(53, 3) ("whoisClose: FD %d\n", fd);
- storeUnlockObject(p->entry);
- cbdataFree(p);
-}
/*
- * $Id: client_side.cc,v 1.329 1998/06/04 05:46:01 rousskov Exp $
+ * $Id: client_side.cc,v 1.330 1998/06/04 18:57:08 wessels Exp $
*
* DEBUG: section 33 Client-side Routines
* AUTHOR: Duane Wessels
entry->refcount++; /* EXPIRED CASE */
http->entry = entry;
http->out.offset = 0;
- protoDispatch(http->conn->fd, http->entry, http->request);
+ fwdStart(http->conn->fd, http->entry, http->request);
/* Register with storage manager to receive updates when data comes in. */
if (entry->store_status == STORE_ABORTED)
debug(33, 0) ("clientProcessExpired: entry->swap_status == STORE_ABORTED\n");
entry = http->entry; /* reset, IMS might have changed it */
if (entry && entry->ping_status == PING_WAITING)
storeReleaseRequest(entry);
- protoUnregister(entry, request);
+ fwdUnregister(entry, request);
}
assert(http->log_type < LOG_TYPE_MAX);
if (entry)
http->entry->refcount++;
if (http->flags.internal)
r->protocol = PROTO_INTERNAL;
- protoDispatch(http->conn->fd, http->entry, r);
+ fwdStart(http->conn->fd, http->entry, r);
}
static clientHttpRequest *
--- /dev/null
+
+/*
+ * $Id: forward.cc,v 1.1 1998/06/04 18:57:10 wessels Exp $
+ *
+ * DEBUG: section 17 Request Forwarding
+ * AUTHOR: Duane Wessels
+ *
+ * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
+ * --------------------------------------------------------
+ *
+ * Squid is the result of efforts by numerous individuals from the
+ * Internet community. Development is led by Duane Wessels of the
+ * National Laboratory for Applied Network Research and funded by
+ * the National Science Foundation.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+
+#include "squid.h"
+
+struct _server {
+ char *host;
+ u_short port;
+ peer *peer;
+ struct _server *next;
+};
+
+typedef struct {
+ int fd;
+ StoreEntry *entry;
+ request_t *request;
+ struct _server *servers;
+} FwdState;
+
+static void fwdStartComplete(peer * p, void *data);
+static void fwdStartFail(peer * p, void *data);
+static void fwdDispatch(FwdState *, int server_fd);
+
+static void
+fwdStateFree(void *data)
+{
+ FwdState *fwdState = data;
+ struct _server *s;
+ struct _server *n = fwdState->servers;
+ while ((s = n)) {
+ n = s->next;
+ xfree(s->host);
+ xfree(s);
+ }
+ fwdState->servers = NULL;
+ requestUnlink(fwdState->request);
+ cbdataFree(fwdState);
+}
+
+static void
+fwdConnectDone(int server_fd, int status, void *data)
+{
+ FwdState *fwdState = data;
+ ErrorState *err;
+ if (status == COMM_ERR_DNS) {
+ debug(17, 4) ("fwdConnectDone: Unknown host: %s\n",
+ fwdState->request->host);
+ err = errorCon(ERR_DNS_FAIL, HTTP_SERVICE_UNAVAILABLE);
+ err->dnsserver_msg = xstrdup(dns_error_message);
+ err->request = requestLink(fwdState->request);
+ errorAppendEntry(fwdState->entry, err);
+ comm_close(server_fd);
+ } else if (status != COMM_OK) {
+ err = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE);
+ err->xerrno = errno;
+ err->host = xstrdup(fwdState->servers->host);
+ err->port = fwdState->servers->port;
+ err->request = requestLink(fwdState->request);
+ errorAppendEntry(fwdState->entry, err);
+ assert(fwdState->servers);
+ if (fwdState->servers->peer)
+ peerCheckConnectStart(fwdState->servers->peer);
+ comm_close(server_fd);
+ } else {
+ fd_note(server_fd, storeUrl(fwdState->entry));
+ fd_table[server_fd].uses++;
+ fwdDispatch(fwdState, server_fd);
+ }
+ fwdStateFree(fwdState);
+}
+
+static void
+fwdConnectTimeout(int fd, void *data)
+{
+ FwdState *fwdState = data;
+ StoreEntry *entry = fwdState->entry;
+ ErrorState *err;
+ debug(17, 3) ("fwdConnectTimeout: FD %d: '%s'\n", fd, storeUrl(entry));
+ assert(entry->store_status == STORE_PENDING);
+ if (entry->mem_obj->inmem_hi == 0) {
+ err = errorCon(ERR_READ_TIMEOUT, HTTP_GATEWAY_TIMEOUT);
+ err->request = requestLink(fwdState->request);
+ errorAppendEntry(entry, err);
+ } else {
+ storeAbort(entry, 0);
+ }
+ comm_close(fd);
+}
+
+static void
+fwdConnectStart(FwdState * fwdState)
+{
+ const char *url = storeUrl(fwdState->entry);
+ int fd;
+ ErrorState *err;
+ struct _server *srv = fwdState->servers;
+ assert(srv);
+ debug(17, 3) ("fwdConnectStart: %s\n", url);
+ if ((fd = pconnPop(srv->host, srv->port)) >= 0) {
+ debug(17, 3) ("fwdConnectStart: reusing pconn FD %d\n", fd);
+ fwdConnectDone(fd, COMM_OK, fwdState);
+ return;
+ }
+ fd = comm_open(SOCK_STREAM,
+ 0,
+ Config.Addrs.tcp_outgoing,
+ 0,
+ COMM_NONBLOCKING,
+ url);
+ if (fd < 0) {
+ debug(50, 4) ("fwdConnectStart: %s\n", xstrerror());
+ err = errorCon(ERR_SOCKET_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
+ err->xerrno = errno;
+ err->request = requestLink(fwdState->request);
+ errorAppendEntry(fwdState->entry, err);
+ return;
+ }
+ commSetTimeout(fd,
+ Config.Timeout.connect,
+ fwdConnectTimeout,
+ fwdState);
+ commConnectStart(fd,
+ srv->host,
+ srv->port,
+ fwdConnectDone,
+ fwdState);
+}
+
+static void
+fwdStartComplete(peer * p, void *data)
+{
+ FwdState *fwdState = data;
+ struct _server *s;
+ if (!storeUnlockObject(fwdState->entry))
+ return;
+ s = xcalloc(1, sizeof(*s));
+ if (NULL != p) {
+ s->host = xstrdup(p->host);
+ s->port = p->http_port;
+ s->peer = p;
+ } else {
+ s->host = xstrdup(fwdState->request->host);
+ s->port = fwdState->request->port;
+ }
+ fwdState->servers = s;
+ fwdConnectStart(fwdState);
+}
+
+static void
+fwdStartFail(peer * peernotused, void *data)
+{
+ FwdState *fwdState = data;
+ ErrorState *err;
+ if (!storeUnlockObject(fwdState->entry))
+ return;
+ err = errorCon(ERR_CANNOT_FORWARD, HTTP_SERVICE_UNAVAILABLE);
+ err->request = requestLink(fwdState->request);
+ errorAppendEntry(fwdState->entry, err);
+ requestUnlink(fwdState->request);
+ cbdataFree(fwdState);
+}
+static void
+fwdDispatch(FwdState * fwdState, int server_fd)
+{
+ peer *p;
+ request_t *request = fwdState->request;
+ StoreEntry *entry = fwdState->entry;
+ debug(17, 5) ("fwdDispatch: FD %d: Fetching '%s %s'\n",
+ fwdState->fd,
+ RequestMethodStr[request->method],
+ storeUrl(entry));
+ assert(!EBIT_TEST(entry->flag, ENTRY_DISPATCHED));
+ assert(entry->ping_status != PING_WAITING);
+ EBIT_SET(entry->flag, ENTRY_DISPATCHED);
+ netdbPingSite(request->host);
+ if (fwdState->servers && (p = fwdState->servers->peer)) {
+ p->stats.fetches++;
+ httpStart(request, entry, p, server_fd);
+ } else {
+ switch (request->protocol) {
+ case PROTO_HTTP:
+ httpStart(request, entry, NULL, server_fd);
+ break;
+ case PROTO_GOPHER:
+ gopherStart(entry, server_fd);
+ break;
+ case PROTO_FTP:
+ ftpStart(request, entry, server_fd);
+ break;
+ case PROTO_WAIS:
+ waisStart(request, entry, server_fd);
+ break;
+ case PROTO_CACHEOBJ:
+ cachemgrStart(fwdState->fd, request, entry);
+ break;
+ case PROTO_URN:
+ urnStart(request, entry);
+ break;
+ case PROTO_WHOIS:
+ whoisStart(request, entry, server_fd);
+ break;
+ case PROTO_INTERNAL:
+ internalStart(request, entry);
+ break;
+ default:
+ if (request->method == METHOD_CONNECT) {
+ ErrorState *err;
+ debug(17, 1) ("fwdDispatch: Cannot retrieve '%s'\n",
+ storeUrl(entry));
+ err = errorCon(ERR_UNSUP_REQ, HTTP_BAD_REQUEST);
+ err->request = requestLink(request);
+ errorAppendEntry(entry, err);
+ }
+ }
+ }
+}
+
+/* PUBLIC FUNCTIONS */
+
+int
+fwdUnregister(StoreEntry * entry, request_t * request)
+{
+ const char *url = entry ? storeUrl(entry) : NULL;
+ protocol_t proto = request ? request->protocol : PROTO_NONE;
+ ErrorState *err;
+ debug(17, 5) ("fwdUnregister '%s'\n", url ? url : "NULL");
+ if (proto == PROTO_CACHEOBJ)
+ return 0;
+ if (entry == NULL)
+ return 0;
+ if (EBIT_TEST(entry->flag, ENTRY_DISPATCHED))
+ return 0;
+ if (entry->mem_status != NOT_IN_MEMORY)
+ return 0;
+ if (entry->store_status != STORE_PENDING)
+ return 0;
+ err = errorCon(ERR_CLIENT_ABORT, HTTP_INTERNAL_SERVER_ERROR);
+ err->request = request;
+ errorAppendEntry(entry, err);
+ return 1;
+}
+
+void
+fwdStart(int fd, StoreEntry * entry, request_t * request)
+{
+ FwdState *fwdState;
+ debug(17, 3) ("fwdStart: '%s'\n", storeUrl(entry));
+ entry->mem_obj->request = requestLink(request);
+ entry->mem_obj->fd = fd;
+ fwdState = xcalloc(1, sizeof(FwdState));
+ cbdataAdd(fwdState, MEM_NONE);
+ fwdState->entry = entry;
+ fwdState->fd = fd;
+ fwdState->request = requestLink(request);
+ switch (request->protocol) {
+ case PROTO_CACHEOBJ:
+ case PROTO_WAIS:
+ case PROTO_INTERNAL:
+ fwdDispatch(fwdState, -1);
+ return;
+ default:
+ break;
+ } /* Keep the StoreEntry locked during peer selection phase */
+ storeLockObject(entry);
+ peerSelect(request,
+ entry,
+ fwdStartComplete,
+ fwdStartFail,
+ fwdState);
+}
+
+/* This is called before reading data from the server side to
+ * decide if the server side should abort the fetch.
+ * XXX This probably breaks quick_abort!
+ * When to abort?
+ * - NOT if there are clients reading
+ * - YES if we don't know the content length
+ * - YES if we do know the content length and we don't have the
+ * whole object
+ */
+int
+fwdAbortFetch(StoreEntry * entry)
+{
+ MemObject *mem;
+ const HttpReply *reply;
+ if (storeClientWaiting(entry))
+ return 0;
+ mem = entry->mem_obj;
+ reply = mem->reply;
+ if (reply->content_length < 0)
+ return 1;
+ if (mem->inmem_hi < reply->content_length + reply->hdr_sz)
+ return 1;
+ return 0;
+}
+
+int
+fwdCheckDeferRead(int fdnotused, void *data)
+{
+ StoreEntry *e = data;
+ MemObject *mem = e->mem_obj;
+ if (mem == NULL)
+ return 0;
+ if (mem->inmem_hi - storeLowestMemReaderOffset(e) < READ_AHEAD_GAP)
+ return 0;
+ return 1;
+}
/*
- * $Id: ftp.cc,v 1.227 1998/05/26 16:20:20 wessels Exp $
+ * $Id: ftp.cc,v 1.228 1998/06/04 18:57:11 wessels Exp $
*
* DEBUG: section 9 File Transfer Protocol (FTP)
* AUTHOR: Harvest Derived
typedef void (FTPSM) (FtpStateData *);
/* Local functions */
-static CNCB ftpConnectDone;
static CNCB ftpPasvCallback;
static PF ftpDataRead;
static PF ftpStateFree;
StoreEntry *entry = ftpState->entry;
MemObject *mem = entry->mem_obj;
assert(fd == ftpState->data.fd);
- if (protoAbortFetch(entry)) {
+ if (fwdAbortFetch(entry)) {
storeAbort(entry, 0);
ftpDataTransferDone(ftpState);
return;
}
void
-ftpStart(request_t * request, StoreEntry * entry)
+ftpStart(request_t * request, StoreEntry * entry, int fd)
{
LOCAL_ARRAY(char, realm, 8192);
const char *url = storeUrl(entry);
FtpStateData *ftpState = xcalloc(1, sizeof(FtpStateData));
- int fd;
- ErrorState *err;
HttpReply *reply;
cbdataAdd(ftpState, MEM_NONE);
debug(9, 3) ("FtpStart: '%s'\n", url);
storeLockObject(entry);
ftpState->entry = entry;
ftpState->request = requestLink(request);
- ftpState->ctrl.fd = -1;
+ ftpState->ctrl.fd = fd;
ftpState->data.fd = -1;
ftpState->size = -1;
ftpState->flags.pasv_supported = 1;
debug(9, 5) ("FtpStart: host=%s, path=%s, user=%s, passwd=%s\n",
ftpState->request->host, strBuf(ftpState->request->urlpath),
ftpState->user, ftpState->password);
- fd = comm_open(SOCK_STREAM,
- 0,
- Config.Addrs.tcp_outgoing,
- 0,
- COMM_NONBLOCKING,
- url);
- if (fd == COMM_ERROR) {
- debug(9, 4) ("ftpStart: Failed to open a socket.\n");
- err = errorCon(ERR_SOCKET_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
- err->xerrno = errno;
- err->request = requestLink(ftpState->request);
- errorAppendEntry(entry, err);
- return;
- }
- ftpState->ctrl.fd = fd;
comm_add_close_handler(fd, ftpStateFree, ftpState);
storeRegisterAbort(entry, ftpAbort, ftpState);
- commSetTimeout(fd, Config.Timeout.connect, ftpTimeout, ftpState);
- commConnectStart(ftpState->ctrl.fd,
- request->host,
- request->port,
- ftpConnectDone,
- ftpState);
-}
-
-static void
-ftpConnectDone(int fd, int status, void *data)
-{
- FtpStateData *ftpState = data;
- request_t *request = ftpState->request;
- ErrorState *err;
- debug(9, 3) ("ftpConnectDone, status = %d\n", status);
- if (status == COMM_ERR_DNS) {
- debug(9, 4) ("ftpConnectDone: Unknown host: %s\n", request->host);
- err = errorCon(ERR_DNS_FAIL, HTTP_SERVICE_UNAVAILABLE);
- err->dnsserver_msg = xstrdup(dns_error_message);
- err->request = requestLink(request);
- errorAppendEntry(ftpState->entry, err);
- comm_close(ftpState->ctrl.fd);
- } else if (status != COMM_OK) {
- err = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE);
- err->xerrno = errno;
- err->host = xstrdup(request->host);
- err->port = request->port;
- err->request = requestLink(request);
- errorAppendEntry(ftpState->entry, err);
- comm_close(ftpState->ctrl.fd);
- } else {
- ftpState->state = BEGIN;
- ftpState->ctrl.buf = memAllocate(MEM_4K_BUF);
- ftpState->ctrl.freefunc = memFree4K;
- ftpState->ctrl.size = 4096;
- ftpState->ctrl.offset = 0;
- ftpState->data.buf = xmalloc(SQUID_TCP_SO_RCVBUF);
- ftpState->data.size = SQUID_TCP_SO_RCVBUF;
- ftpState->data.freefunc = xfree;
- commSetSelect(fd, COMM_SELECT_READ, ftpReadControlReply, ftpState, 0);
- commSetTimeout(fd, Config.Timeout.read, ftpTimeout, ftpState);
- }
+ ftpState->state = BEGIN;
+ ftpState->ctrl.buf = memAllocate(MEM_4K_BUF);
+ ftpState->ctrl.freefunc = memFree4K;
+ ftpState->ctrl.size = 4096;
+ ftpState->ctrl.offset = 0;
+ ftpState->data.buf = xmalloc(SQUID_TCP_SO_RCVBUF);
+ ftpState->data.size = SQUID_TCP_SO_RCVBUF;
+ ftpState->data.freefunc = xfree;
+ commSetSelect(fd, COMM_SELECT_READ, ftpReadControlReply, ftpState, 0);
+ commSetTimeout(fd, Config.Timeout.read, ftpTimeout, ftpState);
}
/* ====================================================================== */
ftpDataRead,
ftpState,
Config.Timeout.read);
- commSetDefer(ftpState->data.fd, protoCheckDeferRead, ftpState->entry);
+ commSetDefer(ftpState->data.fd, fwdCheckDeferRead, ftpState->entry);
ftpState->state = READING_DATA;
/*
* Cancel the timeout on the Control socket and establish one
ftpDataRead,
ftpState,
Config.Timeout.read);
- commSetDefer(ftpState->data.fd, protoCheckDeferRead, ftpState->entry);
+ commSetDefer(ftpState->data.fd, fwdCheckDeferRead, ftpState->entry);
ftpState->state = READING_DATA;
/*
* Cancel the timeout on the Control socket and establish one
/*
- * $Id: gopher.cc,v 1.127 1998/06/02 04:18:21 wessels Exp $
+ * $Id: gopher.cc,v 1.128 1998/06/04 18:57:12 wessels Exp $
*
* DEBUG: section 10 Gopher
* AUTHOR: Harvest Derived
static CWCB gopherSendComplete;
static PF gopherSendRequest;
static GopherStateData *CreateGopherStateData(void);
-static CNCB gopherConnectDone;
static STABH gopherAbort;
static char def_gopher_bin[] = "www/unknown";
int len;
int clen;
int bin;
- if (protoAbortFetch(entry)) {
+ if (fwdAbortFetch(entry)) {
storeAbort(entry, 0);
comm_close(fd);
return;
}
/* Schedule read reply. */
commSetSelect(fd, COMM_SELECT_READ, gopherReadReply, gopherState, 0);
- commSetDefer(fd, protoCheckDeferRead, entry);
+ commSetDefer(fd, fwdCheckDeferRead, entry);
if (buf)
memFree(MEM_4K_BUF, buf); /* Allocated by gopherSendRequest. */
}
}
void
-gopherStart(StoreEntry * entry)
+gopherStart(StoreEntry * entry, int fd)
{
GopherStateData *gopherState = CreateGopherStateData();
- ErrorState *err;
- int fd;
storeLockObject(entry);
gopherState->entry = entry;
debug(10, 3) ("gopherStart: %s\n", storeUrl(entry));
gopherStateFree(-1, gopherState);
return;
}
- /* Create socket. */
- fd = comm_open(SOCK_STREAM,
- 0,
- Config.Addrs.tcp_outgoing,
- 0,
- COMM_NONBLOCKING,
- storeUrl(entry));
- if (fd == COMM_ERROR) {
- debug(10, 4) ("gopherStart: Failed because we're out of sockets.\n");
- err = errorCon(ERR_SOCKET_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
- err->xerrno = errno;
- err->url = xstrdup(storeUrl(entry));
- errorAppendEntry(entry, err);
- gopherStateFree(-1, gopherState);
- return;
- }
comm_add_close_handler(fd, gopherStateFree, gopherState);
storeRegisterAbort(entry, gopherAbort, gopherState);
if (((gopherState->type_id == GOPHER_INDEX) || (gopherState->type_id == GOPHER_CSO))
comm_close(fd);
return;
}
- commSetTimeout(fd, Config.Timeout.connect, gopherTimeout, gopherState);
- commConnectStart(fd,
- gopherState->host,
- gopherState->port,
- gopherConnectDone,
- gopherState);
gopherState->fd = fd;
+ commSetSelect(fd, COMM_SELECT_WRITE, gopherSendRequest, gopherState, 0);
+ commSetTimeout(fd, Config.Timeout.read, gopherTimeout, gopherState);
}
-static void
-gopherConnectDone(int fd, int status, void *data)
-{
- GopherStateData *gopherState = data;
- StoreEntry *entry = gopherState->entry;
-
- ErrorState *err;
- if (status == COMM_ERR_DNS) {
- debug(10, 4) ("gopherConnectDone: Unknown host: %s\n", gopherState->host);
- err = errorCon(ERR_DNS_FAIL, HTTP_SERVICE_UNAVAILABLE);
- err->dnsserver_msg = xstrdup(dns_error_message);
- err->url = xstrdup(storeUrl(entry));
- errorAppendEntry(entry, err);
- comm_close(fd);
- } else if (status != COMM_OK) {
- ErrorState *err;
- err = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE);
- err->xerrno = errno;
- err->host = xstrdup(gopherState->host);
- err->port = gopherState->port;
- err->url = xstrdup(storeUrl(entry));
- errorAppendEntry(entry, err);
- comm_close(fd);
- } else {
- commSetSelect(fd, COMM_SELECT_WRITE, gopherSendRequest, gopherState, 0);
- commSetTimeout(fd, Config.Timeout.read, gopherTimeout, gopherState);
- }
-}
-
-
static GopherStateData *
CreateGopherStateData(void)
{
/*
- * $Id: http.cc,v 1.281 1998/06/03 22:33:02 rousskov Exp $
+ * $Id: http.cc,v 1.282 1998/06/04 18:57:14 wessels Exp $
*
* DEBUG: section 11 Hypertext Transfer Protocol (HTTP)
* AUTHOR: Harvest Derived
int bin;
int clen;
ErrorState *err;
- if (protoAbortFetch(entry)) {
+ if (fwdAbortFetch(entry)) {
storeAbort(entry, 0);
comm_close(fd);
return;
COMM_SELECT_READ,
httpReadReply,
httpState, 0);
- commSetDefer(fd, protoCheckDeferRead, entry);
+ commSetDefer(fd, fwdCheckDeferRead, entry);
}
}
}
void
-httpStart(request_t * request, StoreEntry * entry, peer * e)
+httpStart(request_t * request, StoreEntry * entry, peer * e, int fd)
{
HttpStateData *httpState;
- int fd;
debug(11, 3) ("httpStart: \"%s %s\"\n",
RequestMethodStr[request->method], storeUrl(entry));
Counter.server.all.requests++;
Counter.server.http.requests++;
- if (e) {
+ if (e)
if (EBIT_TEST(e->options, NEIGHBOR_PROXY_ONLY))
storeReleaseRequest(entry);
- if ((fd = pconnPop(e->host, e->http_port)) >= 0) {
- debug(11, 3) ("httpStart: reusing pconn FD %d\n", fd);
- httpState = httpBuildState(fd, entry, request, e);
- commSetTimeout(httpState->fd,
- Config.Timeout.connect,
- httpTimeout,
- httpState);
- httpConnectDone(fd, COMM_OK, httpState);
- return;
- }
- } else {
- if ((fd = pconnPop(request->host, request->port)) >= 0) {
- debug(11, 3) ("httpStart: reusing pconn FD %d\n", fd);
- httpState = httpBuildState(fd, entry, request, e);
- commSetTimeout(httpState->fd,
- Config.Timeout.connect,
- httpTimeout,
- httpState);
- httpConnectDone(fd, COMM_OK, httpState);
- return;
- }
- }
- if ((fd = httpSocketOpen(entry, request)) < 0)
- return;
httpState = httpBuildState(fd, entry, request, e);
- commSetTimeout(httpState->fd,
- Config.Timeout.connect,
- httpTimeout,
- httpState);
- commConnectStart(httpState->fd,
- httpState->request->host,
- httpState->request->port,
- httpConnectDone,
- httpState);
+ httpConnectDone(fd, COMM_OK, httpState);
}
static int
/*
- * $Id: peer_digest.cc,v 1.37 1998/06/04 16:09:37 rousskov Exp $
+ * $Id: peer_digest.cc,v 1.38 1998/06/04 18:57:16 wessels Exp $
*
* DEBUG: section 72 Peer Digest Routines
* AUTHOR: Alex Rousskov
if (old_e)
e->lastmod = old_e->lastmod;
fetch->offset = 0;
- debug(72, 3) ("peerDigestRequest: forwarding to protoDispatch...\n");
+ debug(72, 3) ("peerDigestRequest: forwarding to fwdStart...\n");
/* push towards peer cache */
- protoDispatch(-1, e, req);
+ fwdStart(-1, e, req);
storeClientCopy(e, 0, 0, SM_PAGE_SIZE, memAllocate(MEM_4K_BUF),
peerDigestFetchReply, fetch);
}
extern void fqdncache_restart(void);
extern EVH fqdncache_purgelru;
-extern void ftpStart(request_t * req, StoreEntry * entry);
+extern void ftpStart(request_t * req, StoreEntry * entry, int);
extern char *ftpUrlWith2f(const request_t *);
-extern void gopherStart(StoreEntry *);
+extern void gopherStart(StoreEntry *, int fd);
extern int gopherCachable(const char *);
-extern void whoisStart(request_t * req, StoreEntry *);
+extern void whoisStart(request_t * req, StoreEntry *, int fd);
extern hash_table *hash_create(HASHCMP *, int, HASHHASH *);
extern void hash_join(hash_table *, hash_link *);
extern HASHHASH hash4;
extern int httpCachable(method_t);
-extern void httpStart(request_t *, StoreEntry *, peer *);
+extern void httpStart(request_t *, StoreEntry *, peer *, int);
extern void httpParseReplyHeaders(const char *, http_reply *);
extern void httpProcessReplyHeader(HttpStateData *, const char *, int);
extern size_t httpBuildRequestPrefix(request_t * request,
/* peer_digest.c */
extern EVH peerDigestInit;
-extern void protoDispatch(int, StoreEntry *, request_t *);
-
-extern int protoUnregister(StoreEntry *, request_t *);
-extern int protoAbortFetch(StoreEntry * entry);
-extern DEFER protoCheckDeferRead;
+/* forward.c */
+extern void fwdStart(int, StoreEntry *, request_t *);
+extern int fwdUnregister(StoreEntry *, request_t *);
+extern int fwdAbortFetch(StoreEntry * entry);
+extern DEFER fwdCheckDeferRead;
extern void urnStart(request_t *, StoreEntry *);
extern void start_announce(void *unused);
extern void sslStart(int fd, const char *, request_t *, size_t * sz);
-extern void waisStart(request_t *, StoreEntry *);
+extern void waisStart(request_t *, StoreEntry *, int fd);
extern void passStart(int, const char *, request_t *, size_t *);
extern void identStart(int, ConnStateData *, IDCB * callback, void *);
/*
- * $Id: ssl.cc,v 1.79 1998/05/22 23:44:24 wessels Exp $
+ * $Id: ssl.cc,v 1.80 1998/06/04 18:57:19 wessels Exp $
*
* DEBUG: section 26 Secure Sockets Layer Proxy
* AUTHOR: Duane Wessels
debug(26, 3) ("sslClientClosed: FD %d\n", fd);
/* we have been called from comm_close for the client side, so
* just need to clean up the server side */
- protoUnregister(NULL, sslState->request);
+ fwdUnregister(NULL, sslState->request);
comm_close(sslState->server.fd);
}
/*
- * $Id: tunnel.cc,v 1.79 1998/05/22 23:44:24 wessels Exp $
+ * $Id: tunnel.cc,v 1.80 1998/06/04 18:57:19 wessels Exp $
*
* DEBUG: section 26 Secure Sockets Layer Proxy
* AUTHOR: Duane Wessels
debug(26, 3) ("sslClientClosed: FD %d\n", fd);
/* we have been called from comm_close for the client side, so
* just need to clean up the server side */
- protoUnregister(NULL, sslState->request);
+ fwdUnregister(NULL, sslState->request);
comm_close(sslState->server.fd);
}
/*
*
- * $Id: urn.cc,v 1.34 1998/05/27 22:52:03 rousskov Exp $
+ * $Id: urn.cc,v 1.35 1998/06/04 18:57:19 wessels Exp $
*
* DEBUG: section 52 URN Parsing
* AUTHOR: Kostas Anagnostakis
if ((urlres_e = storeGet(k)) == NULL) {
urlres_e = storeCreateEntry(urlres, urlres, 0, METHOD_GET);
storeClientListAdd(urlres_e, urnState);
- protoDispatch(-1, urlres_e, urlres_r);
+ fwdStart(-1, urlres_e, urlres_r);
} else {
storeLockObject(urlres_e);
storeClientListAdd(urlres_e, urnState);
/*
- * $Id: wais.cc,v 1.109 1998/06/02 04:18:29 wessels Exp $
+ * $Id: wais.cc,v 1.110 1998/06/04 18:57:20 wessels Exp $
*
* DEBUG: section 24 WAIS Relay
* AUTHOR: Harvest Derived
static PF waisReadReply;
static CWCB waisSendComplete;
static PF waisSendRequest;
-static CNCB waisConnectDone;
static STABH waisAbort;
static void
int clen;
int off;
int bin;
- if (protoAbortFetch(entry)) {
+ if (fwdAbortFetch(entry)) {
ErrorState *err;
err = errorCon(ERR_CLIENT_ABORT, HTTP_INTERNAL_SERVER_ERROR);
err->request = urlParse(METHOD_CONNECT, waisState->request);
COMM_SELECT_READ,
waisReadReply,
waisState, 0);
- commSetDefer(fd, protoCheckDeferRead, entry);
+ commSetDefer(fd, fwdCheckDeferRead, entry);
}
}
}
void
-waisStart(request_t * request, StoreEntry * entry)
+waisStart(request_t * request, StoreEntry * entry, int fd)
{
WaisStateData *waisState = NULL;
- int fd;
const char *url = storeUrl(entry);
method_t method = request->method;
debug(24, 3) ("waisStart: \"%s %s\"\n", RequestMethodStr[method], url);
errorAppendEntry(entry, err);
return;
}
- fd = comm_open(SOCK_STREAM,
- 0,
- Config.Addrs.tcp_outgoing,
- 0,
- COMM_NONBLOCKING,
- url);
- if (fd == COMM_ERROR) {
- ErrorState *err;
- debug(24, 4) ("waisStart: Failed because we're out of sockets.\n");
- err = errorCon(ERR_SOCKET_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
- err->request = urlParse(METHOD_CONNECT, waisState->request);
- errorAppendEntry(entry, err);
- return;
- }
waisState = xcalloc(1, sizeof(WaisStateData));
cbdataAdd(waisState, MEM_NONE);
waisState->method = method;
xstrncpy(waisState->request, url, MAX_URL);
comm_add_close_handler(waisState->fd, waisStateFree, waisState);
storeRegisterAbort(entry, waisAbort, waisState);
- commSetTimeout(fd, Config.Timeout.read, waisTimeout, waisState);
storeLockObject(entry);
- commConnectStart(waisState->fd,
- waisState->relayhost,
- waisState->relayport,
- waisConnectDone,
- waisState);
-}
-
-static void
-waisConnectDone(int fd, int status, void *data)
-{
- WaisStateData *waisState = data;
- char *request = waisState->request;
- ErrorState *err;
-
- if (status == COMM_ERR_DNS) {
- err = errorCon(ERR_DNS_FAIL, HTTP_SERVICE_UNAVAILABLE);
- err->dnsserver_msg = xstrdup(dns_error_message);
- err->request = urlParse(METHOD_CONNECT, request);
- errorAppendEntry(waisState->entry, err);
- comm_close(fd);
- } else if (status != COMM_OK) {
- err = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE);
- err->xerrno = errno;
- err->host = xstrdup(waisState->relayhost);
- err->port = waisState->relayport;
- err->request = urlParse(METHOD_CONNECT, request);
- errorAppendEntry(waisState->entry, err);
- comm_close(fd);
- } else {
- commSetSelect(fd, COMM_SELECT_WRITE, waisSendRequest, waisState, 0);
- commSetTimeout(fd, Config.Timeout.read, waisTimeout, waisState);
- }
+ commSetSelect(fd, COMM_SELECT_WRITE, waisSendRequest, waisState, 0);
+ commSetTimeout(fd, Config.Timeout.read, waisTimeout, waisState);
}
static void