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