]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/whois.cc
2 * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
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.
9 /* DEBUG: section 75 WHOIS protocol */
13 #include "comm/Read.h"
14 #include "comm/Write.h"
15 #include "errorpage.h"
17 #include "HttpReply.h"
18 #include "HttpRequest.h"
19 #include "SquidConfig.h"
20 #include "StatCounters.h"
28 CBDATA_CLASS(WhoisState
);
31 void readReply(const Comm::ConnectionPointer
&, char *aBuffer
, size_t aBufferLength
, Comm::Flag flag
, int xerrno
);
32 void setReplyToOK(StoreEntry
*sentry
);
34 HttpRequest::Pointer request
;
35 FwdState::Pointer fwd
;
36 char buf
[BUFSIZ
+1]; /* readReply adds terminating NULL */
40 CBDATA_CLASS_INIT(WhoisState
);
42 static CLCB whoisClose
;
43 static CTCB whoisTimeout
;
44 static IOCB whoisReadReply
;
49 whoisWriteComplete(const Comm::ConnectionPointer
&, char *buf
, size_t, Comm::Flag
, int, void *)
55 whoisStart(FwdState
* fwd
)
57 WhoisState
*p
= new WhoisState
;
58 p
->request
= fwd
->request
;
59 p
->entry
= fwd
->entry
;
61 p
->dataWritten
= false;
63 p
->entry
->lock("whoisStart");
64 comm_add_close_handler(fwd
->serverConnection()->fd
, whoisClose
, p
);
66 size_t l
= p
->request
->url
.path().length() + 3;
67 char *buf
= (char *)xmalloc(l
);
69 const SBuf str_print
= p
->request
->url
.path().substr(1);
70 snprintf(buf
, l
, SQUIDSBUFPH
"\r\n", SQUIDSBUFPRINT(str_print
));
72 AsyncCall::Pointer writeCall
= commCbCall(5,5, "whoisWriteComplete",
73 CommIoCbPtrFun(whoisWriteComplete
, p
));
74 Comm::Write(fwd
->serverConnection(), buf
, strlen(buf
), writeCall
, NULL
);
75 AsyncCall::Pointer readCall
= commCbCall(5,4, "whoisReadReply",
76 CommIoCbPtrFun(whoisReadReply
, p
));
77 comm_read(fwd
->serverConnection(), p
->buf
, BUFSIZ
, readCall
);
78 AsyncCall::Pointer timeoutCall
= commCbCall(5, 4, "whoisTimeout",
79 CommTimeoutCbPtrFun(whoisTimeout
, p
));
80 commSetConnTimeout(fwd
->serverConnection(), Config
.Timeout
.read
, timeoutCall
);
86 whoisTimeout(const CommTimeoutCbParams
&io
)
88 WhoisState
*p
= static_cast<WhoisState
*>(io
.data
);
89 debugs(75, 3, HERE
<< io
.conn
<< ", URL " << p
->entry
->url());
94 whoisReadReply(const Comm::ConnectionPointer
&conn
, char *buf
, size_t len
, Comm::Flag flag
, int xerrno
, void *data
)
96 WhoisState
*p
= (WhoisState
*)data
;
97 p
->readReply(conn
, buf
, len
, flag
, xerrno
);
101 WhoisState::setReplyToOK(StoreEntry
*sentry
)
103 HttpReply
*reply
= new HttpReply
;
105 reply
->setHeaders(Http::scOkay
, "Gatewaying", "text/plain", -1, -1, -2);
106 reply
->sources
|= Http::Message::srcWhois
;
107 sentry
->replaceHttpReply(reply
);
111 WhoisState::readReply(const Comm::ConnectionPointer
&conn
, char *aBuffer
, size_t aBufferLength
, Comm::Flag flag
, int xerrno
)
113 /* Bail out early on Comm::ERR_CLOSING - close handlers will tidy up for us */
114 if (flag
== Comm::ERR_CLOSING
)
117 aBuffer
[aBufferLength
] = '\0';
118 debugs(75, 3, HERE
<< conn
<< " read " << aBufferLength
<< " bytes");
119 debugs(75, 5, "{" << aBuffer
<< "}");
121 // TODO: Honor delay pools.
123 // XXX: Update statCounter before bailing
124 if (!entry
->isAccepting()) {
125 debugs(52, 3, "terminating due to bad " << *entry
);
126 // TODO: Do not abuse connection for triggering cleanup.
131 if (flag
!= Comm::OK
) {
132 debugs(50, 2, conn
<< ": read failure: " << xstrerr(xerrno
));
134 if (ignoreErrno(xerrno
)) {
135 AsyncCall::Pointer call
= commCbCall(5,4, "whoisReadReply",
136 CommIoCbPtrFun(whoisReadReply
, this));
137 comm_read(conn
, aBuffer
, BUFSIZ
, call
);
139 const auto err
= new ErrorState(ERR_READ_ERROR
, Http::scInternalServerError
, fwd
->request
, fwd
->al
);
140 err
->xerrno
= xerrno
;
147 if (aBufferLength
> 0) {
151 statCounter
.server
.all
.kbytes_in
+= aBufferLength
;
152 statCounter
.server
.http
.kbytes_in
+= aBufferLength
;
154 /* No range support, we always grab it all */
156 entry
->append(aBuffer
, aBufferLength
);
159 AsyncCall::Pointer call
= commCbCall(5,4, "whoisReadReply",
160 CommIoCbPtrFun(whoisReadReply
, this));
161 comm_read(conn
, aBuffer
, BUFSIZ
, call
);
165 /* no bytes read. stop reading */
166 entry
->timestampsSet();
169 if (!entry
->makePublic())
170 entry
->makePrivate(true);
173 debugs(75, 3, "whoisReadReply: Done: " << entry
->url());
178 whoisClose(const CommCloseCbParams
¶ms
)
180 WhoisState
*p
= (WhoisState
*)params
.data
;
181 debugs(75, 3, "whoisClose: FD " << params
.fd
);
182 p
->entry
->unlock("whoisClose");