]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/adaptation/icap/OptXact.cc
2 * DEBUG: section 93 ICAP (RFC 3507) Client
6 #include "adaptation/Answer.h"
7 #include "adaptation/icap/Config.h"
8 #include "adaptation/icap/Options.h"
9 #include "adaptation/icap/OptXact.h"
10 #include "base/TextException.h"
12 #include "HttpReply.h"
13 #include "HttpRequest.h"
15 #include "SquidTime.h"
17 CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Icap
, OptXact
);
18 CBDATA_NAMESPACED_CLASS_INIT(Adaptation::Icap
, OptXactLauncher
);
20 Adaptation::Icap::OptXact::OptXact(Adaptation::Icap::ServiceRep::Pointer
&aService
):
21 AsyncJob("Adaptation::Icap::OptXact"),
22 Adaptation::Icap::Xaction("Adaptation::Icap::OptXact", aService
),
27 void Adaptation::Icap::OptXact::start()
29 Adaptation::Icap::Xaction::start();
34 void Adaptation::Icap::OptXact::handleCommConnected()
40 makeRequest(requestBuf
);
41 debugs(93, 9, HERE
<< "request " << status() << ":\n" <<
42 (requestBuf
.terminate(), requestBuf
.content()));
43 icap_tio_start
= current_time
;
44 scheduleWrite(requestBuf
);
47 void Adaptation::Icap::OptXact::makeRequest(MemBuf
&buf
)
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
);
54 if (TheConfig
.allow206_enable
)
55 buf
.Printf("Allow: 206\r\n");
56 buf
.append(ICAP::crlf
, 2);
58 // XXX: HttpRequest cannot fully parse ICAP Request-Line
59 http_status reqStatus
;
60 Must(icapRequest
->parse(&buf
, true, &reqStatus
) > 0);
63 void Adaptation::Icap::OptXact::handleCommWrote(size_t size
)
65 debugs(93, 9, HERE
<< "finished writing " << size
<<
66 "-byte request " << status());
69 // comm module read a portion of the ICAP response for us
70 void Adaptation::Icap::OptXact::handleCommRead(size_t)
72 if (parseResponse()) {
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",
78 "opt-body", ',').size();
79 debugs(93, 7, HERE
<< "readAll=" << readAll
);
80 icap_tio_finish
= current_time
;
82 sendAnswer(Answer::Forward(icapReply
));
83 Must(done()); // there should be nothing else to do
90 bool Adaptation::Icap::OptXact::parseResponse()
92 debugs(93, 5, HERE
<< "have " << readBuf
.contentSize() << " bytes to parse" <<
94 debugs(93, 5, HERE
<< "\n" << readBuf
.content());
96 HttpReply::Pointer
r(new HttpReply
);
97 r
->protoPrefix
= "ICAP/"; // TODO: make an IcapReply class?
99 if (!parseHttpMsg(r
)) // throws on errors
102 if (httpHeaderHasConnDir(&r
->header
, "close"))
103 reuseConnection
= false;
109 void Adaptation::Icap::OptXact::swanSong()
111 Adaptation::Icap::Xaction::swanSong();
114 void Adaptation::Icap::OptXact::finalizeLogInfo()
116 // al.cache.caddr = 0;
117 al
.icap
.reqMethod
= Adaptation::methodOptions
;
119 if (icapReply
&& al
.icap
.bytesRead
> icapReply
->hdr_sz
)
120 al
.icap
.bodyBytesRead
= al
.icap
.bytesRead
- icapReply
->hdr_sz
;
122 Adaptation::Icap::Xaction::finalizeLogInfo();
125 /* Adaptation::Icap::OptXactLauncher */
127 Adaptation::Icap::OptXactLauncher::OptXactLauncher(Adaptation::ServicePointer aService
):
128 AsyncJob("Adaptation::Icap::OptXactLauncher"),
129 Adaptation::Icap::Launcher("Adaptation::Icap::OptXactLauncher", aService
)
133 Adaptation::Icap::Xaction
*Adaptation::Icap::OptXactLauncher::createXaction()
135 Adaptation::Icap::ServiceRep::Pointer s
=
136 dynamic_cast<Adaptation::Icap::ServiceRep
*>(theService
.getRaw());
138 return new Adaptation::Icap::OptXact(s
);