]> git.ipfire.org Git - thirdparty/squid.git/blame - src/ICAP/ICAPOptXact.cc
- Many ICAP fixes from Alex Rousskov accumulated on the
[thirdparty/squid.git] / src / ICAP / ICAPOptXact.cc
CommitLineData
774c051c 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
13CBDATA_CLASS_INIT(ICAPOptXact);
14
15ICAPOptXact::ICAPOptXact(): ICAPXaction("ICAPOptXact"), options(NULL),
16 cb(NULL), cbData(NULL)
17
18{
774c051c 19}
20
21ICAPOptXact::~ICAPOptXact()
22{
23 Must(!options); // the caller must set to NULL
774c051c 24}
25
26void ICAPOptXact::start(ICAPServiceRep::Pointer &aService, Callback *aCb, void *aCbData)
27{
c99de607 28 ICAPXaction_Enter(start);
774c051c 29 service(aService);
30
31 Must(!cb && aCb && aCbData);
32 cb = aCb;
33 cbData = cbdataReference(aCbData);
34
35 openConnection();
c99de607 36
37 ICAPXaction_Exit();
774c051c 38}
39
40void ICAPOptXact::handleCommConnected()
41{
42 scheduleRead();
43
44 MemBuf requestBuf;
45 requestBuf.init();
46 makeRequest(requestBuf);
47 debugs(93, 9, "ICAPOptXact request " << status() << ":\n" <<
48 (requestBuf.terminate(), requestBuf.content()));
49
50 scheduleWrite(requestBuf);
51}
52
c99de607 53bool ICAPOptXact::doneAll() const
54{
55 return options && ICAPXaction::doneAll();
56}
57
58
774c051c 59void ICAPOptXact::doStop()
60{
61 ICAPXaction::doStop();
62
63 if (Callback *call = cb) {
64 cb = NULL;
65 void *data = NULL;
66
67 if (cbdataReferenceValidDone(cbData, &data)) {
68 (*call)(this, data); // will delete us
69 return;
70 }
71 }
72
c99de607 73 // get rid of options if we did not call the callback
774c051c 74 delete options;
75
76 options = NULL;
77}
78
79void ICAPOptXact::makeRequest(MemBuf &buf)
80{
81 const ICAPServiceRep &s = service();
82 buf.Printf("OPTIONS %s ICAP/1.0\r\n", s.uri.buf());
83 buf.Printf("Host: %s:%d\r\n", s.host.buf(), s.port);
84 buf.append(ICAP::crlf, 2);
85}
86
87void ICAPOptXact::handleCommWrote(size_t size)
88{
89 debugs(93, 9, "ICAPOptXact finished writing " << size <<
90 "-byte request " << status());
91}
92
93// comm module read a portion of the ICAP response for us
94void ICAPOptXact::handleCommRead(size_t)
95{
96 if (parseResponse())
97 Must(done()); // there should be nothing else to do
98 else
99 scheduleRead();
100}
101
102bool ICAPOptXact::parseResponse()
103{
c99de607 104 debugs(93, 5, HERE << "have " << readBuf.contentSize() << " bytes to parse" <<
105 status());
106 debugs(93, 5, HERE << "\n" << readBuf.content());
107
774c051c 108 HttpReply *r = new HttpReply;
109 r->protoPrefix = "ICAP/"; // TODO: make an IcapReply class?
110
111 if (!parseHttpMsg(r)) {
112 delete r;
113 return false;
114 }
115
116 options = new ICAPOptions;
117
118 options->configure(r);
119
b0ea5e03 120 if (httpHeaderHasConnDir(&r->header, "close"))
121 reuseConnection = false;
122
774c051c 123 delete r;
b0ea5e03 124
774c051c 125 return true;
126}