]> git.ipfire.org Git - thirdparty/squid.git/blame - src/adaptation/icap/OptXact.cc
Partial bug #2964 fix: Do not leak HttpRequests that are not worth logging.
[thirdparty/squid.git] / src / adaptation / icap / OptXact.cc
CommitLineData
26cc52cb
AR
1/*
2 * DEBUG: section 93 ICAP (RFC 3507) Client
3 */
4
5#include "squid.h"
6#include "comm.h"
7#include "HttpReply.h"
8
9#include "adaptation/icap/OptXact.h"
10#include "adaptation/icap/Options.h"
83c51da9 11#include "adaptation/icap/Config.h"
3d93a84d 12#include "base/TextException.h"
3ff65596
AR
13#include "SquidTime.h"
14#include "HttpRequest.h"
26cc52cb
AR
15
16CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Icap, OptXact);
17CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Icap, OptXactLauncher);
18
19
4299f876 20Adaptation::Icap::OptXact::OptXact(Adaptation::Icap::ServiceRep::Pointer &aService):
26cc52cb 21 AsyncJob("Adaptation::Icap::OptXact"),
4299f876 22 Adaptation::Icap::Xaction("Adaptation::Icap::OptXact", aService)
26cc52cb
AR
23{
24}
25
26void Adaptation::Icap::OptXact::start()
27{
28 Adaptation::Icap::Xaction::start();
29
30 openConnection();
31}
32
33void Adaptation::Icap::OptXact::handleCommConnected()
34{
35 scheduleRead();
36
37 MemBuf requestBuf;
38 requestBuf.init();
39 makeRequest(requestBuf);
192378eb 40 debugs(93, 9, HERE << "request " << status() << ":\n" <<
26cc52cb 41 (requestBuf.terminate(), requestBuf.content()));
3ff65596 42 icap_tio_start = current_time;
26cc52cb
AR
43 scheduleWrite(requestBuf);
44}
45
46void Adaptation::Icap::OptXact::makeRequest(MemBuf &buf)
47{
48 const Adaptation::Service &s = service();
49 const String uri = s.cfg().uri;
50 buf.Printf("OPTIONS " SQUIDSTRINGPH " ICAP/1.0\r\n", SQUIDSTRINGPRINT(uri));
51 const String host = s.cfg().host;
52 buf.Printf("Host: " SQUIDSTRINGPH ":%d\r\n", SQUIDSTRINGPRINT(host), s.cfg().port);
83c51da9
CT
53 if (TheConfig.allow206_enable)
54 buf.Printf("Allow: 206\r\n");
26cc52cb 55 buf.append(ICAP::crlf, 2);
3ff65596
AR
56
57 // XXX: HttpRequest cannot fully parse ICAP Request-Line
b0365bd9
FC
58 http_status reqStatus;
59 Must(icapRequest->parse(&buf, true, &reqStatus) > 0);
26cc52cb
AR
60}
61
62void Adaptation::Icap::OptXact::handleCommWrote(size_t size)
63{
192378eb 64 debugs(93, 9, HERE << "finished writing " << size <<
26cc52cb
AR
65 "-byte request " << status());
66}
67
68// comm module read a portion of the ICAP response for us
69void Adaptation::Icap::OptXact::handleCommRead(size_t)
70{
c7d51c86 71 if (parseResponse()) {
3ff65596
AR
72 icap_tio_finish = current_time;
73 setOutcome(xoOpt);
c7d51c86 74 sendAnswer(icapReply);
26cc52cb
AR
75 Must(done()); // there should be nothing else to do
76 return;
77 }
78
79 scheduleRead();
80}
81
c7d51c86 82bool Adaptation::Icap::OptXact::parseResponse()
26cc52cb
AR
83{
84 debugs(93, 5, HERE << "have " << readBuf.contentSize() << " bytes to parse" <<
85 status());
86 debugs(93, 5, HERE << "\n" << readBuf.content());
87
c7d51c86 88 HttpReply::Pointer r(new HttpReply);
26cc52cb
AR
89 r->protoPrefix = "ICAP/"; // TODO: make an IcapReply class?
90
c7d51c86
AR
91 if (!parseHttpMsg(r)) // throws on errors
92 return false;
26cc52cb
AR
93
94 if (httpHeaderHasConnDir(&r->header, "close"))
95 reuseConnection = false;
96
c7d51c86
AR
97 icapReply = r;
98 return true;
26cc52cb
AR
99}
100
3ff65596
AR
101void Adaptation::Icap::OptXact::swanSong()
102{
103 Adaptation::Icap::Xaction::swanSong();
104}
105
106void Adaptation::Icap::OptXact::finalizeLogInfo()
107{
108 // al.cache.caddr = 0;
109 al.icap.reqMethod = Adaptation::methodOptions;
bae917ac
CT
110
111 if (icapReply && al.icap.bytesRead > icapReply->hdr_sz)
112 al.icap.bodyBytesRead = al.icap.bytesRead - icapReply->hdr_sz;
113
3ff65596
AR
114 Adaptation::Icap::Xaction::finalizeLogInfo();
115}
116
26cc52cb
AR
117/* Adaptation::Icap::OptXactLauncher */
118
4299f876 119Adaptation::Icap::OptXactLauncher::OptXactLauncher(Adaptation::ServicePointer aService):
26cc52cb 120 AsyncJob("Adaptation::Icap::OptXactLauncher"),
4299f876 121 Adaptation::Icap::Launcher("Adaptation::Icap::OptXactLauncher", aService)
26cc52cb
AR
122{
123}
124
125Adaptation::Icap::Xaction *Adaptation::Icap::OptXactLauncher::createXaction()
126{
127 Adaptation::Icap::ServiceRep::Pointer s =
128 dynamic_cast<Adaptation::Icap::ServiceRep*>(theService.getRaw());
129 Must(s != NULL);
4299f876 130 return new Adaptation::Icap::OptXact(s);
26cc52cb 131}