debug(93,5)("ICAPClientRespmodPrecache::noteSourceStart() called\n");
HttpReply *reply = dynamic_cast<HttpReply*>(adapted->data->header);
+ /*
+ * The ICAP reply MUST have a new HTTP reply header, or else
+ * it is an invalid ICAP message. Invalid ICAP messages should
+ * be handled prior to this point.
+ */
assert(reply); // check that ICAP xaction created the right object
httpState->takeAdaptedHeaders(reply);
break;
case 200:
- handle200Ok();
+
+ if (!validate200Ok()) {
+ throw TexcHere("Invalid ICAP Response");
+ } else {
+ handle200Ok();
+ }
+
break;
case 204:
break;
default:
+ debugs(93, 5, HERE << "ICAP status " << icapReply->sline.status);
handleUnknownScode();
break;
}
// TODO: Consider applying a Squid 2.5 patch to recognize 201 responses
}
+bool ICAPModXact::validate200Ok()
+{
+ if (ICAP::methodRespmod == service().method) {
+ if (!gotEncapsulated("res-hdr"))
+ return false;
+
+ return true;
+ }
+
+ if (ICAP::methodReqmod == service().method) {
+ if (!gotEncapsulated("res-hdr") && !gotEncapsulated("req-hdr"))
+ return false;
+
+ return true;
+ }
+
+ return false;
+}
+
void ICAPModXact::handle100Continue()
{
Must(state.writing == State::writingPaused);
if (!parsePresentBody()) // need more body data
return;
} else {
- debugs(93, 5, "not expecting a body");
+ debugs(93, 5, HERE << "not expecting a body");
}
stopParsing();
/*
- * $Id: ICAPModXact.h,v 1.3 2005/12/22 22:26:31 wessels Exp $
+ * $Id: ICAPModXact.h,v 1.4 2005/12/22 23:09:09 wessels Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
void maybeAllocateHttpMsg();
void handle100Continue();
+ bool validate200Ok();
void handle200Ok();
void handle204NoContent();
void handleUnknownScode();
/*
- * $Id: http.cc,v 1.472 2005/12/13 23:37:39 wessels Exp $
+ * $Id: http.cc,v 1.473 2005/12/22 23:09:09 wessels Exp $
*
* DEBUG: section 11 Hypertext Transfer Protocol (HTTP)
* AUTHOR: Harvest Derived
return;
}
+ assert (rep);
storeEntryReplaceObject(entry, rep);
/*
{
debug(11,5)("HttpStateData::doneAdapting() called\n");
+ /*
+ * ICAP is done, so we don't need this any more.
+ */
+ delete icap;
+ cbdataReferenceDone(icap);
+
if (!entry->isAccepting()) {
debug(11,5)("\toops, entry is not Accepting!\n");
icap->ownerAbort();
fwdComplete(fwd);
}
- assert(fd == -1);
- httpStateFree(-1, this);
+ if (fd >= 0)
+ comm_close(fd);
+ else
+ httpStateFree(fd, this);
}
void
{
debug(11,5)("HttpStateData::abortAdapting() called\n");
+ /*
+ * ICAP has given up, we're done with it too
+ */
+ delete icap;
+ cbdataReferenceDone(icap);
+
if (entry->isEmpty()) {
ErrorState *err;
err = errorCon(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR);
err->request = requestLink((HttpRequest *) request);
err->xerrno = errno;
fwdFail(fwd, err);
+ fwd->flags.dont_retry = 1;
flags.do_next_read = 0;
+
+ if (fd >= 0) {
+ comm_close(fd);
+ } else {
+ fwdComplete(fwd);
+ httpStateFree(-1, this); // deletes this
+ }
+
+ return;
}
- fwdComplete(fwd);
- if (fd >= 0)
- comm_close(fd);
- else
- httpStateFree(fd, this);
}
#endif