]> git.ipfire.org Git - thirdparty/squid.git/blob - src/redirect.cc
SMP Cache Manager, Phase2 implementation.
[thirdparty/squid.git] / src / redirect.cc
1
2 /*
3 * $Id$
4 *
5 * DEBUG: section 61 Redirector
6 * AUTHOR: Duane Wessels
7 *
8 * SQUID Web Proxy Cache http://www.squid-cache.org/
9 * ----------------------------------------------------------
10 *
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.
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
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
33 *
34 */
35
36 #include "squid.h"
37 #include "auth/UserRequest.h"
38 #include "mgr/Registration.h"
39 #include "Store.h"
40 #include "fde.h"
41 #include "client_side_request.h"
42 #include "acl/Checklist.h"
43 #include "HttpRequest.h"
44 #include "client_side.h"
45 #include "helper.h"
46 #include "rfc1738.h"
47
48 typedef struct {
49 void *data;
50 char *orig_url;
51
52 Ip::Address client_addr;
53 const char *client_ident;
54 const char *method_s;
55 RH *handler;
56 } redirectStateData;
57
58 static HLPCB redirectHandleReply;
59 static void redirectStateFree(redirectStateData * r);
60 static helper *redirectors = NULL;
61 static OBJH redirectStats;
62 static int n_bypassed = 0;
63 CBDATA_TYPE(redirectStateData);
64
65 static void
66 redirectHandleReply(void *data, char *reply)
67 {
68 redirectStateData *r = static_cast<redirectStateData *>(data);
69 char *t;
70 void *cbdata;
71 debugs(61, 5, "redirectHandleRead: {" << (reply && *reply != '\0' ? reply : "<NULL>") << "}");
72
73 if (reply) {
74 if ((t = strchr(reply, ' ')))
75 *t = '\0';
76
77 if (*reply == '\0')
78 reply = NULL;
79 }
80
81 if (cbdataReferenceValidDone(r->data, &cbdata))
82 r->handler(cbdata, reply);
83
84 redirectStateFree(r);
85 }
86
87 static void
88 redirectStateFree(redirectStateData * r)
89 {
90 safe_free(r->orig_url);
91 cbdataFree(r);
92 }
93
94 static void
95 redirectStats(StoreEntry * sentry)
96 {
97 if (redirectors == NULL) {
98 storeAppendPrintf(sentry, "No redirectors defined\n");
99 return;
100 }
101
102 helperStats(sentry, redirectors, "Redirector Statistics");
103
104 if (Config.onoff.redirector_bypass)
105 storeAppendPrintf(sentry, "\nNumber of requests bypassed "
106 "because all redirectors were busy: %d\n", n_bypassed);
107 }
108
109 /**** PUBLIC FUNCTIONS ****/
110
111 void
112 redirectStart(ClientHttpRequest * http, RH * handler, void *data)
113 {
114 ConnStateData * conn = http->getConn();
115 redirectStateData *r = NULL;
116 const char *fqdn;
117 char buf[8192];
118 char claddr[MAX_IPSTRLEN];
119 char myaddr[MAX_IPSTRLEN];
120 assert(http);
121 assert(handler);
122 debugs(61, 5, "redirectStart: '" << http->uri << "'");
123
124 if (Config.onoff.redirector_bypass && redirectors->stats.queue_size) {
125 /* Skip redirector if there is one request queued */
126 n_bypassed++;
127 handler(data, NULL);
128 return;
129 }
130
131 r = cbdataAlloc(redirectStateData);
132 r->orig_url = xstrdup(http->uri);
133 if (conn != NULL)
134 r->client_addr = conn->log_addr;
135 else
136 r->client_addr.SetNoAddr();
137 r->client_ident = NULL;
138
139 if (http->request->auth_user_request != NULL)
140 r->client_ident = http->request->auth_user_request->username();
141 else if (http->request->extacl_user.defined()) {
142 r->client_ident = http->request->extacl_user.termedBuf();
143 }
144
145 if (!r->client_ident && (conn != NULL && conn->rfc931[0]))
146 r->client_ident = conn->rfc931;
147
148 #if USE_SSL
149
150 if (!r->client_ident && conn != NULL)
151 r->client_ident = sslGetUserEmail(fd_table[conn->fd].ssl);
152
153 #endif
154
155 if (!r->client_ident)
156 r->client_ident = dash_str;
157
158 r->method_s = RequestMethodStr(http->request->method);
159
160 r->handler = handler;
161
162 r->data = cbdataReference(data);
163
164 if ((fqdn = fqdncache_gethostbyaddr(r->client_addr, 0)) == NULL)
165 fqdn = dash_str;
166
167 snprintf(buf, 8192, "%s %s/%s %s %s myip=%s myport=%d\n",
168 r->orig_url,
169 r->client_addr.NtoA(claddr,MAX_IPSTRLEN),
170 fqdn,
171 r->client_ident[0] ? rfc1738_escape(r->client_ident) : dash_str,
172 r->method_s,
173 http->request->my_addr.NtoA(myaddr,MAX_IPSTRLEN),
174 http->request->my_addr.GetPort());
175
176 helperSubmit(redirectors, buf, redirectHandleReply, r);
177 }
178
179 static void
180 redirectRegisterWithCacheManager(void)
181 {
182 Mgr::RegisterAction("redirector", "URL Redirector Stats", redirectStats, 0, 1);
183 }
184
185 void
186 redirectInit(void)
187 {
188 static int init = 0;
189
190 redirectRegisterWithCacheManager();
191
192 if (!Config.Program.redirect)
193 return;
194
195 if (redirectors == NULL)
196 redirectors = new helper("redirector");
197
198 redirectors->cmdline = Config.Program.redirect;
199
200 redirectors->childs = Config.redirectChildren;
201
202 redirectors->ipc_type = IPC_STREAM;
203
204 helperOpenServers(redirectors);
205
206 if (!init) {
207 init = 1;
208 CBDATA_INIT_TYPE(redirectStateData);
209 }
210 }
211
212 void
213 redirectShutdown(void)
214 {
215 if (!redirectors)
216 return;
217
218 helperShutdown(redirectors);
219
220 if (!shutting_down)
221 return;
222
223 delete redirectors;
224 redirectors = NULL;
225 }