]>
Commit | Line | Data |
---|---|---|
be335c22 | 1 | |
30a4f2a8 | 2 | /* |
cc192b50 | 3 | * $Id: redirect.cc,v 1.123 2007/12/14 23:11:48 amosjeffries Exp $ |
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. | |
24 | * | |
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. | |
29 | * | |
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" | |
f5691f9c | 37 | #include "AuthUserRequest.h" |
62ee09ca | 38 | #include "CacheManager.h" |
e6ccf245 | 39 | #include "Store.h" |
472adb2f | 40 | #include "fde.h" |
528b2c61 | 41 | #include "client_side_request.h" |
4fb35c3c | 42 | #include "ACLChecklist.h" |
8000a965 | 43 | #include "HttpRequest.h" |
a46d2c0e | 44 | #include "client_side.h" |
aa839030 | 45 | #include "helper.h" |
30a4f2a8 | 46 | |
62e76326 | 47 | typedef struct |
48 | { | |
d2af9477 | 49 | void *data; |
30a4f2a8 | 50 | char *orig_url; |
62e76326 | 51 | |
cc192b50 | 52 | IPAddress client_addr; |
0ee4272b | 53 | const char *client_ident; |
54 | const char *method_s; | |
582b6456 | 55 | RH *handler; |
62e76326 | 56 | } |
57 | ||
58 | redirectStateData; | |
30a4f2a8 | 59 | |
74addf6c | 60 | static HLPCB redirectHandleReply; |
f5b8bbc4 | 61 | static void redirectStateFree(redirectStateData * r); |
74addf6c | 62 | static helper *redirectors = NULL; |
63 | static OBJH redirectStats; | |
07476a7f | 64 | static int n_bypassed = 0; |
28c60158 | 65 | CBDATA_TYPE(redirectStateData); |
30a4f2a8 | 66 | |
582b6456 | 67 | static void |
74addf6c | 68 | redirectHandleReply(void *data, char *reply) |
30a4f2a8 | 69 | { |
e6ccf245 | 70 | redirectStateData *r = static_cast<redirectStateData *>(data); |
74addf6c | 71 | char *t; |
fa80a8ef | 72 | void *cbdata; |
58523b80 | 73 | debugs(61, 5, "redirectHandleRead: {" << (reply && *reply != '\0' ? reply : "<NULL>") << "}"); |
62e76326 | 74 | |
c68e9c6b | 75 | if (reply) { |
62e76326 | 76 | if ((t = strchr(reply, ' '))) |
77 | *t = '\0'; | |
78 | ||
79 | if (*reply == '\0') | |
80 | reply = NULL; | |
c68e9c6b | 81 | } |
62e76326 | 82 | |
fa80a8ef | 83 | if (cbdataReferenceValidDone(r->data, &cbdata)) |
62e76326 | 84 | r->handler(cbdata, reply); |
85 | ||
74addf6c | 86 | redirectStateFree(r); |
30a4f2a8 | 87 | } |
88 | ||
e7a22b88 | 89 | static void |
90 | redirectStateFree(redirectStateData * r) | |
91 | { | |
92 | safe_free(r->orig_url); | |
74addf6c | 93 | cbdataFree(r); |
e7a22b88 | 94 | } |
95 | ||
b8d8561b | 96 | static void |
74addf6c | 97 | redirectStats(StoreEntry * sentry) |
30a4f2a8 | 98 | { |
587609e9 | 99 | if (redirectors == NULL) { |
100 | storeAppendPrintf(sentry, "No redirectors defined\n"); | |
101 | return; | |
102 | } | |
103 | ||
9522b380 | 104 | helperStats(sentry, redirectors, "Redirector Statistics"); |
62e76326 | 105 | |
07476a7f | 106 | if (Config.onoff.redirector_bypass) |
62e76326 | 107 | storeAppendPrintf(sentry, "\nNumber of requests bypassed " |
108 | "because all redirectors were busy: %d\n", n_bypassed); | |
30a4f2a8 | 109 | } |
110 | ||
d2af9477 | 111 | /**** PUBLIC FUNCTIONS ****/ |
112 | ||
b8d8561b | 113 | void |
59a1efb2 | 114 | redirectStart(ClientHttpRequest * http, RH * handler, void *data) |
d2af9477 | 115 | { |
a2ac85d9 | 116 | ConnStateData::Pointer conn = http->getConn(); |
d2af9477 | 117 | redirectStateData *r = NULL; |
74addf6c | 118 | const char *fqdn; |
119 | char buf[8192]; | |
cc192b50 | 120 | char claddr[MAX_IPSTRLEN]; |
121 | char myaddr[MAX_IPSTRLEN]; | |
74addf6c | 122 | assert(http); |
123 | assert(handler); | |
bf8fe701 | 124 | debugs(61, 5, "redirectStart: '" << http->uri << "'"); |
62e76326 | 125 | |
07476a7f | 126 | if (Config.onoff.redirector_bypass && redirectors->stats.queue_size) { |
62e76326 | 127 | /* Skip redirector if there is one request queued */ |
128 | n_bypassed++; | |
129 | handler(data, NULL); | |
130 | return; | |
07476a7f | 131 | } |
62e76326 | 132 | |
72711e31 | 133 | r = cbdataAlloc(redirectStateData); |
23d92c64 | 134 | r->orig_url = xstrdup(http->uri); |
cc192b50 | 135 | if(conn != NULL) |
136 | r->client_addr = conn->log_addr; | |
137 | else | |
138 | r->client_addr.SetNoAddr(); | |
472adb2f | 139 | r->client_ident = NULL; |
62e76326 | 140 | |
94439e4e | 141 | if (http->request->auth_user_request) |
f5691f9c | 142 | r->client_ident = http->request->auth_user_request->username(); |
30abd221 | 143 | else if (http->request->extacl_user.buf() != NULL) { |
144 | r->client_ident = http->request->extacl_user.buf(); | |
472adb2f | 145 | } |
146 | ||
85a4b153 | 147 | if (!r->client_ident && (conn != NULL && conn->rfc931[0])) |
62e76326 | 148 | r->client_ident = conn->rfc931; |
472adb2f | 149 | |
150 | #if USE_SSL | |
151 | ||
85a4b153 | 152 | if (!r->client_ident && conn != NULL) |
472adb2f | 153 | r->client_ident = sslGetUserEmail(fd_table[conn->fd].ssl); |
154 | ||
155 | #endif | |
156 | ||
157 | if (!r->client_ident) | |
62e76326 | 158 | r->client_ident = dash_str; |
62e76326 | 159 | |
382d851a | 160 | r->method_s = RequestMethodStr[http->request->method]; |
472adb2f | 161 | |
d2af9477 | 162 | r->handler = handler; |
472adb2f | 163 | |
fa80a8ef | 164 | r->data = cbdataReference(data); |
62e76326 | 165 | |
74addf6c | 166 | if ((fqdn = fqdncache_gethostbyaddr(r->client_addr, 0)) == NULL) |
62e76326 | 167 | fqdn = dash_str; |
168 | ||
c71adec1 | 169 | snprintf(buf, 8192, "%s %s/%s %s %s myip=%s myport=%d\n", |
62e76326 | 170 | r->orig_url, |
cc192b50 | 171 | r->client_addr.NtoA(claddr,MAX_IPSTRLEN), |
62e76326 | 172 | fqdn, |
5ce4b8cc | 173 | r->client_ident[0] ? rfc1738_escape(r->client_ident) : dash_str, |
c71adec1 | 174 | r->method_s, |
cc192b50 | 175 | http->request->my_addr.NtoA(myaddr,MAX_IPSTRLEN), |
176 | http->request->my_addr.GetPort()); | |
62e76326 | 177 | |
74addf6c | 178 | helperSubmit(redirectors, buf, redirectHandleReply, r); |
0a21bd84 | 179 | } |
180 | ||
b8d8561b | 181 | void |
74addf6c | 182 | redirectInit(void) |
30a4f2a8 | 183 | { |
74addf6c | 184 | static int init = 0; |
62e76326 | 185 | |
74addf6c | 186 | if (!Config.Program.redirect) |
62e76326 | 187 | return; |
188 | ||
838b993c | 189 | if (redirectors == NULL) |
62e76326 | 190 | redirectors = helperCreate("redirector"); |
191 | ||
c6d5b87b | 192 | redirectors->cmdline = Config.Program.redirect; |
62e76326 | 193 | |
74addf6c | 194 | redirectors->n_to_start = Config.redirectChildren; |
62e76326 | 195 | |
07eca7e0 | 196 | redirectors->concurrency = Config.redirectConcurrency; |
197 | ||
1ccc0d40 | 198 | redirectors->ipc_type = IPC_STREAM; |
62e76326 | 199 | |
74addf6c | 200 | helperOpenServers(redirectors); |
62e76326 | 201 | |
74addf6c | 202 | if (!init) { |
62e76326 | 203 | init = 1; |
204 | CBDATA_INIT_TYPE(redirectStateData); | |
d2af9477 | 205 | } |
30a4f2a8 | 206 | } |
207 | ||
62ee09ca | 208 | void |
209 | redirectRegisterWithCacheManager(CacheManager & manager) | |
210 | { | |
211 | manager.registerAction("redirector", | |
212 | "URL Redirector Stats", | |
213 | redirectStats, 0, 1); | |
214 | } | |
215 | ||
16d3fe0d | 216 | void |
74addf6c | 217 | redirectShutdown(void) |
30a4f2a8 | 218 | { |
74addf6c | 219 | if (!redirectors) |
62e76326 | 220 | return; |
221 | ||
74addf6c | 222 | helperShutdown(redirectors); |
62e76326 | 223 | |
838b993c | 224 | if (!shutting_down) |
62e76326 | 225 | return; |
226 | ||
1f5f60dd | 227 | helperFree(redirectors); |
62e76326 | 228 | |
1f5f60dd | 229 | redirectors = NULL; |
30a4f2a8 | 230 | } |