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