]> git.ipfire.org Git - thirdparty/squid.git/blame - src/redirect.cc
UnitTests: check precompiler is sane with our wrapping style.
[thirdparty/squid.git] / src / redirect.cc
CommitLineData
be335c22 1
30a4f2a8 2/*
262a0e14 3 * $Id$
30a4f2a8 4 *
17bb3486 5 * DEBUG: section 61 Redirector
30a4f2a8 6 * AUTHOR: Duane Wessels
7 *
2b6662ba 8 * SQUID Web Proxy Cache http://www.squid-cache.org/
e25c139f 9 * ----------------------------------------------------------
30a4f2a8 10 *
2b6662ba 11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
30a4f2a8 19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
26ac0430 24 *
30a4f2a8 25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
26ac0430 29 *
30a4f2a8 30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
cbdec147 32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
e25c139f 33 *
30a4f2a8 34 */
35
36#include "squid.h"
2d2b0bb7 37#include "auth/UserRequest.h"
62ee09ca 38#include "CacheManager.h"
e6ccf245 39#include "Store.h"
472adb2f 40#include "fde.h"
528b2c61 41#include "client_side_request.h"
3ad63615 42#include "acl/Checklist.h"
8000a965 43#include "HttpRequest.h"
a46d2c0e 44#include "client_side.h"
aa839030 45#include "helper.h"
30a4f2a8 46
26ac0430 47typedef struct {
d2af9477 48 void *data;
30a4f2a8 49 char *orig_url;
62e76326 50
ad61a2b4 51 IpAddress client_addr;
0ee4272b 52 const char *client_ident;
53 const char *method_s;
582b6456 54 RH *handler;
2fadd50d 55} redirectStateData;
30a4f2a8 56
74addf6c 57static HLPCB redirectHandleReply;
f5b8bbc4 58static void redirectStateFree(redirectStateData * r);
74addf6c 59static helper *redirectors = NULL;
60static OBJH redirectStats;
07476a7f 61static int n_bypassed = 0;
28c60158 62CBDATA_TYPE(redirectStateData);
30a4f2a8 63
582b6456 64static void
74addf6c 65redirectHandleReply(void *data, char *reply)
30a4f2a8 66{
e6ccf245 67 redirectStateData *r = static_cast<redirectStateData *>(data);
74addf6c 68 char *t;
fa80a8ef 69 void *cbdata;
58523b80 70 debugs(61, 5, "redirectHandleRead: {" << (reply && *reply != '\0' ? reply : "<NULL>") << "}");
62e76326 71
c68e9c6b 72 if (reply) {
62e76326 73 if ((t = strchr(reply, ' ')))
74 *t = '\0';
75
76 if (*reply == '\0')
77 reply = NULL;
c68e9c6b 78 }
62e76326 79
fa80a8ef 80 if (cbdataReferenceValidDone(r->data, &cbdata))
62e76326 81 r->handler(cbdata, reply);
82
74addf6c 83 redirectStateFree(r);
30a4f2a8 84}
85
e7a22b88 86static void
87redirectStateFree(redirectStateData * r)
88{
89 safe_free(r->orig_url);
74addf6c 90 cbdataFree(r);
e7a22b88 91}
92
b8d8561b 93static void
74addf6c 94redirectStats(StoreEntry * sentry)
30a4f2a8 95{
587609e9 96 if (redirectors == NULL) {
97 storeAppendPrintf(sentry, "No redirectors defined\n");
98 return;
99 }
100
9522b380 101 helperStats(sentry, redirectors, "Redirector Statistics");
62e76326 102
07476a7f 103 if (Config.onoff.redirector_bypass)
62e76326 104 storeAppendPrintf(sentry, "\nNumber of requests bypassed "
105 "because all redirectors were busy: %d\n", n_bypassed);
30a4f2a8 106}
107
d2af9477 108/**** PUBLIC FUNCTIONS ****/
109
b8d8561b 110void
59a1efb2 111redirectStart(ClientHttpRequest * http, RH * handler, void *data)
d2af9477 112{
9512de47 113 ConnStateData * conn = http->getConn();
d2af9477 114 redirectStateData *r = NULL;
74addf6c 115 const char *fqdn;
116 char buf[8192];
cc192b50 117 char claddr[MAX_IPSTRLEN];
118 char myaddr[MAX_IPSTRLEN];
74addf6c 119 assert(http);
120 assert(handler);
bf8fe701 121 debugs(61, 5, "redirectStart: '" << http->uri << "'");
62e76326 122
07476a7f 123 if (Config.onoff.redirector_bypass && redirectors->stats.queue_size) {
62e76326 124 /* Skip redirector if there is one request queued */
125 n_bypassed++;
126 handler(data, NULL);
127 return;
07476a7f 128 }
62e76326 129
72711e31 130 r = cbdataAlloc(redirectStateData);
23d92c64 131 r->orig_url = xstrdup(http->uri);
26ac0430 132 if (conn != NULL)
cc192b50 133 r->client_addr = conn->log_addr;
134 else
135 r->client_addr.SetNoAddr();
472adb2f 136 r->client_ident = NULL;
62e76326 137
94439e4e 138 if (http->request->auth_user_request)
f5691f9c 139 r->client_ident = http->request->auth_user_request->username();
b4f2886c
FC
140 else if (http->request->extacl_user.defined()) {
141 r->client_ident = http->request->extacl_user.termedBuf();
472adb2f 142 }
143
85a4b153 144 if (!r->client_ident && (conn != NULL && conn->rfc931[0]))
62e76326 145 r->client_ident = conn->rfc931;
472adb2f 146
147#if USE_SSL
148
85a4b153 149 if (!r->client_ident && conn != NULL)
472adb2f 150 r->client_ident = sslGetUserEmail(fd_table[conn->fd].ssl);
151
152#endif
153
154 if (!r->client_ident)
62e76326 155 r->client_ident = dash_str;
62e76326 156
60745f24 157 r->method_s = RequestMethodStr(http->request->method);
472adb2f 158
d2af9477 159 r->handler = handler;
472adb2f 160
fa80a8ef 161 r->data = cbdataReference(data);
62e76326 162
74addf6c 163 if ((fqdn = fqdncache_gethostbyaddr(r->client_addr, 0)) == NULL)
62e76326 164 fqdn = dash_str;
165
c71adec1 166 snprintf(buf, 8192, "%s %s/%s %s %s myip=%s myport=%d\n",
62e76326 167 r->orig_url,
cc192b50 168 r->client_addr.NtoA(claddr,MAX_IPSTRLEN),
62e76326 169 fqdn,
5ce4b8cc 170 r->client_ident[0] ? rfc1738_escape(r->client_ident) : dash_str,
c71adec1 171 r->method_s,
cc192b50 172 http->request->my_addr.NtoA(myaddr,MAX_IPSTRLEN),
173 http->request->my_addr.GetPort());
62e76326 174
74addf6c 175 helperSubmit(redirectors, buf, redirectHandleReply, r);
0a21bd84 176}
177
5f5e883f
FC
178static void
179redirectRegisterWithCacheManager(void)
180{
181 CacheManager::GetInstance()->
26ac0430 182 registerAction("redirector", "URL Redirector Stats", redirectStats, 0, 1);
5f5e883f
FC
183}
184
b8d8561b 185void
74addf6c 186redirectInit(void)
30a4f2a8 187{
74addf6c 188 static int init = 0;
62e76326 189
d120ed12
FC
190 redirectRegisterWithCacheManager();
191
74addf6c 192 if (!Config.Program.redirect)
62e76326 193 return;
194
838b993c 195 if (redirectors == NULL)
62e76326 196 redirectors = helperCreate("redirector");
197
c6d5b87b 198 redirectors->cmdline = Config.Program.redirect;
62e76326 199
74addf6c 200 redirectors->n_to_start = Config.redirectChildren;
62e76326 201
07eca7e0 202 redirectors->concurrency = Config.redirectConcurrency;
203
1ccc0d40 204 redirectors->ipc_type = IPC_STREAM;
62e76326 205
74addf6c 206 helperOpenServers(redirectors);
62e76326 207
74addf6c 208 if (!init) {
62e76326 209 init = 1;
210 CBDATA_INIT_TYPE(redirectStateData);
d2af9477 211 }
30a4f2a8 212}
213
16d3fe0d 214void
74addf6c 215redirectShutdown(void)
30a4f2a8 216{
74addf6c 217 if (!redirectors)
62e76326 218 return;
219
74addf6c 220 helperShutdown(redirectors);
62e76326 221
838b993c 222 if (!shutting_down)
62e76326 223 return;
224
1f5f60dd 225 helperFree(redirectors);
62e76326 226
1f5f60dd 227 redirectors = NULL;
30a4f2a8 228}