]> git.ipfire.org Git - thirdparty/squid.git/blame - src/whois.cc
Bug 3181: /dev/poll fails to build on Solaris with GCC 4.5.0
[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();
e053c141
FC
53 void readReply (int fd, char *aBuffer, size_t aBufferLength, comm_err_t flag, int xerrno);
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
76whoisWriteComplete(int fd, char *buf, size_t size, comm_err_t flag, int xerrno, void *data)
77{
62e76326 78 xfree(buf);
e6546865 79}
80
af6691cc 81void
db1cd23c 82whoisStart(FwdState * fwd)
af6691cc 83{
28c60158 84 WhoisState *p;
db1cd23c 85 int fd = fwd->server_fd;
af6691cc 86 char *buf;
87 size_t l;
28c60158 88 CBDATA_INIT_TYPE(WhoisState);
72711e31 89 p = cbdataAlloc(WhoisState);
db1cd23c 90 p->request = fwd->request;
91 p->entry = fwd->entry;
92 p->fwd = fwd;
5bac8e33 93 p->dataWritten = false;
34266cde 94
3d0ac046 95 p->entry->lock();
af6691cc 96 comm_add_close_handler(fd, whoisClose, p);
34266cde 97
528b2c61 98 l = p->request->urlpath.size() + 3;
34266cde 99
e6ccf245 100 buf = (char *)xmalloc(l);
34266cde 101
2c1fd837
FC
102 String str_print=p->request->urlpath.substr(1,p->request->urlpath.size());
103 snprintf(buf, l, SQUIDSTRINGPH"\r\n", SQUIDSTRINGPRINT(str_print));
34266cde 104
ec41b64c
AJ
105 AsyncCall::Pointer call = commCbCall(5,5, "whoisWriteComplete",
106 CommIoCbPtrFun(whoisWriteComplete, p));
107
108 Comm::Write(fd, buf, strlen(buf), call, NULL);
c4b7a5a9 109 comm_read(fd, p->buf, BUFSIZ, whoisReadReply, p);
af6691cc 110 commSetTimeout(fd, Config.Timeout.read, whoisTimeout, p);
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
c4b7a5a9 124whoisReadReply(int fd, char *buf, size_t len, comm_err_t flag, int xerrno, void *data)
af6691cc 125{
e6ccf245 126 WhoisState *p = (WhoisState *)data;
528b2c61 127 p->readReply(fd, buf, len, flag, xerrno);
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
e053c141 140WhoisState::readReply (int fd, 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
FC
150 aBuffer[aBufferLength] = '\0';
151 debugs(75, 3, "whoisReadReply: FD " << fd << " read " << aBufferLength << " bytes");
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) {
bf8fe701 171 debugs(50, 2, "whoisReadReply: FD " << fd << ": 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);
62e76326 180 comm_close(fd);
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();
62e76326 191
bf8fe701 192 debugs(75, 3, "whoisReadReply: Done: " << entry->url() );
62e76326 193
194 comm_close(fd);
195
c4b7a5a9 196 do_next_read = 0;
af6691cc 197 }
62e76326 198
c4b7a5a9 199 if (do_next_read)
e053c141 200 comm_read(fd, aBuffer, BUFSIZ, whoisReadReply, this);
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}