/*
- * $Id: http.cc,v 1.408 2003/02/13 22:20:37 robertc Exp $
+ * $Id: http.cc,v 1.409 2003/02/15 00:15:51 hno Exp $
*
* DEBUG: section 11 Hypertext Transfer Protocol (HTTP)
* AUTHOR: Harvest Derived
static int httpCachableReply(HttpStateData *);
static void httpMaybeRemovePublic(StoreEntry *, http_status);
static void copyOneHeaderFromClientsideRequestToUpstreamRequest(const HttpHeaderEntry *e, String strConnection, request_t * request, request_t * orig_request,
-HttpHeader * hdr_out, int we_do_ranges, bool);
+HttpHeader * hdr_out, int we_do_ranges, http_state_flags);
static int decideIfWeDoRanges (request_t * orig_request);
strConnection = httpHeaderGetList(hdr_in, HDR_CONNECTION);
while ((e = httpHeaderGetEntry(hdr_in, &pos)))
- copyOneHeaderFromClientsideRequestToUpstreamRequest(e, strConnection, request, orig_request, hdr_out, we_do_ranges, flags.front_end_https);
+ copyOneHeaderFromClientsideRequestToUpstreamRequest(e, strConnection, request, orig_request, hdr_out, we_do_ranges, flags);
/* Abstraction break: We should interpret myultipart/byterange responses
* into offset-length data, and this works around our inability to do so.
/* append Host if not there already */
if (!httpHeaderHas(hdr_out, HDR_HOST)) {
- /* use port# only if not default */
- if (orig_request->port == urlDefaultPort(orig_request->protocol)) {
+ if (orig_request->peer_domain) {
+ httpHeaderPutStr(hdr_out, HDR_HOST, orig_request->peer_domain);
+ } else if (orig_request->port == urlDefaultPort(orig_request->protocol)) {
+ /* use port# only if not default */
httpHeaderPutStr(hdr_out, HDR_HOST, orig_request->host);
} else {
httpHeaderPutStrf(hdr_out, HDR_HOST, "%s:%d",
}
/* append Proxy-Authorization if configured for peer, and proxying */
if (request->flags.proxying && orig_request->peer_login &&
- !httpHeaderHas(hdr_out, HDR_PROXY_AUTHORIZATION) &&
- strcmp(orig_request->peer_login, "PASS") != 0) {
+ !httpHeaderHas(hdr_out, HDR_PROXY_AUTHORIZATION)) {
if (*orig_request->peer_login == '*') {
/* Special mode, to pass the username to the upstream cache */
char loginbuf[256];
snprintf(loginbuf, sizeof(loginbuf), "%s%s", username, orig_request->peer_login + 1);
httpHeaderPutStrf(hdr_out, HDR_PROXY_AUTHORIZATION, "Basic %s",
base64_encode(loginbuf));
+ } else if (strcmp(orig_request->peer_login, "PASS") == 0) {
+ /* Nothing to do */
+ } else if (strcmp(orig_request->peer_login, "PROXYPASS") == 0) {
+ /* Nothing to do */
} else {
httpHeaderPutStrf(hdr_out, HDR_PROXY_AUTHORIZATION, "Basic %s",
base64_encode(orig_request->peer_login));
}
}
+ /* append WWW-Authorization if configured for peer */
+ if (flags.originpeer && orig_request->peer_login &&
+ !httpHeaderHas(hdr_out, HDR_AUTHORIZATION)) {
+ if (strcmp(orig_request->peer_login, "PASS") == 0) {
+ /* No credentials to forward.. (should have been done above if available) */
+ } else if (strcmp(orig_request->peer_login, "PROXYPASS") == 0) {
+ /* Special mode, convert proxy authentication to WWW authentication
+ */
+ const char *auth = httpHeaderGetStr(hdr_in, HDR_PROXY_AUTHORIZATION);
+ if (auth && strncasecmp(auth, "basic ", 6) == 0) {
+ httpHeaderPutStr(hdr_out, HDR_AUTHORIZATION, auth);
+ }
+ } else if (*orig_request->peer_login == '*') {
+ /* Special mode, to pass the username to the upstream cache */
+ char loginbuf[256];
+ const char *username = "-";
+ if (orig_request->auth_user_request)
+ username = authenticateUserRequestUsername(orig_request->auth_user_request);
+ snprintf(loginbuf, sizeof(loginbuf), "%s%s", username, orig_request->peer_login + 1);
+ httpHeaderPutStrf(hdr_out, HDR_AUTHORIZATION, "Basic %s",
+ base64_encode(loginbuf));
+ } else {
+ /* Fixed login string */
+ httpHeaderPutStrf(hdr_out, HDR_AUTHORIZATION, "Basic %s",
+ base64_encode(orig_request->peer_login));
+ }
+ }
/* append Cache-Control, add max-age if not there already */
{
HttpHdrCc *cc = httpHeaderGetCc(hdr_in);
void
-copyOneHeaderFromClientsideRequestToUpstreamRequest(const HttpHeaderEntry *e, String strConnection, request_t * request, request_t * orig_request, HttpHeader * hdr_out, int we_do_ranges, bool front_end_https)
+copyOneHeaderFromClientsideRequestToUpstreamRequest(const HttpHeaderEntry *e, String strConnection, request_t * request, request_t * orig_request, HttpHeader * hdr_out, int we_do_ranges, http_state_flags flags)
{
debug(11, 5) ("httpBuildRequestHeader: %s: %s\n",
e->name.buf(), e->value.buf());
return;
}
switch (e->id) {
- case HDR_PROXY_AUTHORIZATION:
- /* Only pass on proxy authentication to peers for which
- * authentication forwarding is explicitly enabled
- */
- if (request->flags.proxying && orig_request->peer_login &&
- strcmp(orig_request->peer_login, "PASS") == 0) {
- httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
- }
- break;
- case HDR_AUTHORIZATION:
- /* Pass on WWW authentication even if used locally. If this is
- * not wanted in an accelerator then the header can be removed
- * using the anonymization functions
- */
- httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
- /* XXX Some accelerators might want to strip the header
- * and regard the reply as cacheable, but authentication
- * is not normally enabled for accelerators without reading
- * the code, so there is not much use in adding logics here
- * without first defining the concept of having authentication
- * in the accelerator...
- */
- break;
- case HDR_HOST:
- /*
- * Normally Squid does not copy the Host: header from
- * a client request into the forwarded request headers.
- * However, there is one case when we do: If the URL
- * went through our redirector and the admin configured
- * 'redir_rewrites_host' to be off.
- */
- if (request->flags.redirected)
- if (!Config.onoff.redir_rewrites_host)
- httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
- break;
- case HDR_IF_MODIFIED_SINCE:
- /* append unless we added our own;
- * note: at most one client's ims header can pass through */
- if (!httpHeaderHas(hdr_out, HDR_IF_MODIFIED_SINCE))
- httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
- break;
- case HDR_MAX_FORWARDS:
- if (orig_request->method == METHOD_TRACE) {
- const int hops = httpHeaderEntryGetInt(e);
- if (hops > 0)
- httpHeaderPutInt(hdr_out, HDR_MAX_FORWARDS, hops - 1);
- }
- break;
- case HDR_VIA:
- /* If Via is disabled then forward any received header as-is */
- if (!Config.onoff.via)
- httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
- break;
- case HDR_RANGE:
- case HDR_IF_RANGE:
- case HDR_REQUEST_RANGE:
- if (!we_do_ranges)
- httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
- break;
- case HDR_PROXY_CONNECTION:
- case HDR_CONNECTION:
- case HDR_X_FORWARDED_FOR:
- case HDR_CACHE_CONTROL:
- /* append these after the loop if needed */
- break;
- case HDR_FRONT_END_HTTPS:
- if (!front_end_https)
- httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
- break;
- default:
- /* pass on all other header fields */
- httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
+ case HDR_PROXY_AUTHORIZATION:
+ /* Only pass on proxy authentication to peers for which
+ * authentication forwarding is explicitly enabled
+ */
+ if (flags.proxying && orig_request->peer_login &&
+ strcmp(orig_request->peer_login, "PASS") == 0) {
+ httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
+ }
+ break;
+ case HDR_AUTHORIZATION:
+ /* Pass on WWW authentication */
+ if (!flags.originpeer) {
+ httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
+ } else {
+ /* In accelerators, only forward authentication if enabled
+ * (see also below for proxy->server authentication)
+ */
+ if (orig_request->peer_login && (strcmp(orig_request->peer_login, "PASS") == 0 || strcmp(orig_request->peer_login, "PROXYPASS") == 0)) {
+ httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
+ }
+ }
+ break;
+ case HDR_HOST:
+ /*
+ * Normally Squid does not copy the Host: header from
+ * a client request into the forwarded request headers.
+ * However, there is one case when we do: If the URL
+ * went through our redirector and the admin configured
+ * 'redir_rewrites_host' to be off.
+ */
+ if (request->flags.redirected)
+ if (!Config.onoff.redir_rewrites_host)
+ httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
+ break;
+ case HDR_IF_MODIFIED_SINCE:
+ /* append unless we added our own;
+ * note: at most one client's ims header can pass through */
+ if (!httpHeaderHas(hdr_out, HDR_IF_MODIFIED_SINCE))
+ httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
+ break;
+ case HDR_MAX_FORWARDS:
+ if (orig_request->method == METHOD_TRACE) {
+ const int hops = httpHeaderEntryGetInt(e);
+ if (hops > 0)
+ httpHeaderPutInt(hdr_out, HDR_MAX_FORWARDS, hops - 1);
+ }
+ break;
+ case HDR_VIA:
+ /* If Via is disabled then forward any received header as-is */
+ if (!Config.onoff.via)
+ httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
+ break;
+ case HDR_RANGE:
+ case HDR_IF_RANGE:
+ case HDR_REQUEST_RANGE:
+ if (!we_do_ranges)
+ httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
+ break;
+ case HDR_PROXY_CONNECTION:
+ case HDR_CONNECTION:
+ case HDR_X_FORWARDED_FOR:
+ case HDR_CACHE_CONTROL:
+ /* append these after the loop if needed */
+ break;
+ case HDR_FRONT_END_HTTPS:
+ if (!flags.front_end_https)
+ httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
+ break;
+ default:
+ /* pass on all other header fields */
+ httpHeaderAddEntry(hdr_out, httpHeaderEntryClone(e));
}
}
else
sendHeaderDone = HttpStateData::SendComplete;
- if (p != NULL)
- httpState->flags.proxying = 1;
- else
+ if (p != NULL) {
+ if (p->options.originserver) {
+ httpState->flags.proxying = 0;
+ httpState->flags.originpeer = 1;
+ } else {
+ httpState->flags.proxying = 1;
+ httpState->flags.originpeer = 0;
+ }
+ } else {
httpState->flags.proxying = 0;
+ httpState->flags.originpeer = 0;
+ }
/*
* Is keep-alive okay for all request methods?
*/
if (fwd->servers)
httpState->_peer = fwd->servers->_peer; /* might be NULL */
if (httpState->_peer) {
+ const char *url;
+ if (httpState->_peer->options.originserver)
+ url = orig_req->urlpath.buf();
+ else
+ url = storeUrl(httpState->entry);
proxy_req = requestCreate(orig_req->method,
- orig_req->protocol, storeUrl(httpState->entry));
+ orig_req->protocol, url);
xstrncpy(proxy_req->host, httpState->_peer->host, SQUIDHOSTNAMELEN);
proxy_req->port = httpState->_peer->http_port;
proxy_req->flags = orig_req->flags;
/*
- * $Id: neighbors.cc,v 1.312 2003/02/13 20:52:42 wessels Exp $
+ * $Id: neighbors.cc,v 1.313 2003/02/15 00:15:51 hno Exp $
*
* DEBUG: section 15 Neighbor Routines
* AUTHOR: Harvest Derived
/* Neighbor is dead; ping it anyway, but don't expect a reply */
/* log it once at the threshold */
if (p->stats.logged_state == PEER_ALIVE) {
- debug(15, 1) ("Detected DEAD %s: %s/%d/%d\n",
- neighborTypeStr(p),
- p->host, p->http_port, p->icp.port);
+ debug(15, 1) ("Detected DEAD %s: %s\n",
+ neighborTypeStr(p), p->name);
p->stats.logged_state = PEER_DEAD;
}
}
neighborAlive(peer * p, const MemObject * mem, const icp_common_t * header)
{
if (p->stats.logged_state == PEER_DEAD && p->tcp_up) {
- debug(15, 1) ("Detected REVIVED %s: %s/%d/%d\n",
- neighborTypeStr(p),
- p->host, p->http_port, p->icp.port);
+ debug(15, 1) ("Detected REVIVED %s: %s\n",
+ neighborTypeStr(p), p->name);
p->stats.logged_state = PEER_ALIVE;
}
p->stats.last_reply = squid_curtime;
neighborAliveHtcp(peer * p, const MemObject * mem, const htcpReplyData * htcp)
{
if (p->stats.logged_state == PEER_DEAD && p->tcp_up) {
- debug(15, 1) ("Detected REVIVED %s: %s/%d/%d\n",
- neighborTypeStr(p),
- p->host, p->http_port, p->icp.port);
+ debug(15, 1) ("Detected REVIVED %s: %s\n",
+ neighborTypeStr(p), p->name);
p->stats.logged_state = PEER_ALIVE;
}
p->stats.last_reply = squid_curtime;
{
peer *p = NULL;
for (p = Config.peers; p; p = p->next) {
- if (!strcasecmp(name, p->host))
+ if (!strcasecmp(name, p->name))
break;
}
return p;
{
peer *p = NULL;
for (p = Config.peers; p; p = p->next) {
- if (strcasecmp(name, p->host))
+ if (strcasecmp(name, p->name))
continue;
if (port != p->http_port)
continue;
safe_free(l);
}
safe_free(p->host);
+ safe_free(p->name);
+ safe_free(p->domain);
#if USE_CACHE_DIGESTS
cbdataReferenceDone(p->digest);
#endif
debug(15, 1) ("TCP connection to %s/%d failed\n", p->host, p->http_port);
p->tcp_up--;
if (!p->tcp_up) {
- debug(15, 1) ("Detected DEAD %s: %s/%d/%d\n",
- neighborTypeStr(p),
- p->host, p->http_port, p->icp.port);
+ debug(15, 1) ("Detected DEAD %s: %s\n",
+ neighborTypeStr(p), p->name);
p->stats.logged_state = PEER_DEAD;
}
}
{
if (!p->tcp_up) {
debug(15, 2) ("TCP connection to %s/%d succeded\n", p->host, p->http_port);
- debug(15, 1) ("Detected REVIVED %s: %s/%d/%d\n",
- neighborTypeStr(p),
- p->host, p->http_port, p->icp.port);
+ debug(15, 1) ("Detected REVIVED %s: %s\n",
+ neighborTypeStr(p), p->name);
p->stats.logged_state = PEER_ALIVE;
}
p->tcp_up = PEER_TCP_MAGIC_COUNT;
storeAppendPrintf(sentry, " login=%s", p->login);
if (p->mcast.ttl > 0)
storeAppendPrintf(sentry, " ttl=%d", p->mcast.ttl);
+ if (p->connect_timeout > 0)
+ storeAppendPrintf(sentry, " connect-timeout=%d", (int) p->connect_timeout);
+#if USE_CACHE_DIGESTS
+ if (p->digest_url)
+ storeAppendPrintf(sentry, " digest-url=%s", p->digest_url);
+#endif
+ if (p->options.allow_miss)
+ storeAppendPrintf(sentry, " allow-miss");
+ if (p->max_conn > 0)
+ storeAppendPrintf(sentry, " max-conn=%d", p->max_conn);
+ if (p->options.originserver)
+ storeAppendPrintf(sentry, " originserver");
+ if (p->domain)
+ storeAppendPrintf(sentry, " forceddomain=%s", p->domain);
storeAppendPrintf(sentry, "\n");
}
storeAppendPrintf(sentry, "There are no neighbors installed.\n");
for (e = peers; e; e = e->next) {
assert(e->host != NULL);
- storeAppendPrintf(sentry, "\n%-11.11s: %s/%d/%d\n",
+ storeAppendPrintf(sentry, "\n%-11.11s: %s\n",
neighborTypeStr(e),
+ e->name);
+ storeAppendPrintf(sentry, "Host : %s/%d/%d\n",
e->host,
e->http_port,
e->icp.port);