]> git.ipfire.org Git - thirdparty/squid.git/blame - src/whois.cc
Docs: Add man(8) page for helper-mux tool
[thirdparty/squid.git] / src / whois.cc
CommitLineData
af6691cc 1/*
bbc27441 2 * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
e25c139f 3 *
bbc27441
AJ
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
af6691cc 7 */
8
bbc27441
AJ
9/* DEBUG: section 75 WHOIS protocol */
10
582c2af2
FC
11#include "squid.h"
12#include "comm.h"
7e66d5e2 13#include "comm/Read.h"
ec41b64c 14#include "comm/Write.h"
aa839030 15#include "errorpage.h"
eb13c21e 16#include "FwdState.h"
528b2c61 17#include "HttpReply.h"
924f73bc 18#include "HttpRequest.h"
4d5904f7 19#include "SquidConfig.h"
e4f1fdae 20#include "StatCounters.h"
582c2af2 21#include "Store.h"
4e540555 22#include "tools.h"
af6691cc 23
1a30fdf5 24#include <cerrno>
21d845b1 25
af6691cc 26#define WHOIS_PORT 43
27
62e76326 28class WhoisState
29{
528b2c61 30public:
c8407295 31 void readReply(const Comm::ConnectionPointer &, char *aBuffer, size_t aBufferLength, Comm::Flag flag, int xerrno);
e053c141 32 void setReplyToOK(StoreEntry *sentry);
af6691cc 33 StoreEntry *entry;
c31bb519 34 HttpRequest::Pointer request;
b6b6f466 35 FwdState::Pointer fwd;
5bac8e33 36 char buf[BUFSIZ+1]; /* readReply adds terminating NULL */
528b2c61 37 bool dataWritten;
c31bb519
AJ
38
39private:
40 CBDATA_CLASS2(WhoisState);
528b2c61 41};
af6691cc 42
c31bb519
AJ
43CBDATA_CLASS_INIT(WhoisState);
44
575d05c4 45static CLCB whoisClose;
8d77a37c 46static CTCB whoisTimeout;
c4b7a5a9 47static IOCB whoisReadReply;
af6691cc 48
49/* PUBLIC */
50
e6546865 51static void
c8407295 52whoisWriteComplete(const Comm::ConnectionPointer &, char *buf, size_t size, Comm::Flag flag, int xerrno, void *data)
e6546865 53{
62e76326 54 xfree(buf);
e6546865 55}
56
af6691cc 57void
db1cd23c 58whoisStart(FwdState * fwd)
af6691cc 59{
af6691cc 60 char *buf;
61 size_t l;
c31bb519 62 WhoisState *p = new WhoisState;
db1cd23c 63 p->request = fwd->request;
64 p->entry = fwd->entry;
65 p->fwd = fwd;
5bac8e33 66 p->dataWritten = false;
34266cde 67
1bfe9ade 68 p->entry->lock("whoisStart");
e0d28505 69 comm_add_close_handler(fwd->serverConnection()->fd, whoisClose, p);
34266cde 70
528b2c61 71 l = p->request->urlpath.size() + 3;
34266cde 72
e6ccf245 73 buf = (char *)xmalloc(l);
34266cde 74
2c1fd837
FC
75 String str_print=p->request->urlpath.substr(1,p->request->urlpath.size());
76 snprintf(buf, l, SQUIDSTRINGPH"\r\n", SQUIDSTRINGPRINT(str_print));
34266cde 77
abd8f140 78 AsyncCall::Pointer writeCall = commCbCall(5,5, "whoisWriteComplete",
dc49061a 79 CommIoCbPtrFun(whoisWriteComplete, p));
abd8f140
AJ
80 Comm::Write(fwd->serverConnection(), buf, strlen(buf), writeCall, NULL);
81 AsyncCall::Pointer readCall = commCbCall(5,4, "whoisReadReply",
dc49061a 82 CommIoCbPtrFun(whoisReadReply, p));
abd8f140 83 comm_read(fwd->serverConnection(), p->buf, BUFSIZ, readCall);
8d77a37c 84 AsyncCall::Pointer timeoutCall = commCbCall(5, 4, "whoisTimeout",
dc49061a 85 CommTimeoutCbPtrFun(whoisTimeout, p));
8d77a37c 86 commSetConnTimeout(fwd->serverConnection(), Config.Timeout.read, timeoutCall);
af6691cc 87}
88
89/* PRIVATE */
90
91static void
8d77a37c 92whoisTimeout(const CommTimeoutCbParams &io)
af6691cc 93{
8d77a37c
AJ
94 WhoisState *p = static_cast<WhoisState *>(io.data);
95 debugs(75, 3, HERE << io.conn << ", URL " << p->entry->url());
96 io.conn->close();
af6691cc 97}
98
99static void
c8407295 100whoisReadReply(const Comm::ConnectionPointer &conn, char *buf, size_t len, Comm::Flag flag, int xerrno, void *data)
af6691cc 101{
e6ccf245 102 WhoisState *p = (WhoisState *)data;
e0d28505 103 p->readReply(conn, buf, len, flag, xerrno);
528b2c61 104}
105
106void
e053c141 107WhoisState::setReplyToOK(StoreEntry *sentry)
528b2c61 108{
06a5ae20 109 HttpReply *reply = new HttpReply;
e053c141 110 sentry->buffer();
955394ce 111 reply->setHeaders(Http::scOkay, "Gatewaying", "text/plain", -1, -1, -2);
e053c141 112 sentry->replaceHttpReply(reply);
528b2c61 113}
114
115void
c8407295 116WhoisState::readReply(const Comm::ConnectionPointer &conn, char *aBuffer, size_t aBufferLength, Comm::Flag flag, int xerrno)
528b2c61 117{
c8407295
AJ
118 /* Bail out early on Comm::ERR_CLOSING - close handlers will tidy up for us */
119 if (flag == Comm::ERR_CLOSING)
c4b7a5a9 120 return;
c4b7a5a9 121
e053c141 122 aBuffer[aBufferLength] = '\0';
e0d28505 123 debugs(75, 3, HERE << conn << " read " << aBufferLength << " bytes");
e053c141 124 debugs(75, 5, "{" << aBuffer << "}");
62e76326 125
c8407295 126 if (flag != Comm::OK) {
e0d28505 127 debugs(50, 2, HERE << conn << ": read failure: " << xstrerror() << ".");
62e76326 128
129 if (ignoreErrno(errno)) {
1b76e6c1
AJ
130 AsyncCall::Pointer call = commCbCall(5,4, "whoisReadReply",
131 CommIoCbPtrFun(whoisReadReply, this));
132 comm_read(conn, aBuffer, BUFSIZ, call);
6cae5db1 133 } else {
955394ce 134 ErrorState *err = new ErrorState(ERR_READ_ERROR, Http::scInternalServerError, fwd->request);
129fe2a1 135 err->xerrno = xerrno;
b6b6f466 136 fwd->fail(err);
80463bb4 137 conn->close();
62e76326 138 }
58c0b17d
AJ
139 return;
140 }
62e76326 141
58c0b17d
AJ
142 if (aBufferLength > 0) {
143 if (!dataWritten)
144 setReplyToOK(entry);
62e76326 145
e4f1fdae
FC
146 kb_incr(&(statCounter.server.all.kbytes_in), aBufferLength);
147 kb_incr(&(statCounter.server.http.kbytes_in), aBufferLength);
62e76326 148
58c0b17d
AJ
149 /* No range support, we always grab it all */
150 dataWritten = true;
151 entry->append(aBuffer, aBufferLength);
152 entry->flush();
62e76326 153
abd8f140
AJ
154 AsyncCall::Pointer call = commCbCall(5,4, "whoisReadReply",
155 CommIoCbPtrFun(whoisReadReply, this));
156 comm_read(conn, aBuffer, BUFSIZ, call);
58c0b17d 157 return;
abd8f140 158 }
62e76326 159
58c0b17d
AJ
160 /* no bytes read. stop reading */
161 entry->timestampsSet();
162 entry->flush();
163
6919be24 164 entry->makePublic();
58c0b17d
AJ
165
166 fwd->complete();
167 debugs(75, 3, "whoisReadReply: Done: " << entry->url());
1b76e6c1 168 conn->close();
af6691cc 169}
170
171static void
575d05c4 172whoisClose(const CommCloseCbParams &params)
af6691cc 173{
575d05c4
AJ
174 WhoisState *p = (WhoisState *)params.data;
175 debugs(75, 3, "whoisClose: FD " << params.fd);
1bfe9ade 176 p->entry->unlock("whoisClose");
c31bb519 177 delete p;
af6691cc 178}