]> git.ipfire.org Git - thirdparty/squid.git/blob - src/whois.cc
Renamed squid.h to squid-old.h and config.h to squid.h
[thirdparty/squid.git] / src / whois.cc
1
2 /*
3 * $Id$
4 *
5 * DEBUG: section 75 WHOIS protocol
6 * AUTHOR: Duane Wessels, Kostas Anagnostakis
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-old.h"
37 #include "comm/Write.h"
38 #include "errorpage.h"
39 #include "Store.h"
40 #include "HttpReply.h"
41 #include "HttpRequest.h"
42 #include "comm.h"
43 #include "HttpRequest.h"
44 #include "forward.h"
45 #include "StatCounters.h"
46
47 #define WHOIS_PORT 43
48
49 class WhoisState
50 {
51
52 public:
53 ~WhoisState();
54 void readReply(const Comm::ConnectionPointer &, char *aBuffer, size_t aBufferLength, comm_err_t flag, int xerrno);
55 void setReplyToOK(StoreEntry *sentry);
56 StoreEntry *entry;
57 HttpRequest *request;
58 FwdState::Pointer fwd;
59 char buf[BUFSIZ+1]; /* readReply adds terminating NULL */
60 bool dataWritten;
61 };
62
63 static CLCB whoisClose;
64 static CTCB whoisTimeout;
65 static IOCB whoisReadReply;
66
67 /* PUBLIC */
68
69 CBDATA_TYPE(WhoisState);
70
71 WhoisState::~WhoisState()
72 {
73 fwd = NULL; // refcounted
74 }
75
76 static void
77 whoisWriteComplete(const Comm::ConnectionPointer &, char *buf, size_t size, comm_err_t flag, int xerrno, void *data)
78 {
79 xfree(buf);
80 }
81
82 void
83 whoisStart(FwdState * fwd)
84 {
85 WhoisState *p;
86 char *buf;
87 size_t l;
88 CBDATA_INIT_TYPE(WhoisState);
89 p = cbdataAlloc(WhoisState);
90 p->request = fwd->request;
91 p->entry = fwd->entry;
92 p->fwd = fwd;
93 p->dataWritten = false;
94
95 p->entry->lock();
96 comm_add_close_handler(fwd->serverConnection()->fd, whoisClose, p);
97
98 l = p->request->urlpath.size() + 3;
99
100 buf = (char *)xmalloc(l);
101
102 String str_print=p->request->urlpath.substr(1,p->request->urlpath.size());
103 snprintf(buf, l, SQUIDSTRINGPH"\r\n", SQUIDSTRINGPRINT(str_print));
104
105 AsyncCall::Pointer writeCall = commCbCall(5,5, "whoisWriteComplete",
106 CommIoCbPtrFun(whoisWriteComplete, p));
107 Comm::Write(fwd->serverConnection(), buf, strlen(buf), writeCall, NULL);
108 AsyncCall::Pointer readCall = commCbCall(5,4, "whoisReadReply",
109 CommIoCbPtrFun(whoisReadReply, p));
110 comm_read(fwd->serverConnection(), p->buf, BUFSIZ, readCall);
111 AsyncCall::Pointer timeoutCall = commCbCall(5, 4, "whoisTimeout",
112 CommTimeoutCbPtrFun(whoisTimeout, p));
113 commSetConnTimeout(fwd->serverConnection(), Config.Timeout.read, timeoutCall);
114 }
115
116 /* PRIVATE */
117
118 static void
119 whoisTimeout(const CommTimeoutCbParams &io)
120 {
121 WhoisState *p = static_cast<WhoisState *>(io.data);
122 debugs(75, 3, HERE << io.conn << ", URL " << p->entry->url());
123 io.conn->close();
124 }
125
126 static void
127 whoisReadReply(const Comm::ConnectionPointer &conn, char *buf, size_t len, comm_err_t flag, int xerrno, void *data)
128 {
129 WhoisState *p = (WhoisState *)data;
130 p->readReply(conn, buf, len, flag, xerrno);
131 }
132
133 void
134 WhoisState::setReplyToOK(StoreEntry *sentry)
135 {
136 HttpReply *reply = new HttpReply;
137 sentry->buffer();
138 reply->setHeaders(HTTP_OK, "Gatewaying", "text/plain", -1, -1, -2);
139 sentry->replaceHttpReply(reply);
140 }
141
142 void
143 WhoisState::readReply(const Comm::ConnectionPointer &conn, char *aBuffer, size_t aBufferLength, comm_err_t flag, int xerrno)
144 {
145 /* Bail out early on COMM_ERR_CLOSING - close handlers will tidy up for us */
146 if (flag == COMM_ERR_CLOSING)
147 return;
148
149 aBuffer[aBufferLength] = '\0';
150 debugs(75, 3, HERE << conn << " read " << aBufferLength << " bytes");
151 debugs(75, 5, "{" << aBuffer << "}");
152
153 if (flag != COMM_OK) {
154 debugs(50, 2, HERE << conn << ": read failure: " << xstrerror() << ".");
155
156 if (ignoreErrno(errno)) {
157 AsyncCall::Pointer call = commCbCall(5,4, "whoisReadReply",
158 CommIoCbPtrFun(whoisReadReply, this));
159 comm_read(conn, aBuffer, BUFSIZ, call);
160 } else {
161 ErrorState *err = new ErrorState(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR, fwd->request);
162 err->xerrno = errno;
163 fwd->fail(err);
164 conn->close();
165 }
166 return;
167 }
168
169 if (aBufferLength > 0) {
170 if (!dataWritten)
171 setReplyToOK(entry);
172
173 kb_incr(&(statCounter.server.all.kbytes_in), aBufferLength);
174 kb_incr(&(statCounter.server.http.kbytes_in), aBufferLength);
175
176 /* No range support, we always grab it all */
177 dataWritten = true;
178 entry->append(aBuffer, aBufferLength);
179 entry->flush();
180
181 AsyncCall::Pointer call = commCbCall(5,4, "whoisReadReply",
182 CommIoCbPtrFun(whoisReadReply, this));
183 comm_read(conn, aBuffer, BUFSIZ, call);
184 return;
185 }
186
187 /* no bytes read. stop reading */
188 entry->timestampsSet();
189 entry->flush();
190
191 if (!EBIT_TEST(entry->flags, RELEASE_REQUEST))
192 entry->setPublicKey();
193
194 fwd->complete();
195 debugs(75, 3, "whoisReadReply: Done: " << entry->url());
196 conn->close();
197 }
198
199 static void
200 whoisClose(const CommCloseCbParams &params)
201 {
202 WhoisState *p = (WhoisState *)params.data;
203 debugs(75, 3, "whoisClose: FD " << params.fd);
204 p->entry->unlock();
205 cbdataFree(p);
206 }