#include "fde.h"
#include "HttpReply.h"
#include "HttpRequest.h"
+#include "ip/QosConfig.h"
#include "MemObject.h"
#include "ProtoPort.h"
#include "Store.h"
#include "SquidTime.h"
#include "wordlist.h"
+#include "err_detail_type.h"
#if LINGERING_CLOSE
{
start_time = current_time;
setConn(aConn);
+ clientConnection = aConn->clientConn;
dlinkAdd(this, &active, &ClientActiveRequests);
#if USE_ADAPTATION
request_satisfaction_mode = false;
if (calloutContext)
delete calloutContext;
+ clientConnection = NULL;
+
if (conn_)
cbdataReferenceDone(conn_);
tmpnoaddr.SetNoAddr();
repContext->setReplyToError(page_id, status,
http->request->method, NULL,
- http->getConn() != NULL ? http->getConn()->peer : tmpnoaddr,
+ http->getConn() != NULL ? http->getConn()->clientConn->remote : tmpnoaddr,
http->request,
NULL,
http->getConn() != NULL && http->getConn()->auth_user_request != NULL ?
if ((t = strchr(result, ':')) != NULL) {
http->redirect.status = status;
http->redirect.location = xstrdup(t + 1);
+ // TODO: validate the URL produced here is RFC 2616 compliant absolute URI
} else {
- debugs(85, 1, "clientRedirectDone: bad input: " << result);
+ if (old_request->http_ver < HttpVersion(1,1))
+ debugs(85, DBG_CRITICAL, "ERROR: URL-rewrite produces invalid 302 redirect Location: " << result);
+ else
+ debugs(85, DBG_CRITICAL, "ERROR: URL-rewrite produces invalid 303 redirect Location: " << result);
}
- } else if (strcmp(result, http->uri))
- new_request = HttpRequest::CreateFromUrlAndMethod(result, old_request->method);
+ } else if (strcmp(result, http->uri)) {
+ if (!(new_request = HttpRequest::CreateFromUrlAndMethod(result, old_request->method)))
+ debugs(85, DBG_CRITICAL, "ERROR: URL-rewrite produces invalid request: " <<
+ old_request->method << " " << result << " HTTP/1.1");
+ }
}
if (new_request) {
// called when comm_write has completed
static void
-SslBumpEstablish(int, char *, size_t, comm_err_t errflag, int, void *data)
+SslBumpEstablish(const Comm::ConnectionPointer &, char *, size_t, comm_err_t errflag, int, void *data)
{
ClientHttpRequest *r = static_cast<ClientHttpRequest*>(data);
debugs(85, 5, HERE << "responded to CONNECT: " << r << " ? " << errflag);
debugs(33, 7, HERE << "Confirming CONNECT tunnel on FD " << getConn()->clientConn);
// TODO: Unify with tunnel.cc and add a Server(?) header
- static const char *const conn_established =
- "HTTP/1.0 200 Connection established\r\n\r\n";
- comm_write(getConn()->clientConn->fd, conn_established, strlen(conn_established),
- &SslBumpEstablish, this, NULL);
+ static const char *const conn_established = "HTTP/1.0 200 Connection established\r\n\r\n";
+ comm_write(getConn()->clientConn, conn_established, strlen(conn_established), &SslBumpEstablish, this, NULL);
}
#endif
* the callout. This is strictly for convenience.
*/
-extern int aclMapTOS (acl_tos * head, ACLChecklist * ch);
+extern tos_t aclMapTOS (acl_tos * head, ACLChecklist * ch);
+extern nfmark_t aclMapNfmark (acl_nfmark * head, ACLChecklist * ch);
void
ClientHttpRequest::doCallouts()
}
}
- if (!calloutContext->clientside_tos_done) {
- calloutContext->clientside_tos_done = true;
+ if (!calloutContext->tosToClientDone) {
+ calloutContext->tosToClientDone = true;
if (getConn() != NULL && Comm::IsConnOpen(getConn()->clientConn)) {
ACLFilledChecklist ch(NULL, request, NULL);
ch.src_addr = request->client_addr;
ch.my_addr = request->my_addr;
- int tos = aclMapTOS(Config.accessList.clientside_tos, &ch);
+ tos_t tos = aclMapTOS(Ip::Qos::TheConfig.tosToClient, &ch);
if (tos)
- comm_set_tos(getConn()->clientConn->fd, tos);
+ Ip::Qos::setSockTos(getConn()->clientConn, tos);
+ }
+ }
+
+ if (!calloutContext->nfmarkToClientDone) {
+ calloutContext->nfmarkToClientDone = true;
+ if (getConn() != NULL && Comm::IsConnOpen(getConn()->clientConn)) {
+ ACLFilledChecklist ch(NULL, request, NULL);
+ ch.src_addr = request->client_addr;
+ ch.my_addr = request->my_addr;
+ nfmark_t mark = aclMapNfmark(Ip::Qos::TheConfig.nfmarkToClient, &ch);
+ if (mark)
+ Ip::Qos::setSockNfmark(getConn()->clientConn, mark);
}
}
{
clearAdaptation(virginHeadSource);
assert(!adaptedBodySource);
- handleAdaptationFailure(!final);
+ handleAdaptationFailure(ERR_DETAIL_ICAP_REQMOD_ABORT, !final);
}
void
{
assert(!virginHeadSource);
stopConsumingFrom(adaptedBodySource);
- handleAdaptationFailure();
+ handleAdaptationFailure(ERR_DETAIL_ICAP_RESPMOD_CLT_SIDE_BODY);
}
void
-ClientHttpRequest::handleAdaptationFailure(bool bypassable)
+ClientHttpRequest::handleAdaptationFailure(int errDetail, bool bypassable)
{
debugs(85,3, HERE << "handleAdaptationFailure(" << bypassable << ")");
ConnStateData * c = getConn();
repContext->setReplyToError(ERR_ICAP_FAILURE, HTTP_INTERNAL_SERVER_ERROR,
request->method, NULL,
- (c != NULL ? c->peer : noAddr), request, NULL,
+ (c != NULL ? c->clientConn->remote : noAddr), request, NULL,
(c != NULL && c->auth_user_request != NULL ?
c->auth_user_request : request->auth_user_request));
+ request->detailError(ERR_ICAP_FAILURE, errDetail);
+
node = (clientStreamNode *)client_stream.tail->data;
clientStreamRead(node, this, node->readBuffer);
}