]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/adaptation/icap/OptXact.cc
d463faf31630fbd39aa076faea740c6de92b26b3
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 93 ICAP (RFC 3507) Client */
12 #include "adaptation/Answer.h"
13 #include "adaptation/icap/Config.h"
14 #include "adaptation/icap/Options.h"
15 #include "adaptation/icap/OptXact.h"
16 #include "base/TextException.h"
18 #include "HttpHeaderTools.h"
19 #include "HttpReply.h"
20 #include "HttpRequest.h"
21 #include "SquidTime.h"
23 CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Icap
, OptXact
);
24 CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Icap
, OptXactLauncher
);
26 Adaptation::Icap::OptXact::OptXact(Adaptation::Icap::ServiceRep::Pointer
&aService
):
27 AsyncJob("Adaptation::Icap::OptXact"),
28 Adaptation::Icap::Xaction("Adaptation::Icap::OptXact", aService
),
33 void Adaptation::Icap::OptXact::start()
35 Adaptation::Icap::Xaction::start();
40 void Adaptation::Icap::OptXact::handleCommConnected()
46 makeRequest(requestBuf
);
47 debugs(93, 9, HERE
<< "request " << status() << ":\n" <<
48 (requestBuf
.terminate(), requestBuf
.content()));
49 icap_tio_start
= current_time
;
50 scheduleWrite(requestBuf
);
53 void Adaptation::Icap::OptXact::makeRequest(MemBuf
&buf
)
55 const Adaptation::Service
&s
= service();
56 const String uri
= s
.cfg().uri
;
57 buf
.appendf("OPTIONS " SQUIDSTRINGPH
" ICAP/1.0\r\n", SQUIDSTRINGPRINT(uri
));
58 const String host
= s
.cfg().host
;
59 buf
.appendf("Host: " SQUIDSTRINGPH
":%d\r\n", SQUIDSTRINGPRINT(host
), s
.cfg().port
);
61 if (!TheConfig
.reuse_connections
)
62 buf
.append("Connection: close\r\n", 19);
64 buf
.append("Allow: ", 7);
65 if (TheConfig
.allow206_enable
)
66 buf
.append("206, ", 5);
67 buf
.append("trailers\r\n", 10);
68 buf
.append(ICAP::crlf
, 2);
70 // XXX: HttpRequest cannot fully parse ICAP Request-Line
71 Http::StatusCode reqStatus
;
72 buf
.terminate(); // Http::Message::parse requires terminated buffer
73 Must(icapRequest
->parse(buf
.content(), buf
.contentSize(), true, &reqStatus
) > 0);
76 void Adaptation::Icap::OptXact::handleCommWrote(size_t size
)
78 debugs(93, 9, HERE
<< "finished writing " << size
<<
79 "-byte request " << status());
82 // comm module read a portion of the ICAP response for us
83 void Adaptation::Icap::OptXact::handleCommRead(size_t)
85 if (parseResponse()) {
86 Must(icapReply
!= NULL
);
87 // We read everything if there is no response body. If there is a body,
88 // we cannot parse it because we do not support any opt-body-types, so
89 // we leave readAll false which forces connection closure.
90 readAll
= icapReply
->header
.getByNameListMember("Encapsulated",
91 "opt-body", ',').isEmpty();
92 debugs(93, 7, HERE
<< "readAll=" << readAll
);
93 icap_tio_finish
= current_time
;
95 sendAnswer(Answer::Forward(icapReply
.getRaw()));
96 Must(done()); // there should be nothing else to do
103 bool Adaptation::Icap::OptXact::parseResponse()
105 debugs(93, 5, "have " << readBuf
.length() << " bytes to parse" << status());
106 debugs(93, DBG_DATA
, "\n" << readBuf
);
108 HttpReply::Pointer
r(new HttpReply
);
109 r
->protoPrefix
= "ICAP/"; // TODO: make an IcapReply class?
111 if (!parseHttpMsg(r
.getRaw())) // throws on errors
114 static SBuf
close("close", 5);
115 if (httpHeaderHasConnDir(&r
->header
, close
))
116 reuseConnection
= false;
122 void Adaptation::Icap::OptXact::swanSong()
124 Adaptation::Icap::Xaction::swanSong();
127 void Adaptation::Icap::OptXact::finalizeLogInfo()
129 // al.cache.caddr = 0;
130 al
.icap
.reqMethod
= Adaptation::methodOptions
;
132 if (icapReply
!= NULL
&& al
.icap
.bytesRead
> icapReply
->hdr_sz
)
133 al
.icap
.bodyBytesRead
= al
.icap
.bytesRead
- icapReply
->hdr_sz
;
135 Adaptation::Icap::Xaction::finalizeLogInfo();
138 /* Adaptation::Icap::OptXactLauncher */
140 Adaptation::Icap::OptXactLauncher::OptXactLauncher(Adaptation::ServicePointer aService
):
141 AsyncJob("Adaptation::Icap::OptXactLauncher"),
142 Adaptation::Icap::Launcher("Adaptation::Icap::OptXactLauncher", aService
)
146 Adaptation::Icap::Xaction
*Adaptation::Icap::OptXactLauncher::createXaction()
148 Adaptation::Icap::ServiceRep::Pointer s
=
149 dynamic_cast<Adaptation::Icap::ServiceRep
*>(theService
.getRaw());
151 return new Adaptation::Icap::OptXact(s
);