]> git.ipfire.org Git - thirdparty/squid.git/blob - src/ICAP/ICAPOptXact.cc
Adding ICAP library files
[thirdparty/squid.git] / src / ICAP / ICAPOptXact.cc
1 /*
2 * DEBUG: section 93 ICAP (RFC 3507) Client
3 */
4
5 #include "squid.h"
6 #include "comm.h"
7 #include "HttpReply.h"
8
9 #include "ICAPOptXact.h"
10 #include "ICAPOptions.h"
11 #include "TextException.h"
12
13 CBDATA_CLASS_INIT(ICAPOptXact);
14
15 ICAPOptXact::ICAPOptXact(): ICAPXaction("ICAPOptXact"), options(NULL),
16 cb(NULL), cbData(NULL)
17
18 {
19 debug(93,9)("ICAPOptXact constructed, this=%p\n", this);
20 }
21
22 ICAPOptXact::~ICAPOptXact()
23 {
24 Must(!options); // the caller must set to NULL
25 debug(93,9)("ICAPOptXact destructed, this=%p\n", this);
26 }
27
28 void ICAPOptXact::start(ICAPServiceRep::Pointer &aService, Callback *aCb, void *aCbData)
29 {
30 service(aService);
31
32 Must(!cb && aCb && aCbData);
33 cb = aCb;
34 cbData = cbdataReference(aCbData);
35
36 openConnection();
37 }
38
39 void ICAPOptXact::handleCommConnected()
40 {
41 scheduleRead();
42
43 MemBuf requestBuf;
44 requestBuf.init();
45 makeRequest(requestBuf);
46 debugs(93, 9, "ICAPOptXact request " << status() << ":\n" <<
47 (requestBuf.terminate(), requestBuf.content()));
48
49 scheduleWrite(requestBuf);
50 }
51
52 void ICAPOptXact::doStop()
53 {
54 ICAPXaction::doStop();
55
56 if (Callback *call = cb) {
57 cb = NULL;
58 void *data = NULL;
59
60 if (cbdataReferenceValidDone(cbData, &data)) {
61 (*call)(this, data); // will delete us
62 return;
63 }
64 }
65
66 // get rid of options if we did call the callback
67 delete options;
68
69 options = NULL;
70 }
71
72 void ICAPOptXact::makeRequest(MemBuf &buf)
73 {
74 const ICAPServiceRep &s = service();
75 buf.Printf("OPTIONS %s ICAP/1.0\r\n", s.uri.buf());
76 buf.Printf("Host: %s:%d\r\n", s.host.buf(), s.port);
77 buf.append(ICAP::crlf, 2);
78 }
79
80 void ICAPOptXact::handleCommWrote(size_t size)
81 {
82 debugs(93, 9, "ICAPOptXact finished writing " << size <<
83 "-byte request " << status());
84 }
85
86 // comm module read a portion of the ICAP response for us
87 void ICAPOptXact::handleCommRead(size_t)
88 {
89 if (parseResponse())
90 Must(done()); // there should be nothing else to do
91 else
92 scheduleRead();
93 }
94
95 bool ICAPOptXact::parseResponse()
96 {
97 HttpReply *r = new HttpReply;
98 r->protoPrefix = "ICAP/"; // TODO: make an IcapReply class?
99
100 if (!parseHttpMsg(r)) {
101 delete r;
102 return false;
103 }
104
105 options = new ICAPOptions;
106
107 options->configure(r);
108
109 delete r;
110 return true;
111 }