]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/whois.cc
2 * Copyright (C) 1996-2017 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"
30 CBDATA_CLASS(WhoisState
);
33 void readReply(const Comm::ConnectionPointer
&, char *aBuffer
, size_t aBufferLength
, Comm::Flag flag
, int xerrno
);
34 void setReplyToOK(StoreEntry
*sentry
);
36 HttpRequest::Pointer request
;
37 FwdState::Pointer fwd
;
38 char buf
[BUFSIZ
+1]; /* readReply adds terminating NULL */
42 CBDATA_CLASS_INIT(WhoisState
);
44 static CLCB whoisClose
;
45 static CTCB whoisTimeout
;
46 static IOCB whoisReadReply
;
51 whoisWriteComplete(const Comm::ConnectionPointer
&, char *buf
, size_t, Comm::Flag
, int, void *)
57 whoisStart(FwdState
* fwd
)
59 WhoisState
*p
= new WhoisState
;
60 p
->request
= fwd
->request
;
61 p
->entry
= fwd
->entry
;
63 p
->dataWritten
= false;
65 p
->entry
->lock("whoisStart");
66 comm_add_close_handler(fwd
->serverConnection()->fd
, whoisClose
, p
);
68 size_t l
= p
->request
->url
.path().length() + 3;
69 char *buf
= (char *)xmalloc(l
);
71 const SBuf str_print
= p
->request
->url
.path().substr(1);
72 snprintf(buf
, l
, SQUIDSBUFPH
"\r\n", SQUIDSBUFPRINT(str_print
));
74 AsyncCall::Pointer writeCall
= commCbCall(5,5, "whoisWriteComplete",
75 CommIoCbPtrFun(whoisWriteComplete
, p
));
76 Comm::Write(fwd
->serverConnection(), buf
, strlen(buf
), writeCall
, NULL
);
77 AsyncCall::Pointer readCall
= commCbCall(5,4, "whoisReadReply",
78 CommIoCbPtrFun(whoisReadReply
, p
));
79 comm_read(fwd
->serverConnection(), p
->buf
, BUFSIZ
, readCall
);
80 AsyncCall::Pointer timeoutCall
= commCbCall(5, 4, "whoisTimeout",
81 CommTimeoutCbPtrFun(whoisTimeout
, p
));
82 commSetConnTimeout(fwd
->serverConnection(), Config
.Timeout
.read
, timeoutCall
);
88 whoisTimeout(const CommTimeoutCbParams
&io
)
90 WhoisState
*p
= static_cast<WhoisState
*>(io
.data
);
91 debugs(75, 3, HERE
<< io
.conn
<< ", URL " << p
->entry
->url());
96 whoisReadReply(const Comm::ConnectionPointer
&conn
, char *buf
, size_t len
, Comm::Flag flag
, int xerrno
, void *data
)
98 WhoisState
*p
= (WhoisState
*)data
;
99 p
->readReply(conn
, buf
, len
, flag
, xerrno
);
103 WhoisState::setReplyToOK(StoreEntry
*sentry
)
105 HttpReply
*reply
= new HttpReply
;
107 reply
->setHeaders(Http::scOkay
, "Gatewaying", "text/plain", -1, -1, -2);
108 reply
->sources
|= HttpMsg::srcWhois
;
109 sentry
->replaceHttpReply(reply
);
113 WhoisState::readReply(const Comm::ConnectionPointer
&conn
, char *aBuffer
, size_t aBufferLength
, Comm::Flag flag
, int xerrno
)
115 /* Bail out early on Comm::ERR_CLOSING - close handlers will tidy up for us */
116 if (flag
== Comm::ERR_CLOSING
)
119 aBuffer
[aBufferLength
] = '\0';
120 debugs(75, 3, HERE
<< conn
<< " read " << aBufferLength
<< " bytes");
121 debugs(75, 5, "{" << aBuffer
<< "}");
123 if (flag
!= Comm::OK
) {
124 debugs(50, 2, conn
<< ": read failure: " << xstrerr(xerrno
));
126 if (ignoreErrno(xerrno
)) {
127 AsyncCall::Pointer call
= commCbCall(5,4, "whoisReadReply",
128 CommIoCbPtrFun(whoisReadReply
, this));
129 comm_read(conn
, aBuffer
, BUFSIZ
, call
);
131 ErrorState
*err
= new ErrorState(ERR_READ_ERROR
, Http::scInternalServerError
, fwd
->request
);
132 err
->xerrno
= xerrno
;
139 if (aBufferLength
> 0) {
143 statCounter
.server
.all
.kbytes_in
+= aBufferLength
;
144 statCounter
.server
.http
.kbytes_in
+= aBufferLength
;
146 /* No range support, we always grab it all */
148 entry
->append(aBuffer
, aBufferLength
);
151 AsyncCall::Pointer call
= commCbCall(5,4, "whoisReadReply",
152 CommIoCbPtrFun(whoisReadReply
, this));
153 comm_read(conn
, aBuffer
, BUFSIZ
, call
);
157 /* no bytes read. stop reading */
158 entry
->timestampsSet();
164 debugs(75, 3, "whoisReadReply: Done: " << entry
->url());
169 whoisClose(const CommCloseCbParams
¶ms
)
171 WhoisState
*p
= (WhoisState
*)params
.data
;
172 debugs(75, 3, "whoisClose: FD " << params
.fd
);
173 p
->entry
->unlock("whoisClose");