]>
Commit | Line | Data |
---|---|---|
be335c22 | 1 | |
30a4f2a8 | 2 | /* |
2b6662ba | 3 | * $Id: redirect.cc,v 1.87 2001/01/12 00:37:20 wessels Exp $ |
30a4f2a8 | 4 | * |
5 | * DEBUG: section 29 Redirector | |
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" | |
37 | ||
30a4f2a8 | 38 | typedef struct { |
d2af9477 | 39 | void *data; |
30a4f2a8 | 40 | char *orig_url; |
c0cdaf99 | 41 | struct in_addr client_addr; |
0ee4272b | 42 | const char *client_ident; |
43 | const char *method_s; | |
582b6456 | 44 | RH *handler; |
30a4f2a8 | 45 | } redirectStateData; |
46 | ||
74addf6c | 47 | static HLPCB redirectHandleReply; |
f5b8bbc4 | 48 | static void redirectStateFree(redirectStateData * r); |
74addf6c | 49 | static helper *redirectors = NULL; |
50 | static OBJH redirectStats; | |
07476a7f | 51 | static int n_bypassed = 0; |
28c60158 | 52 | CBDATA_TYPE(redirectStateData); |
30a4f2a8 | 53 | |
582b6456 | 54 | static void |
74addf6c | 55 | redirectHandleReply(void *data, char *reply) |
30a4f2a8 | 56 | { |
74addf6c | 57 | redirectStateData *r = data; |
16d3fe0d | 58 | int valid; |
74addf6c | 59 | char *t; |
c68e9c6b | 60 | debug(29, 5) ("redirectHandleRead: {%s}\n", reply ? reply : "<NULL>"); |
61 | if (reply) { | |
62 | if ((t = strchr(reply, ' '))) | |
63 | *t = '\0'; | |
64 | if (*reply == '\0') | |
65 | reply = NULL; | |
66 | } | |
74addf6c | 67 | valid = cbdataValid(r->data); |
68 | cbdataUnlock(r->data); | |
69 | if (valid) | |
70 | r->handler(r->data, reply); | |
71 | redirectStateFree(r); | |
30a4f2a8 | 72 | } |
73 | ||
e7a22b88 | 74 | static void |
75 | redirectStateFree(redirectStateData * r) | |
76 | { | |
77 | safe_free(r->orig_url); | |
74addf6c | 78 | cbdataFree(r); |
e7a22b88 | 79 | } |
80 | ||
b8d8561b | 81 | static void |
74addf6c | 82 | redirectStats(StoreEntry * sentry) |
30a4f2a8 | 83 | { |
74addf6c | 84 | storeAppendPrintf(sentry, "Redirector Statistics:\n"); |
85 | helperStats(sentry, redirectors); | |
07476a7f | 86 | if (Config.onoff.redirector_bypass) |
87 | storeAppendPrintf(sentry, "\nNumber of requests bypassed " | |
88 | "because all redirectors were busy: %d\n", n_bypassed); | |
30a4f2a8 | 89 | } |
90 | ||
d2af9477 | 91 | /**** PUBLIC FUNCTIONS ****/ |
92 | ||
b8d8561b | 93 | void |
382d851a | 94 | redirectStart(clientHttpRequest * http, RH * handler, void *data) |
d2af9477 | 95 | { |
382d851a | 96 | ConnStateData *conn = http->conn; |
d2af9477 | 97 | redirectStateData *r = NULL; |
74addf6c | 98 | const char *fqdn; |
99 | char buf[8192]; | |
100 | assert(http); | |
101 | assert(handler); | |
23d92c64 | 102 | debug(29, 5) ("redirectStart: '%s'\n", http->uri); |
b6f794d6 | 103 | if (Config.Program.redirect == NULL) { |
e6f18b4a | 104 | handler(data, NULL); |
d2af9477 | 105 | return; |
106 | } | |
9bc73deb | 107 | if (Config.accessList.redirector) { |
108 | aclCheck_t ch; | |
109 | memset(&ch, '\0', sizeof(ch)); | |
110 | ch.src_addr = http->conn->peer.sin_addr; | |
111 | ch.my_addr = http->conn->me.sin_addr; | |
efd900cb | 112 | ch.my_port = ntohs(http->conn->me.sin_port); |
9bc73deb | 113 | ch.request = http->request; |
114 | if (!aclCheckFast(Config.accessList.redirector, &ch)) { | |
115 | /* denied -- bypass redirector */ | |
116 | handler(data, NULL); | |
117 | return; | |
118 | } | |
119 | } | |
07476a7f | 120 | if (Config.onoff.redirector_bypass && redirectors->stats.queue_size) { |
121 | /* Skip redirector if there is one request queued */ | |
122 | n_bypassed++; | |
123 | handler(data, NULL); | |
124 | return; | |
125 | } | |
28c60158 | 126 | r = CBDATA_ALLOC(redirectStateData, NULL); |
23d92c64 | 127 | r->orig_url = xstrdup(http->uri); |
382d851a | 128 | r->client_addr = conn->log_addr; |
94439e4e | 129 | if (http->request->auth_user_request) |
130 | r->client_ident = authenticateUserRequestUsername(http->request->auth_user_request); | |
131 | else if (conn->rfc931[0]) { | |
132 | r->client_ident = conn->rfc931; | |
c0cdaf99 | 133 | } else { |
94439e4e | 134 | r->client_ident = dash_str; |
c0cdaf99 | 135 | } |
382d851a | 136 | r->method_s = RequestMethodStr[http->request->method]; |
d2af9477 | 137 | r->handler = handler; |
138 | r->data = data; | |
16d3fe0d | 139 | cbdataLock(r->data); |
74addf6c | 140 | if ((fqdn = fqdncache_gethostbyaddr(r->client_addr, 0)) == NULL) |
141 | fqdn = dash_str; | |
142 | snprintf(buf, 8192, "%s %s/%s %s %s\n", | |
143 | r->orig_url, | |
144 | inet_ntoa(r->client_addr), | |
145 | fqdn, | |
146 | r->client_ident, | |
147 | r->method_s); | |
148 | helperSubmit(redirectors, buf, redirectHandleReply, r); | |
0a21bd84 | 149 | } |
150 | ||
b8d8561b | 151 | void |
74addf6c | 152 | redirectInit(void) |
30a4f2a8 | 153 | { |
74addf6c | 154 | static int init = 0; |
74addf6c | 155 | if (!Config.Program.redirect) |
d2af9477 | 156 | return; |
838b993c | 157 | if (redirectors == NULL) |
7d47d8e6 | 158 | redirectors = helperCreate("redirector"); |
c6d5b87b | 159 | redirectors->cmdline = Config.Program.redirect; |
74addf6c | 160 | redirectors->n_to_start = Config.redirectChildren; |
161 | redirectors->ipc_type = IPC_TCP_SOCKET; | |
162 | helperOpenServers(redirectors); | |
163 | if (!init) { | |
22f3fd98 | 164 | cachemgrRegister("redirector", |
165 | "URL Redirector Stats", | |
1da3b90b | 166 | redirectStats, 0, 1); |
7e3ce7b9 | 167 | init = 1; |
28c60158 | 168 | CBDATA_INIT_TYPE(redirectStateData); |
d2af9477 | 169 | } |
30a4f2a8 | 170 | } |
171 | ||
16d3fe0d | 172 | void |
74addf6c | 173 | redirectShutdown(void) |
30a4f2a8 | 174 | { |
74addf6c | 175 | if (!redirectors) |
16d3fe0d | 176 | return; |
74addf6c | 177 | helperShutdown(redirectors); |
838b993c | 178 | if (!shutting_down) |
179 | return; | |
1f5f60dd | 180 | helperFree(redirectors); |
181 | redirectors = NULL; | |
30a4f2a8 | 182 | } |