/*
- * $Id: client_side.cc,v 1.333 1998/06/09 05:54:12 wessels Exp $
+ * $Id: client_side.cc,v 1.334 1998/06/09 21:18:45 wessels Exp $
*
* DEBUG: section 33 Client-side Routines
* AUTHOR: Duane Wessels
debug(33, 3) ("clientHandleIMSReply: %s, %d bytes\n", url, (int) size);
memFree(MEM_4K_BUF, buf);
buf = NULL;
- /* unregister this handler */
- if (size < 0 || entry->store_status == STORE_ABORTED) {
+ if (size < 0 && entry->store_status != STORE_ABORTED)
+ storeAbort(entry, 1);
+ if (entry->store_status == STORE_ABORTED) {
debug(33, 3) ("clientHandleIMSReply: ABORTED '%s'\n", url);
/* We have an existing entry, but failed to validate it */
/* Its okay to send the old one anyway */
entry = http->entry; /* reset, IMS might have changed it */
if (entry && entry->ping_status == PING_WAITING)
storeReleaseRequest(entry);
- fwdUnregister(entry, request);
}
assert(http->log_type < LOG_TYPE_MAX);
if (entry)
/*
- * $Id: forward.cc,v 1.4 1998/06/09 05:57:34 wessels Exp $
+ * $Id: forward.cc,v 1.5 1998/06/09 21:18:46 wessels Exp $
*
* DEBUG: section 17 Request Forwarding
* AUTHOR: Duane Wessels
static void fwdStartComplete(peer * p, void *data);
static void fwdStartFail(peer * p, void *data);
-static void fwdDispatch(FwdState *, int server_fd);
+static void fwdDispatch(FwdState *);
static void fwdConnectStart(FwdState * fwdState);
static void fwdStateFree(FwdState * fwdState);
static PF fwdConnectTimeout;
{
FwdServer *s;
FwdServer *n = fwdState->servers;
+ int sfd;
+ static int loop_detect = 0;
assert(cbdataValid(fwdState));
+ assert(loop_detect++ == 0);
while ((s = n)) {
n = s->next;
xfree(s->host);
fwdState->servers = NULL;
requestUnlink(fwdState->request);
fwdState->request = NULL;
+ storeUnregisterAbort(fwdState->entry);
storeUnlockObject(fwdState->entry);
fwdState->entry = NULL;
+ sfd = fwdState->server_fd;
+ if (sfd > -1) {
+ comm_remove_close_handler(sfd, fwdServerClosed, fwdState);
+ fwdState->server_fd = -1;
+ debug(17,1)("fwdStateFree: closing FD %d\n", sfd);
+ comm_close(sfd);
+ }
cbdataFree(fwdState);
+ loop_detect--;
}
static void
FwdState *fwdState = data;
debug(17, 3) ("fwdServerClosed: FD %d %s\n", fd,
storeUrl(fwdState->entry));
+ assert(fwdState->server_fd == fd);
+ fwdState->server_fd = -1;
fwdStateFree(fwdState);
}
cbdataUnlock(fwdState);
if (!valid)
return;
+ assert(fwdState->server_fd == server_fd);
if (status == COMM_ERR_DNS) {
debug(17, 4) ("fwdConnectDone: Unknown host: %s\n",
fwdState->request->host);
} else {
fd_note(server_fd, storeUrl(fwdState->entry));
fd_table[server_fd].uses++;
- fwdDispatch(fwdState, server_fd);
+ fwdDispatch(fwdState);
}
}
StoreEntry *entry = fwdState->entry;
ErrorState *err;
debug(17, 3) ("fwdConnectTimeout: FD %d: '%s'\n", fd, storeUrl(entry));
+ assert(fd == fwdState->server_fd);
if (entry->mem_obj->inmem_hi == 0) {
err = errorCon(ERR_READ_TIMEOUT, HTTP_GATEWAY_TIMEOUT);
err->request = requestLink(fwdState->request);
cbdataLock(fwdState);
if ((fd = pconnPop(srv->host, srv->port)) >= 0) {
debug(17, 3) ("fwdConnectStart: reusing pconn FD %d\n", fd);
+ fwdState->server_fd = fd;
comm_add_close_handler(fd, fwdServerClosed, fwdState);
fwdConnectDone(fd, COMM_OK, fwdState);
return;
fwdStateFree(fwdState);
return;
}
+ fwdState->server_fd = fd;
comm_add_close_handler(fd, fwdServerClosed, fwdState);
commSetTimeout(fd,
Config.Timeout.connect,
}
static void
-fwdDispatch(FwdState * fwdState, int server_fd)
+fwdDispatch(FwdState * fwdState)
{
peer *p;
request_t *request = fwdState->request;
netdbPingSite(request->host);
if (fwdState->servers && (p = fwdState->servers->peer)) {
p->stats.fetches++;
- httpStart(fwdState, server_fd);
+ httpStart(fwdState, fwdState->server_fd);
} else {
switch (request->protocol) {
case PROTO_HTTP:
- httpStart(fwdState, server_fd);
+ httpStart(fwdState, fwdState->server_fd);
break;
case PROTO_GOPHER:
- gopherStart(entry, server_fd);
+ gopherStart(entry, fwdState->server_fd);
break;
case PROTO_FTP:
- ftpStart(request, entry, server_fd);
+ ftpStart(request, entry, fwdState->server_fd);
break;
case PROTO_WAIS:
- waisStart(request, entry, server_fd);
+ waisStart(request, entry, fwdState->server_fd);
break;
case PROTO_CACHEOBJ:
cachemgrStart(fwdState->client_fd, request, entry);
urnStart(request, entry);
break;
case PROTO_WHOIS:
- whoisStart(request, entry, server_fd);
+ whoisStart(request, entry, fwdState->server_fd);
break;
case PROTO_INTERNAL:
internalStart(request, entry);
/* 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)
{
cbdataAdd(fwdState, MEM_NONE);
fwdState->entry = entry;
fwdState->client_fd = fd;
+ fwdState->server_fd = -1;
fwdState->request = requestLink(request);
storeLockObject(entry);
switch (request->protocol) {
case PROTO_CACHEOBJ:
case PROTO_WAIS:
case PROTO_INTERNAL:
- fwdDispatch(fwdState, -1);
+ fwdDispatch(fwdState);
return;
default:
break;
}
cbdataLock(fwdState);
+ storeRegisterAbort(entry, fwdAbort, fwdState);
peerSelect(request,
entry,
fwdStartComplete,
fwdState->fail.http_code = http_code;
fwdState->fail.xerrno = xerrno;
}
+
+/*
+ * Called when someone else calls StoreAbort() on this entry
+ */
+void
+fwdAbort(void *data)
+{
+ FwdState * fwdState = data;
+ debug(17,1)("fwdAbort: %s\n", storeUrl(fwdState->entry));
+ fwdStateFree(fwdState);
+}
/*
- * $Id: ftp.cc,v 1.228 1998/06/04 18:57:11 wessels Exp $
+ * $Id: ftp.cc,v 1.229 1998/06/09 21:18:48 wessels Exp $
*
* DEBUG: section 9 File Transfer Protocol (FTP)
* AUTHOR: Harvest Derived
static wordlist *ftpParseControlReply(char *buf, size_t len, int *code);
static void ftpAppendSuccessHeader(FtpStateData * ftpState);
static void ftpAuthRequired(HttpReply * reply, request_t * request, const char *realm);
+#if OLD_CODE
static STABH ftpAbort;
+#endif
static void ftpHackShortcut(FtpStateData * ftpState, FTPSM * nextState);
static void ftpPutStart(FtpStateData *);
static CWCB ftpPutTransferDone;
ftpState->request->host, strBuf(ftpState->request->urlpath),
ftpState->user, ftpState->password);
comm_add_close_handler(fd, ftpStateFree, ftpState);
+#if OLD_CODE
storeRegisterAbort(entry, ftpAbort, ftpState);
+#endif
ftpState->state = BEGIN;
ftpState->ctrl.buf = memAllocate(MEM_4K_BUF);
ftpState->ctrl.freefunc = memFree4K;
storeSetPublicKey(e);
}
+#if OLD_CODE
static void
ftpAbort(void *data)
{
}
comm_close(ftpState->ctrl.fd);
}
+#endif
static void
ftpAuthRequired(HttpReply * old_reply, request_t * request, const char *realm)
/*
- * $Id: gopher.cc,v 1.128 1998/06/04 18:57:12 wessels Exp $
+ * $Id: gopher.cc,v 1.129 1998/06/09 21:18:49 wessels Exp $
*
* DEBUG: section 10 Gopher
* AUTHOR: Harvest Derived
static CWCB gopherSendComplete;
static PF gopherSendRequest;
static GopherStateData *CreateGopherStateData(void);
+#if OLD_CODE
static STABH gopherAbort;
+#endif
static char def_gopher_bin[] = "www/unknown";
static char def_gopher_text[] = "text/plain";
if (gopherState == NULL)
return;
if (gopherState->entry) {
+#if OLD_CODE
storeUnregisterAbort(gopherState->entry);
+#endif
storeUnlockObject(gopherState->entry);
}
memFree(MEM_4K_BUF, gopherState->buf);
return;
}
comm_add_close_handler(fd, gopherStateFree, gopherState);
+#if OLD_CODE
storeRegisterAbort(entry, gopherAbort, gopherState);
+#endif
if (((gopherState->type_id == GOPHER_INDEX) || (gopherState->type_id == GOPHER_CSO))
&& (strchr(gopherState->request, '?') == NULL)) {
/* Index URL without query word */
return (gd);
}
+#if OLD_CODE
static void
gopherAbort(void *data)
{
debug(10, 1) ("gopherAbort: %s\n", storeUrl(gopherState->entry));
comm_close(gopherState->fd);
}
+#endif
/*
- * $Id: http.cc,v 1.284 1998/06/09 05:22:05 wessels Exp $
+ * $Id: http.cc,v 1.285 1998/06/09 21:18:50 wessels Exp $
*
* DEBUG: section 11 Hypertext Transfer Protocol (HTTP)
* AUTHOR: Harvest Derived
static void httpCacheNegatively(StoreEntry *);
static void httpMakePrivate(StoreEntry *);
static void httpMakePublic(StoreEntry *);
-static STABH httpAbort;
static int httpSocketOpen(StoreEntry *, request_t *);
static void httpRestart(HttpStateData *);
static int httpTryRestart(HttpStateData *);
HttpStateData *httpState = data;
if (httpState == NULL)
return;
+#if OLD_CODE
storeUnregisterAbort(httpState->entry);
+#endif
storeUnlockObject(httpState->entry);
if (httpState->reply_hdr) {
memFree(MEM_8K_BUF, httpState->reply_hdr);
* register the handler to free HTTP state data when the FD closes
*/
comm_add_close_handler(fd, httpStateFree, httpState);
- storeRegisterAbort(httpState->entry, httpAbort, httpState);
Counter.server.all.requests++;
Counter.server.http.requests++;
httpConnectDone(fd, COMM_OK, httpState);
}
}
-static void
-httpAbort(void *data)
-{
- HttpStateData *httpState = data;
- debug(11, 2) ("httpAbort: %s\n", storeUrl(httpState->entry));
- comm_close(httpState->fd);
-}
-
static void
httpSendRequestEntry(int fd, char *bufnotused, size_t size, int errflag, void *data)
{
/* 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 fwdFail(FwdState *, int, http_status, int);
+extern STABH fwdAbort;
extern void urnStart(request_t *, StoreEntry *);
/*
- * $Id: ssl.cc,v 1.80 1998/06/04 18:57:19 wessels Exp $
+ * $Id: ssl.cc,v 1.81 1998/06/09 21:18:53 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 */
- fwdUnregister(NULL, sslState->request);
comm_close(sslState->server.fd);
}
/*
- * $Id: store.cc,v 1.422 1998/06/02 04:18:27 wessels Exp $
+ * $Id: store.cc,v 1.423 1998/06/09 21:18:55 wessels Exp $
*
* DEBUG: section 20 Storage Manager
* AUTHOR: Harvest Derived
storeAbort(StoreEntry * e, int cbflag)
{
MemObject *mem = e->mem_obj;
+ STABH *callback;
+ void *data;
assert(e->store_status == STORE_PENDING);
assert(mem != NULL);
debug(20, 6) ("storeAbort: %s\n", storeKeyText(e->key));
mem->object_sz = mem->inmem_hi;
/* Notify the server side */
if (cbflag && mem->abort.callback) {
- mem->abort.callback(mem->abort.data);
+ callback = mem->abort.callback;
+ data = mem->abort.data;
mem->abort.callback = NULL;
+ mem->abort.data = NULL;
+ callback(data);
}
/* Notify the client side */
InvokeHandlers(e);
StoreEntry *entry;
request_t *request;
FwdServer *servers;
+ int server_fd;
struct {
int err_code;
http_status http_code;
/*
- * $Id: tunnel.cc,v 1.80 1998/06/04 18:57:19 wessels Exp $
+ * $Id: tunnel.cc,v 1.81 1998/06/09 21:18:53 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 */
- fwdUnregister(NULL, sslState->request);
comm_close(sslState->server.fd);
}
/*
- * $Id: wais.cc,v 1.110 1998/06/04 18:57:20 wessels Exp $
+ * $Id: wais.cc,v 1.111 1998/06/09 21:18:57 wessels Exp $
*
* DEBUG: section 24 WAIS Relay
* AUTHOR: Harvest Derived
static PF waisReadReply;
static CWCB waisSendComplete;
static PF waisSendRequest;
+#if OLD_CODE
static STABH waisAbort;
+#endif
static void
waisStateFree(int fdnotused, void *data)
WaisStateData *waisState = data;
if (waisState == NULL)
return;
+#if OLD_CODE
storeUnregisterAbort(waisState->entry);
+#endif
storeUnlockObject(waisState->entry);
cbdataFree(waisState);
}
waisState->entry = entry;
xstrncpy(waisState->request, url, MAX_URL);
comm_add_close_handler(waisState->fd, waisStateFree, waisState);
+#if OLD_CODE
storeRegisterAbort(entry, waisAbort, waisState);
+#endif
storeLockObject(entry);
commSetSelect(fd, COMM_SELECT_WRITE, waisSendRequest, waisState, 0);
commSetTimeout(fd, Config.Timeout.read, waisTimeout, waisState);
}
+#if OLD_CODE
static void
waisAbort(void *data)
{
debug(24, 1) ("waisAbort: %s\n", storeUrl(waisState->entry));
comm_close(waisState->fd);
}
+#endif