]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/adaptation/icap/OptXact.cc
2 * Copyright (C) 1996-2015 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
.Printf("OPTIONS " SQUIDSTRINGPH
" ICAP/1.0\r\n", SQUIDSTRINGPRINT(uri
));
58 const String host
= s
.cfg().host
;
59 buf
.Printf("Host: " SQUIDSTRINGPH
":%d\r\n", SQUIDSTRINGPRINT(host
), s
.cfg().port
);
61 if (!TheConfig
.reuse_connections
)
62 buf
.Printf("Connection: close\r\n");
64 if (TheConfig
.allow206_enable
)
65 buf
.Printf("Allow: 206\r\n");
66 buf
.append(ICAP::crlf
, 2);
68 // XXX: HttpRequest cannot fully parse ICAP Request-Line
69 Http::StatusCode reqStatus
;
70 Must(icapRequest
->parse(&buf
, true, &reqStatus
) > 0);
73 void Adaptation::Icap::OptXact::handleCommWrote(size_t size
)
75 debugs(93, 9, HERE
<< "finished writing " << size
<<
76 "-byte request " << status());
79 // comm module read a portion of the ICAP response for us
80 void Adaptation::Icap::OptXact::handleCommRead(size_t)
82 if (parseResponse()) {
83 Must(icapReply
!= NULL
);
84 // We read everything if there is no response body. If there is a body,
85 // we cannot parse it because we do not support any opt-body-types, so
86 // we leave readAll false which forces connection closure.
87 readAll
= !icapReply
->header
.getByNameListMember("Encapsulated",
88 "opt-body", ',').size();
89 debugs(93, 7, HERE
<< "readAll=" << readAll
);
90 icap_tio_finish
= current_time
;
92 sendAnswer(Answer::Forward(icapReply
.getRaw()));
93 Must(done()); // there should be nothing else to do
100 bool Adaptation::Icap::OptXact::parseResponse()
102 debugs(93, 5, HERE
<< "have " << readBuf
.contentSize() << " bytes to parse" <<
104 debugs(93, 5, HERE
<< "\n" << readBuf
.content());
106 HttpReply::Pointer
r(new HttpReply
);
107 r
->protoPrefix
= "ICAP/"; // TODO: make an IcapReply class?
109 if (!parseHttpMsg(r
.getRaw())) // throws on errors
112 if (httpHeaderHasConnDir(&r
->header
, "close"))
113 reuseConnection
= false;
119 void Adaptation::Icap::OptXact::swanSong()
121 Adaptation::Icap::Xaction::swanSong();
124 void Adaptation::Icap::OptXact::finalizeLogInfo()
126 // al.cache.caddr = 0;
127 al
.icap
.reqMethod
= Adaptation::methodOptions
;
129 if (icapReply
!= NULL
&& al
.icap
.bytesRead
> icapReply
->hdr_sz
)
130 al
.icap
.bodyBytesRead
= al
.icap
.bytesRead
- icapReply
->hdr_sz
;
132 Adaptation::Icap::Xaction::finalizeLogInfo();
135 /* Adaptation::Icap::OptXactLauncher */
137 Adaptation::Icap::OptXactLauncher::OptXactLauncher(Adaptation::ServicePointer aService
):
138 AsyncJob("Adaptation::Icap::OptXactLauncher"),
139 Adaptation::Icap::Launcher("Adaptation::Icap::OptXactLauncher", aService
)
143 Adaptation::Icap::Xaction
*Adaptation::Icap::OptXactLauncher::createXaction()
145 Adaptation::Icap::ServiceRep::Pointer s
=
146 dynamic_cast<Adaptation::Icap::ServiceRep
*>(theService
.getRaw());
148 return new Adaptation::Icap::OptXact(s
);