]> git.ipfire.org Git - thirdparty/squid.git/blame - src/whois.cc
extra debugs on IdleConnList clearHandlers
[thirdparty/squid.git] / src / whois.cc
CommitLineData
77b32a34 1
af6691cc 2/*
262a0e14 3 * $Id$
af6691cc 4 *
5 * DEBUG: section 75 WHOIS protocol
6 * AUTHOR: Duane Wessels, Kostas Anagnostakis
7 *
2b6662ba 8 * SQUID Web Proxy Cache http://www.squid-cache.org/
e25c139f 9 * ----------------------------------------------------------
af6691cc 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.
af6691cc 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.
26ac0430 24 *
af6691cc 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.
26ac0430 29 *
af6691cc 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 *
af6691cc 34 */
35
36#include "squid.h"
ec41b64c 37#include "comm/Write.h"
aa839030 38#include "errorpage.h"
e6ccf245 39#include "Store.h"
528b2c61 40#include "HttpReply.h"
924f73bc 41#include "HttpRequest.h"
e6546865 42#include "comm.h"
a2ac85d9 43#include "HttpRequest.h"
b6b6f466 44#include "forward.h"
af6691cc 45
46#define WHOIS_PORT 43
47
62e76326 48class WhoisState
49{
50
528b2c61 51public:
b6b6f466 52 ~WhoisState();
e0d28505 53 void readReply(const Comm::ConnectionPointer &, char *aBuffer, size_t aBufferLength, comm_err_t flag, int xerrno);
e053c141 54 void setReplyToOK(StoreEntry *sentry);
af6691cc 55 StoreEntry *entry;
190154cf 56 HttpRequest *request;
b6b6f466 57 FwdState::Pointer fwd;
5bac8e33 58 char buf[BUFSIZ+1]; /* readReply adds terminating NULL */
528b2c61 59 bool dataWritten;
60};
af6691cc 61
62static PF whoisClose;
63static PF whoisTimeout;
c4b7a5a9 64static IOCB whoisReadReply;
af6691cc 65
66/* PUBLIC */
67
28c60158 68CBDATA_TYPE(WhoisState);
69
b6b6f466 70WhoisState::~WhoisState()
71{
72 fwd = NULL; // refcounted
73}
74
e6546865 75static void
e0d28505 76whoisWriteComplete(const Comm::ConnectionPointer &, char *buf, size_t size, comm_err_t flag, int xerrno, void *data)
e6546865 77{
62e76326 78 xfree(buf);
e6546865 79}
80
af6691cc 81void
db1cd23c 82whoisStart(FwdState * fwd)
af6691cc 83{
28c60158 84 WhoisState *p;
af6691cc 85 char *buf;
86 size_t l;
28c60158 87 CBDATA_INIT_TYPE(WhoisState);
72711e31 88 p = cbdataAlloc(WhoisState);
db1cd23c 89 p->request = fwd->request;
90 p->entry = fwd->entry;
91 p->fwd = fwd;
5bac8e33 92 p->dataWritten = false;
34266cde 93
3d0ac046 94 p->entry->lock();
e0d28505 95 comm_add_close_handler(fwd->serverConnection()->fd, whoisClose, p);
34266cde 96
528b2c61 97 l = p->request->urlpath.size() + 3;
34266cde 98
e6ccf245 99 buf = (char *)xmalloc(l);
34266cde 100
2c1fd837
FC
101 String str_print=p->request->urlpath.substr(1,p->request->urlpath.size());
102 snprintf(buf, l, SQUIDSTRINGPH"\r\n", SQUIDSTRINGPRINT(str_print));
34266cde 103
abd8f140
AJ
104 AsyncCall::Pointer writeCall = commCbCall(5,5, "whoisWriteComplete",
105 CommIoCbPtrFun(whoisWriteComplete, p));
106 Comm::Write(fwd->serverConnection(), buf, strlen(buf), writeCall, NULL);
107 AsyncCall::Pointer readCall = commCbCall(5,4, "whoisReadReply",
108 CommIoCbPtrFun(whoisReadReply, p));
109 comm_read(fwd->serverConnection(), p->buf, BUFSIZ, readCall);
e0d28505 110 commSetTimeout(fwd->serverConnection()->fd, Config.Timeout.read, whoisTimeout, p);
af6691cc 111}
112
113/* PRIVATE */
114
115static void
116whoisTimeout(int fd, void *data)
117{
e6ccf245 118 WhoisState *p = (WhoisState *)data;
bf8fe701 119 debugs(75, 1, "whoisTimeout: " << p->entry->url() );
af6691cc 120 whoisClose(fd, p);
121}
122
123static void
e0d28505 124whoisReadReply(const Comm::ConnectionPointer &conn, char *buf, size_t len, comm_err_t flag, int xerrno, void *data)
af6691cc 125{
e6ccf245 126 WhoisState *p = (WhoisState *)data;
e0d28505 127 p->readReply(conn, buf, len, flag, xerrno);
528b2c61 128}
129
130void
e053c141 131WhoisState::setReplyToOK(StoreEntry *sentry)
528b2c61 132{
06a5ae20 133 HttpReply *reply = new HttpReply;
e053c141 134 sentry->buffer();
11992b6f 135 reply->setHeaders(HTTP_OK, "Gatewaying", "text/plain", -1, -1, -2);
e053c141 136 sentry->replaceHttpReply(reply);
528b2c61 137}
138
139void
e0d28505 140WhoisState::readReply(const Comm::ConnectionPointer &conn, char *aBuffer, size_t aBufferLength, comm_err_t flag, int xerrno)
528b2c61 141{
c4b7a5a9 142 int do_next_read = 0;
143
144 /* Bail out early on COMM_ERR_CLOSING - close handlers will tidy up for us */
62e76326 145
c4b7a5a9 146 if (flag == COMM_ERR_CLOSING) {
147 return;
148 }
149
e053c141 150 aBuffer[aBufferLength] = '\0';
e0d28505 151 debugs(75, 3, HERE << conn << " read " << aBufferLength << " bytes");
e053c141 152 debugs(75, 5, "{" << aBuffer << "}");
62e76326 153
e053c141 154 if (flag == COMM_OK && aBufferLength > 0) {
62e76326 155 if (!dataWritten)
156 setReplyToOK(entry);
157
e053c141 158 kb_incr(&statCounter.server.all.kbytes_in, aBufferLength);
62e76326 159
e053c141 160 kb_incr(&statCounter.server.http.kbytes_in, aBufferLength);
62e76326 161
162 /* No range support, we always grab it all */
5bac8e33 163 dataWritten = true;
62e76326 164
e053c141 165 entry->append(aBuffer, aBufferLength);
62e76326 166
3900307b 167 entry->flush();
b66315e4 168
c4b7a5a9 169 do_next_read = 1;
e053c141 170 } else if (flag != COMM_OK || aBufferLength < 0) {
e0d28505 171 debugs(50, 2, HERE << conn << ": read failure: " << xstrerror() << ".");
62e76326 172
173 if (ignoreErrno(errno)) {
c4b7a5a9 174 do_next_read = 1;
6cae5db1 175 } else {
62e76326 176 ErrorState *err;
2cc81f1f 177 err = errorCon(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR, fwd->request);
62e76326 178 err->xerrno = errno;
b6b6f466 179 fwd->fail(err);
80463bb4 180 conn->close();
c4b7a5a9 181 do_next_read = 0;
62e76326 182 }
abdacbb5 183 } else {
3900307b 184 entry->timestampsSet();
185 entry->flush();
62e76326 186
187 if (!EBIT_TEST(entry->flags, RELEASE_REQUEST))
d88e3c49 188 entry->setPublicKey();
62e76326 189
b6b6f466 190 fwd->complete();
bf8fe701 191 debugs(75, 3, "whoisReadReply: Done: " << entry->url() );
80463bb4 192 conn->close();
c4b7a5a9 193 do_next_read = 0;
af6691cc 194 }
62e76326 195
abd8f140
AJ
196 if (do_next_read) {
197 AsyncCall::Pointer call = commCbCall(5,4, "whoisReadReply",
198 CommIoCbPtrFun(whoisReadReply, this));
199 comm_read(conn, aBuffer, BUFSIZ, call);
200 }
af6691cc 201}
202
203static void
204whoisClose(int fd, void *data)
205{
e6ccf245 206 WhoisState *p = (WhoisState *)data;
bf8fe701 207 debugs(75, 3, "whoisClose: FD " << fd);
97b5e68f 208 p->entry->unlock();
af6691cc 209 cbdataFree(p);
210}