]>
Commit | Line | Data |
---|---|---|
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 | 47 | typedef 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 | 57 | static HLPCB redirectHandleReply; |
f5b8bbc4 | 58 | static void redirectStateFree(redirectStateData * r); |
74addf6c | 59 | static helper *redirectors = NULL; |
60 | static OBJH redirectStats; | |
07476a7f | 61 | static int n_bypassed = 0; |
28c60158 | 62 | CBDATA_TYPE(redirectStateData); |
30a4f2a8 | 63 | |
582b6456 | 64 | static void |
74addf6c | 65 | redirectHandleReply(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 | 86 | static void |
87 | redirectStateFree(redirectStateData * r) | |
88 | { | |
89 | safe_free(r->orig_url); | |
74addf6c | 90 | cbdataFree(r); |
e7a22b88 | 91 | } |
92 | ||
b8d8561b | 93 | static void |
74addf6c | 94 | redirectStats(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 | 110 | void |
59a1efb2 | 111 | redirectStart(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 |
178 | static void |
179 | redirectRegisterWithCacheManager(void) | |
180 | { | |
181 | CacheManager::GetInstance()-> | |
26ac0430 | 182 | registerAction("redirector", "URL Redirector Stats", redirectStats, 0, 1); |
5f5e883f FC |
183 | } |
184 | ||
b8d8561b | 185 | void |
74addf6c | 186 | redirectInit(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 | 214 | void |
74addf6c | 215 | redirectShutdown(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 | } |