]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/adaptation/icap/OptXact.cc
2 * DEBUG: section 93 ICAP (RFC 3507) Client
9 #include "adaptation/Answer.h"
10 #include "adaptation/icap/OptXact.h"
11 #include "adaptation/icap/Options.h"
12 #include "adaptation/icap/Config.h"
13 #include "base/TextException.h"
14 #include "SquidTime.h"
15 #include "HttpRequest.h"
17 CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Icap
, OptXact
);
18 CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Icap
, OptXactLauncher
);
21 Adaptation::Icap::OptXact::OptXact(Adaptation::Icap::ServiceRep::Pointer
&aService
):
22 AsyncJob("Adaptation::Icap::OptXact"),
23 Adaptation::Icap::Xaction("Adaptation::Icap::OptXact", aService
),
28 void Adaptation::Icap::OptXact::start()
30 Adaptation::Icap::Xaction::start();
35 void Adaptation::Icap::OptXact::handleCommConnected()
41 makeRequest(requestBuf
);
42 debugs(93, 9, HERE
<< "request " << status() << ":\n" <<
43 (requestBuf
.terminate(), requestBuf
.content()));
44 icap_tio_start
= current_time
;
45 scheduleWrite(requestBuf
);
48 void Adaptation::Icap::OptXact::makeRequest(MemBuf
&buf
)
50 const Adaptation::Service
&s
= service();
51 const String uri
= s
.cfg().uri
;
52 buf
.Printf("OPTIONS " SQUIDSTRINGPH
" ICAP/1.0\r\n", SQUIDSTRINGPRINT(uri
));
53 const String host
= s
.cfg().host
;
54 buf
.Printf("Host: " SQUIDSTRINGPH
":%d\r\n", SQUIDSTRINGPRINT(host
), s
.cfg().port
);
55 if (TheConfig
.allow206_enable
)
56 buf
.Printf("Allow: 206\r\n");
57 buf
.append(ICAP::crlf
, 2);
59 // XXX: HttpRequest cannot fully parse ICAP Request-Line
60 http_status reqStatus
;
61 Must(icapRequest
->parse(&buf
, true, &reqStatus
) > 0);
64 void Adaptation::Icap::OptXact::handleCommWrote(size_t size
)
66 debugs(93, 9, HERE
<< "finished writing " << size
<<
67 "-byte request " << status());
70 // comm module read a portion of the ICAP response for us
71 void Adaptation::Icap::OptXact::handleCommRead(size_t)
73 if (parseResponse()) {
74 Must(icapReply
!= NULL
);
75 // We read everything if there is no response body. If there is a body,
76 // we cannot parse it because we do not support any opt-body-types, so
77 // we leave readAll false which forces connection closure.
78 readAll
= !icapReply
->header
.getByNameListMember("Encapsulated",
79 "opt-body", ',').size();
80 debugs(93, 7, HERE
<< "readAll=" << readAll
);
81 icap_tio_finish
= current_time
;
83 sendAnswer(Answer::Forward(icapReply
));
84 Must(done()); // there should be nothing else to do
91 bool Adaptation::Icap::OptXact::parseResponse()
93 debugs(93, 5, HERE
<< "have " << readBuf
.contentSize() << " bytes to parse" <<
95 debugs(93, 5, HERE
<< "\n" << readBuf
.content());
97 HttpReply::Pointer
r(new HttpReply
);
98 r
->protoPrefix
= "ICAP/"; // TODO: make an IcapReply class?
100 if (!parseHttpMsg(r
)) // throws on errors
103 if (httpHeaderHasConnDir(&r
->header
, "close"))
104 reuseConnection
= false;
110 void Adaptation::Icap::OptXact::swanSong()
112 Adaptation::Icap::Xaction::swanSong();
115 void Adaptation::Icap::OptXact::finalizeLogInfo()
117 // al.cache.caddr = 0;
118 al
.icap
.reqMethod
= Adaptation::methodOptions
;
120 if (icapReply
&& al
.icap
.bytesRead
> icapReply
->hdr_sz
)
121 al
.icap
.bodyBytesRead
= al
.icap
.bytesRead
- icapReply
->hdr_sz
;
123 Adaptation::Icap::Xaction::finalizeLogInfo();
126 /* Adaptation::Icap::OptXactLauncher */
128 Adaptation::Icap::OptXactLauncher::OptXactLauncher(Adaptation::ServicePointer aService
):
129 AsyncJob("Adaptation::Icap::OptXactLauncher"),
130 Adaptation::Icap::Launcher("Adaptation::Icap::OptXactLauncher", aService
)
134 Adaptation::Icap::Xaction
*Adaptation::Icap::OptXactLauncher::createXaction()
136 Adaptation::Icap::ServiceRep::Pointer s
=
137 dynamic_cast<Adaptation::Icap::ServiceRep
*>(theService
.getRaw());
139 return new Adaptation::Icap::OptXact(s
);