]> git.ipfire.org Git - thirdparty/squid.git/blame - src/whois.cc
Fix typo in rev.13441
[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"
7e66d5e2 36#include "comm/Read.h"
ec41b64c 37#include "comm/Write.h"
aa839030 38#include "errorpage.h"
eb13c21e 39#include "FwdState.h"
528b2c61 40#include "HttpReply.h"
924f73bc 41#include "HttpRequest.h"
4d5904f7 42#include "SquidConfig.h"
e4f1fdae 43#include "StatCounters.h"
582c2af2 44#include "Store.h"
4e540555 45#include "tools.h"
af6691cc 46
1a30fdf5 47#include <cerrno>
21d845b1 48
af6691cc 49#define WHOIS_PORT 43
50
62e76326 51class WhoisState
52{
528b2c61 53public:
e0d28505 54 void readReply(const Comm::ConnectionPointer &, char *aBuffer, size_t aBufferLength, comm_err_t flag, int xerrno);
e053c141 55 void setReplyToOK(StoreEntry *sentry);
af6691cc 56 StoreEntry *entry;
c31bb519 57 HttpRequest::Pointer request;
b6b6f466 58 FwdState::Pointer fwd;
5bac8e33 59 char buf[BUFSIZ+1]; /* readReply adds terminating NULL */
528b2c61 60 bool dataWritten;
c31bb519
AJ
61
62private:
63 CBDATA_CLASS2(WhoisState);
528b2c61 64};
af6691cc 65
c31bb519
AJ
66CBDATA_CLASS_INIT(WhoisState);
67
575d05c4 68static CLCB whoisClose;
8d77a37c 69static CTCB whoisTimeout;
c4b7a5a9 70static IOCB whoisReadReply;
af6691cc 71
72/* PUBLIC */
73
e6546865 74static void
e0d28505 75whoisWriteComplete(const Comm::ConnectionPointer &, char *buf, size_t size, comm_err_t flag, int xerrno, void *data)
e6546865 76{
62e76326 77 xfree(buf);
e6546865 78}
79
af6691cc 80void
db1cd23c 81whoisStart(FwdState * fwd)
af6691cc 82{
af6691cc 83 char *buf;
84 size_t l;
c31bb519 85 WhoisState *p = new WhoisState;
db1cd23c 86 p->request = fwd->request;
87 p->entry = fwd->entry;
88 p->fwd = fwd;
5bac8e33 89 p->dataWritten = false;
34266cde 90
1bfe9ade 91 p->entry->lock("whoisStart");
e0d28505 92 comm_add_close_handler(fwd->serverConnection()->fd, whoisClose, p);
34266cde 93
528b2c61 94 l = p->request->urlpath.size() + 3;
34266cde 95
e6ccf245 96 buf = (char *)xmalloc(l);
34266cde 97
2c1fd837
FC
98 String str_print=p->request->urlpath.substr(1,p->request->urlpath.size());
99 snprintf(buf, l, SQUIDSTRINGPH"\r\n", SQUIDSTRINGPRINT(str_print));
34266cde 100
abd8f140 101 AsyncCall::Pointer writeCall = commCbCall(5,5, "whoisWriteComplete",
dc49061a 102 CommIoCbPtrFun(whoisWriteComplete, p));
abd8f140
AJ
103 Comm::Write(fwd->serverConnection(), buf, strlen(buf), writeCall, NULL);
104 AsyncCall::Pointer readCall = commCbCall(5,4, "whoisReadReply",
dc49061a 105 CommIoCbPtrFun(whoisReadReply, p));
abd8f140 106 comm_read(fwd->serverConnection(), p->buf, BUFSIZ, readCall);
8d77a37c 107 AsyncCall::Pointer timeoutCall = commCbCall(5, 4, "whoisTimeout",
dc49061a 108 CommTimeoutCbPtrFun(whoisTimeout, p));
8d77a37c 109 commSetConnTimeout(fwd->serverConnection(), Config.Timeout.read, timeoutCall);
af6691cc 110}
111
112/* PRIVATE */
113
114static void
8d77a37c 115whoisTimeout(const CommTimeoutCbParams &io)
af6691cc 116{
8d77a37c
AJ
117 WhoisState *p = static_cast<WhoisState *>(io.data);
118 debugs(75, 3, HERE << io.conn << ", URL " << p->entry->url());
119 io.conn->close();
af6691cc 120}
121
122static void
e0d28505 123whoisReadReply(const Comm::ConnectionPointer &conn, char *buf, size_t len, comm_err_t flag, int xerrno, void *data)
af6691cc 124{
e6ccf245 125 WhoisState *p = (WhoisState *)data;
e0d28505 126 p->readReply(conn, buf, len, flag, xerrno);
528b2c61 127}
128
129void
e053c141 130WhoisState::setReplyToOK(StoreEntry *sentry)
528b2c61 131{
06a5ae20 132 HttpReply *reply = new HttpReply;
e053c141 133 sentry->buffer();
955394ce 134 reply->setHeaders(Http::scOkay, "Gatewaying", "text/plain", -1, -1, -2);
e053c141 135 sentry->replaceHttpReply(reply);
528b2c61 136}
137
138void
e0d28505 139WhoisState::readReply(const Comm::ConnectionPointer &conn, char *aBuffer, size_t aBufferLength, comm_err_t flag, int xerrno)
528b2c61 140{
c4b7a5a9 141 /* Bail out early on COMM_ERR_CLOSING - close handlers will tidy up for us */
58c0b17d 142 if (flag == COMM_ERR_CLOSING)
c4b7a5a9 143 return;
c4b7a5a9 144
e053c141 145 aBuffer[aBufferLength] = '\0';
e0d28505 146 debugs(75, 3, HERE << conn << " read " << aBufferLength << " bytes");
e053c141 147 debugs(75, 5, "{" << aBuffer << "}");
62e76326 148
58c0b17d 149 if (flag != COMM_OK) {
e0d28505 150 debugs(50, 2, HERE << conn << ": read failure: " << xstrerror() << ".");
62e76326 151
152 if (ignoreErrno(errno)) {
1b76e6c1
AJ
153 AsyncCall::Pointer call = commCbCall(5,4, "whoisReadReply",
154 CommIoCbPtrFun(whoisReadReply, this));
155 comm_read(conn, aBuffer, BUFSIZ, call);
6cae5db1 156 } else {
955394ce 157 ErrorState *err = new ErrorState(ERR_READ_ERROR, Http::scInternalServerError, fwd->request);
129fe2a1 158 err->xerrno = xerrno;
b6b6f466 159 fwd->fail(err);
80463bb4 160 conn->close();
62e76326 161 }
58c0b17d
AJ
162 return;
163 }
62e76326 164
58c0b17d
AJ
165 if (aBufferLength > 0) {
166 if (!dataWritten)
167 setReplyToOK(entry);
62e76326 168
e4f1fdae
FC
169 kb_incr(&(statCounter.server.all.kbytes_in), aBufferLength);
170 kb_incr(&(statCounter.server.http.kbytes_in), aBufferLength);
62e76326 171
58c0b17d
AJ
172 /* No range support, we always grab it all */
173 dataWritten = true;
174 entry->append(aBuffer, aBufferLength);
175 entry->flush();
62e76326 176
abd8f140
AJ
177 AsyncCall::Pointer call = commCbCall(5,4, "whoisReadReply",
178 CommIoCbPtrFun(whoisReadReply, this));
179 comm_read(conn, aBuffer, BUFSIZ, call);
58c0b17d 180 return;
abd8f140 181 }
62e76326 182
58c0b17d
AJ
183 /* no bytes read. stop reading */
184 entry->timestampsSet();
185 entry->flush();
186
6919be24 187 entry->makePublic();
58c0b17d
AJ
188
189 fwd->complete();
190 debugs(75, 3, "whoisReadReply: Done: " << entry->url());
1b76e6c1 191 conn->close();
af6691cc 192}
193
194static void
575d05c4 195whoisClose(const CommCloseCbParams &params)
af6691cc 196{
575d05c4
AJ
197 WhoisState *p = (WhoisState *)params.data;
198 debugs(75, 3, "whoisClose: FD " << params.fd);
1bfe9ade 199 p->entry->unlock("whoisClose");
c31bb519 200 delete p;
af6691cc 201}