]> git.ipfire.org Git - thirdparty/squid.git/blame - src/whois.cc
Changed some structs to classes.
[thirdparty/squid.git] / src / whois.cc
CommitLineData
77b32a34 1
af6691cc 2/*
af6691cc 3 * DEBUG: section 75 WHOIS protocol
4 * AUTHOR: Duane Wessels, Kostas Anagnostakis
5 *
2b6662ba 6 * SQUID Web Proxy Cache http://www.squid-cache.org/
e25c139f 7 * ----------------------------------------------------------
af6691cc 8 *
2b6662ba 9 * Squid is the result of efforts by numerous individuals from
10 * the Internet community; see the CONTRIBUTORS file for full
11 * details. Many organizations have provided support for Squid's
12 * development; see the SPONSORS file for full details. Squid is
13 * Copyrighted (C) 2001 by the Regents of the University of
14 * California; see the COPYRIGHT file for full details. Squid
15 * incorporates software developed and/or copyrighted by other
16 * sources; see the CREDITS file for full details.
af6691cc 17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
26ac0430 22 *
af6691cc 23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
26ac0430 27 *
af6691cc 28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
cbdec147 30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
e25c139f 31 *
af6691cc 32 */
33
582c2af2
FC
34#include "squid.h"
35#include "comm.h"
ec41b64c 36#include "comm/Write.h"
aa839030 37#include "errorpage.h"
528b2c61 38#include "HttpReply.h"
924f73bc 39#include "HttpRequest.h"
a2ac85d9 40#include "HttpRequest.h"
b6b6f466 41#include "forward.h"
e4f1fdae 42#include "StatCounters.h"
582c2af2 43#include "Store.h"
4e540555 44#include "tools.h"
af6691cc 45
21d845b1
FC
46#if HAVE_ERRNO_H
47#include <errno.h>
48#endif
49
af6691cc 50#define WHOIS_PORT 43
51
62e76326 52class WhoisState
53{
54
528b2c61 55public:
b6b6f466 56 ~WhoisState();
e0d28505 57 void readReply(const Comm::ConnectionPointer &, char *aBuffer, size_t aBufferLength, comm_err_t flag, int xerrno);
e053c141 58 void setReplyToOK(StoreEntry *sentry);
af6691cc 59 StoreEntry *entry;
190154cf 60 HttpRequest *request;
b6b6f466 61 FwdState::Pointer fwd;
5bac8e33 62 char buf[BUFSIZ+1]; /* readReply adds terminating NULL */
528b2c61 63 bool dataWritten;
64};
af6691cc 65
575d05c4 66static CLCB whoisClose;
8d77a37c 67static CTCB whoisTimeout;
c4b7a5a9 68static IOCB whoisReadReply;
af6691cc 69
70/* PUBLIC */
71
28c60158 72CBDATA_TYPE(WhoisState);
73
b6b6f466 74WhoisState::~WhoisState()
75{
76 fwd = NULL; // refcounted
77}
78
e6546865 79static void
e0d28505 80whoisWriteComplete(const Comm::ConnectionPointer &, char *buf, size_t size, comm_err_t flag, int xerrno, void *data)
e6546865 81{
62e76326 82 xfree(buf);
e6546865 83}
84
af6691cc 85void
db1cd23c 86whoisStart(FwdState * fwd)
af6691cc 87{
28c60158 88 WhoisState *p;
af6691cc 89 char *buf;
90 size_t l;
28c60158 91 CBDATA_INIT_TYPE(WhoisState);
72711e31 92 p = cbdataAlloc(WhoisState);
db1cd23c 93 p->request = fwd->request;
94 p->entry = fwd->entry;
95 p->fwd = fwd;
5bac8e33 96 p->dataWritten = false;
34266cde 97
3d0ac046 98 p->entry->lock();
e0d28505 99 comm_add_close_handler(fwd->serverConnection()->fd, whoisClose, p);
34266cde 100
528b2c61 101 l = p->request->urlpath.size() + 3;
34266cde 102
e6ccf245 103 buf = (char *)xmalloc(l);
34266cde 104
2c1fd837
FC
105 String str_print=p->request->urlpath.substr(1,p->request->urlpath.size());
106 snprintf(buf, l, SQUIDSTRINGPH"\r\n", SQUIDSTRINGPRINT(str_print));
34266cde 107
abd8f140 108 AsyncCall::Pointer writeCall = commCbCall(5,5, "whoisWriteComplete",
dc49061a 109 CommIoCbPtrFun(whoisWriteComplete, p));
abd8f140
AJ
110 Comm::Write(fwd->serverConnection(), buf, strlen(buf), writeCall, NULL);
111 AsyncCall::Pointer readCall = commCbCall(5,4, "whoisReadReply",
dc49061a 112 CommIoCbPtrFun(whoisReadReply, p));
abd8f140 113 comm_read(fwd->serverConnection(), p->buf, BUFSIZ, readCall);
8d77a37c 114 AsyncCall::Pointer timeoutCall = commCbCall(5, 4, "whoisTimeout",
dc49061a 115 CommTimeoutCbPtrFun(whoisTimeout, p));
8d77a37c 116 commSetConnTimeout(fwd->serverConnection(), Config.Timeout.read, timeoutCall);
af6691cc 117}
118
119/* PRIVATE */
120
121static void
8d77a37c 122whoisTimeout(const CommTimeoutCbParams &io)
af6691cc 123{
8d77a37c
AJ
124 WhoisState *p = static_cast<WhoisState *>(io.data);
125 debugs(75, 3, HERE << io.conn << ", URL " << p->entry->url());
126 io.conn->close();
af6691cc 127}
128
129static void
e0d28505 130whoisReadReply(const Comm::ConnectionPointer &conn, char *buf, size_t len, comm_err_t flag, int xerrno, void *data)
af6691cc 131{
e6ccf245 132 WhoisState *p = (WhoisState *)data;
e0d28505 133 p->readReply(conn, buf, len, flag, xerrno);
528b2c61 134}
135
136void
e053c141 137WhoisState::setReplyToOK(StoreEntry *sentry)
528b2c61 138{
06a5ae20 139 HttpReply *reply = new HttpReply;
e053c141 140 sentry->buffer();
11992b6f 141 reply->setHeaders(HTTP_OK, "Gatewaying", "text/plain", -1, -1, -2);
e053c141 142 sentry->replaceHttpReply(reply);
528b2c61 143}
144
145void
e0d28505 146WhoisState::readReply(const Comm::ConnectionPointer &conn, char *aBuffer, size_t aBufferLength, comm_err_t flag, int xerrno)
528b2c61 147{
c4b7a5a9 148 /* Bail out early on COMM_ERR_CLOSING - close handlers will tidy up for us */
58c0b17d 149 if (flag == COMM_ERR_CLOSING)
c4b7a5a9 150 return;
c4b7a5a9 151
e053c141 152 aBuffer[aBufferLength] = '\0';
e0d28505 153 debugs(75, 3, HERE << conn << " read " << aBufferLength << " bytes");
e053c141 154 debugs(75, 5, "{" << aBuffer << "}");
62e76326 155
58c0b17d 156 if (flag != COMM_OK) {
e0d28505 157 debugs(50, 2, HERE << conn << ": read failure: " << xstrerror() << ".");
62e76326 158
159 if (ignoreErrno(errno)) {
1b76e6c1
AJ
160 AsyncCall::Pointer call = commCbCall(5,4, "whoisReadReply",
161 CommIoCbPtrFun(whoisReadReply, this));
162 comm_read(conn, aBuffer, BUFSIZ, call);
6cae5db1 163 } else {
913524f0 164 ErrorState *err = new ErrorState(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR, fwd->request);
129fe2a1 165 err->xerrno = xerrno;
b6b6f466 166 fwd->fail(err);
80463bb4 167 conn->close();
62e76326 168 }
58c0b17d
AJ
169 return;
170 }
62e76326 171
58c0b17d
AJ
172 if (aBufferLength > 0) {
173 if (!dataWritten)
174 setReplyToOK(entry);
62e76326 175
e4f1fdae
FC
176 kb_incr(&(statCounter.server.all.kbytes_in), aBufferLength);
177 kb_incr(&(statCounter.server.http.kbytes_in), aBufferLength);
62e76326 178
58c0b17d
AJ
179 /* No range support, we always grab it all */
180 dataWritten = true;
181 entry->append(aBuffer, aBufferLength);
182 entry->flush();
62e76326 183
abd8f140
AJ
184 AsyncCall::Pointer call = commCbCall(5,4, "whoisReadReply",
185 CommIoCbPtrFun(whoisReadReply, this));
186 comm_read(conn, aBuffer, BUFSIZ, call);
58c0b17d 187 return;
abd8f140 188 }
62e76326 189
58c0b17d
AJ
190 /* no bytes read. stop reading */
191 entry->timestampsSet();
192 entry->flush();
193
194 if (!EBIT_TEST(entry->flags, RELEASE_REQUEST))
195 entry->setPublicKey();
196
197 fwd->complete();
198 debugs(75, 3, "whoisReadReply: Done: " << entry->url());
1b76e6c1 199 conn->close();
af6691cc 200}
201
202static void
575d05c4 203whoisClose(const CommCloseCbParams &params)
af6691cc 204{
575d05c4
AJ
205 WhoisState *p = (WhoisState *)params.data;
206 debugs(75, 3, "whoisClose: FD " << params.fd);
97b5e68f 207 p->entry->unlock();
af6691cc 208 cbdataFree(p);
209}