]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/whois.cc
2 * Copyright (C) 1996-2014 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 size
, Comm::Flag flag
, int xerrno
, void *data
)
57 whoisStart(FwdState
* fwd
)
61 WhoisState
*p
= new WhoisState
;
62 p
->request
= fwd
->request
;
63 p
->entry
= fwd
->entry
;
65 p
->dataWritten
= false;
67 p
->entry
->lock("whoisStart");
68 comm_add_close_handler(fwd
->serverConnection()->fd
, whoisClose
, p
);
70 l
= p
->request
->urlpath
.size() + 3;
72 buf
= (char *)xmalloc(l
);
74 String str_print
=p
->request
->urlpath
.substr(1,p
->request
->urlpath
.size());
75 snprintf(buf
, l
, SQUIDSTRINGPH
"\r\n", SQUIDSTRINGPRINT(str_print
));
77 AsyncCall::Pointer writeCall
= commCbCall(5,5, "whoisWriteComplete",
78 CommIoCbPtrFun(whoisWriteComplete
, p
));
79 Comm::Write(fwd
->serverConnection(), buf
, strlen(buf
), writeCall
, NULL
);
80 AsyncCall::Pointer readCall
= commCbCall(5,4, "whoisReadReply",
81 CommIoCbPtrFun(whoisReadReply
, p
));
82 comm_read(fwd
->serverConnection(), p
->buf
, BUFSIZ
, readCall
);
83 AsyncCall::Pointer timeoutCall
= commCbCall(5, 4, "whoisTimeout",
84 CommTimeoutCbPtrFun(whoisTimeout
, p
));
85 commSetConnTimeout(fwd
->serverConnection(), Config
.Timeout
.read
, timeoutCall
);
91 whoisTimeout(const CommTimeoutCbParams
&io
)
93 WhoisState
*p
= static_cast<WhoisState
*>(io
.data
);
94 debugs(75, 3, HERE
<< io
.conn
<< ", URL " << p
->entry
->url());
99 whoisReadReply(const Comm::ConnectionPointer
&conn
, char *buf
, size_t len
, Comm::Flag flag
, int xerrno
, void *data
)
101 WhoisState
*p
= (WhoisState
*)data
;
102 p
->readReply(conn
, buf
, len
, flag
, xerrno
);
106 WhoisState::setReplyToOK(StoreEntry
*sentry
)
108 HttpReply
*reply
= new HttpReply
;
110 reply
->setHeaders(Http::scOkay
, "Gatewaying", "text/plain", -1, -1, -2);
111 sentry
->replaceHttpReply(reply
);
115 WhoisState::readReply(const Comm::ConnectionPointer
&conn
, char *aBuffer
, size_t aBufferLength
, Comm::Flag flag
, int xerrno
)
117 /* Bail out early on Comm::ERR_CLOSING - close handlers will tidy up for us */
118 if (flag
== Comm::ERR_CLOSING
)
121 aBuffer
[aBufferLength
] = '\0';
122 debugs(75, 3, HERE
<< conn
<< " read " << aBufferLength
<< " bytes");
123 debugs(75, 5, "{" << aBuffer
<< "}");
125 if (flag
!= Comm::OK
) {
126 debugs(50, 2, HERE
<< conn
<< ": read failure: " << xstrerror() << ".");
128 if (ignoreErrno(errno
)) {
129 AsyncCall::Pointer call
= commCbCall(5,4, "whoisReadReply",
130 CommIoCbPtrFun(whoisReadReply
, this));
131 comm_read(conn
, aBuffer
, BUFSIZ
, call
);
133 ErrorState
*err
= new ErrorState(ERR_READ_ERROR
, Http::scInternalServerError
, fwd
->request
);
134 err
->xerrno
= xerrno
;
141 if (aBufferLength
> 0) {
145 kb_incr(&(statCounter
.server
.all
.kbytes_in
), aBufferLength
);
146 kb_incr(&(statCounter
.server
.http
.kbytes_in
), aBufferLength
);
148 /* No range support, we always grab it all */
150 entry
->append(aBuffer
, aBufferLength
);
153 AsyncCall::Pointer call
= commCbCall(5,4, "whoisReadReply",
154 CommIoCbPtrFun(whoisReadReply
, this));
155 comm_read(conn
, aBuffer
, BUFSIZ
, call
);
159 /* no bytes read. stop reading */
160 entry
->timestampsSet();
166 debugs(75, 3, "whoisReadReply: Done: " << entry
->url());
171 whoisClose(const CommCloseCbParams
¶ms
)
173 WhoisState
*p
= (WhoisState
*)params
.data
;
174 debugs(75, 3, "whoisClose: FD " << params
.fd
);
175 p
->entry
->unlock("whoisClose");