]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/adaptation/icap/OptXact.cc
2 * Copyright (C) 1996-2022 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"
22 CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Icap
, OptXact
);
23 CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Icap
, OptXactLauncher
);
25 Adaptation::Icap::OptXact::OptXact(Adaptation::Icap::ServiceRep::Pointer
&aService
):
26 AsyncJob("Adaptation::Icap::OptXact"),
27 Adaptation::Icap::Xaction("Adaptation::Icap::OptXact", aService
),
32 void Adaptation::Icap::OptXact::start()
34 Adaptation::Icap::Xaction::start();
39 void Adaptation::Icap::OptXact::startShoveling()
45 makeRequest(requestBuf
);
46 debugs(93, 9, "request " << status() << ":\n" <<
47 (requestBuf
.terminate(), requestBuf
.content()));
48 icap_tio_start
= current_time
;
49 scheduleWrite(requestBuf
);
52 void Adaptation::Icap::OptXact::makeRequest(MemBuf
&buf
)
54 const Adaptation::Service
&s
= service();
55 const String uri
= s
.cfg().uri
;
56 buf
.appendf("OPTIONS " SQUIDSTRINGPH
" ICAP/1.0\r\n", SQUIDSTRINGPRINT(uri
));
57 const String host
= s
.cfg().host
;
58 buf
.appendf("Host: " SQUIDSTRINGPH
":%d\r\n", SQUIDSTRINGPRINT(host
), s
.cfg().port
);
60 if (!TheConfig
.reuse_connections
)
61 buf
.append("Connection: close\r\n", 19);
63 buf
.append("Allow: ", 7);
64 if (TheConfig
.allow206_enable
)
65 buf
.append("206, ", 5);
66 buf
.append("trailers\r\n", 10);
67 buf
.append(ICAP::crlf
, 2);
69 // XXX: HttpRequest cannot fully parse ICAP Request-Line
70 Http::StatusCode reqStatus
;
71 buf
.terminate(); // Http::Message::parse requires terminated buffer
72 Must(icapRequest
->parse(buf
.content(), buf
.contentSize(), true, &reqStatus
) > 0);
75 void Adaptation::Icap::OptXact::handleCommWrote(size_t size
)
77 debugs(93, 9, "finished writing " << size
<<
78 "-byte request " << status());
81 // comm module read a portion of the ICAP response for us
82 void Adaptation::Icap::OptXact::handleCommRead(size_t)
84 if (parseResponse()) {
85 Must(icapReply
!= NULL
);
86 // We read everything if there is no response body. If there is a body,
87 // we cannot parse it because we do not support any opt-body-types, so
88 // we leave readAll false which forces connection closure.
89 readAll
= icapReply
->header
.getByNameListMember("Encapsulated",
90 "opt-body", ',').isEmpty();
91 debugs(93, 7, "readAll=" << readAll
);
92 icap_tio_finish
= current_time
;
94 sendAnswer(Answer::Forward(icapReply
.getRaw()));
95 Must(done()); // there should be nothing else to do
102 bool Adaptation::Icap::OptXact::parseResponse()
104 debugs(93, 5, "have " << readBuf
.length() << " bytes to parse" << status());
105 debugs(93, DBG_DATA
, "\n" << readBuf
);
107 HttpReply::Pointer
r(new HttpReply
);
108 r
->protoPrefix
= "ICAP/"; // TODO: make an IcapReply class?
110 if (!parseHttpMsg(r
.getRaw())) // throws on errors
113 static SBuf
close("close", 5);
114 if (httpHeaderHasConnDir(&r
->header
, close
))
115 reuseConnection
= false;
121 void Adaptation::Icap::OptXact::swanSong()
123 Adaptation::Icap::Xaction::swanSong();
126 void Adaptation::Icap::OptXact::finalizeLogInfo()
128 // al.cache.caddr = 0;
129 al
.icap
.reqMethod
= Adaptation::methodOptions
;
131 if (icapReply
!= NULL
&& al
.icap
.bytesRead
> icapReply
->hdr_sz
)
132 al
.icap
.bodyBytesRead
= al
.icap
.bytesRead
- icapReply
->hdr_sz
;
134 Adaptation::Icap::Xaction::finalizeLogInfo();
137 /* Adaptation::Icap::OptXactLauncher */
139 Adaptation::Icap::OptXactLauncher::OptXactLauncher(Adaptation::ServicePointer aService
):
140 AsyncJob("Adaptation::Icap::OptXactLauncher"),
141 Adaptation::Icap::Launcher("Adaptation::Icap::OptXactLauncher", aService
)
145 Adaptation::Icap::Xaction
*Adaptation::Icap::OptXactLauncher::createXaction()
147 Adaptation::Icap::ServiceRep::Pointer s
=
148 dynamic_cast<Adaptation::Icap::ServiceRep
*>(theService
.getRaw());
150 return new Adaptation::Icap::OptXact(s
);