]> git.ipfire.org Git - thirdparty/squid.git/blame - src/servers/Server.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / servers / Server.cc
CommitLineData
fcc444e3 1/*
ef57eb7b 2 * Copyright (C) 1996-2016 The Squid Software Foundation and contributors
fcc444e3
AJ
3 *
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.
7 */
8
9#include "squid.h"
10#include "anyp/PortCfg.h"
c6ae1627 11#include "client_side.h"
fcc444e3
AJ
12#include "comm.h"
13#include "comm/Read.h"
14#include "Debug.h"
15#include "fd.h"
16#include "fde.h"
17#include "MasterXaction.h"
18#include "servers/Server.h"
19#include "SquidConfig.h"
20#include "StatCounters.h"
21#include "tools.h"
22
23Server::Server(const MasterXaction::Pointer &xact) :
24 AsyncJob("::Server"), // kids overwrite
25 clientConnection(xact->tcpClient),
26 transferProtocol(xact->squidPort->transport),
27 port(xact->squidPort),
28 receivedFirstByte_(false)
29{}
30
31bool
32Server::doneAll() const
33{
34 // servers are not done while the connection is open
35 return !Comm::IsConnOpen(clientConnection) &&
36 BodyProducer::doneAll();
37}
38
39void
40Server::start()
41{
42 // TODO: shuffle activity from ConnStateData
43}
44
45void
46Server::swanSong()
47{
48 if (Comm::IsConnOpen(clientConnection))
49 clientConnection->close();
50
51 BodyProducer::swanSong();
52}
53
54void
55Server::stopReading()
56{
57 if (reading()) {
58 Comm::ReadCancel(clientConnection->fd, reader);
59 reader = NULL;
60 }
61}
62
63bool
64Server::maybeMakeSpaceAvailable()
65{
66 if (inBuf.spaceSize() < 2) {
67 const SBuf::size_type haveCapacity = inBuf.length() + inBuf.spaceSize();
68 if (haveCapacity >= Config.maxRequestBufferSize) {
69 debugs(33, 4, "request buffer full: client_request_buffer_max_size=" << Config.maxRequestBufferSize);
70 return false;
71 }
72 if (haveCapacity == 0) {
73 // haveCapacity is based on the SBuf visible window of the MemBlob buffer, which may fill up.
74 // at which point bump the buffer back to default. This allocates a new MemBlob with any un-parsed bytes.
75 inBuf.reserveCapacity(CLIENT_REQ_BUF_SZ);
76 } else {
77 const SBuf::size_type wantCapacity = min(static_cast<SBuf::size_type>(Config.maxRequestBufferSize), haveCapacity*2);
78 inBuf.reserveCapacity(wantCapacity);
79 }
80 debugs(33, 2, "growing request buffer: available=" << inBuf.spaceSize() << " used=" << inBuf.length());
81 }
82 return (inBuf.spaceSize() >= 2);
83}
84
85void
86Server::readSomeData()
87{
88 if (reading())
89 return;
90
91 debugs(33, 4, clientConnection << ": reading request...");
92
93 // we can only read if there is more than 1 byte of space free
94 if (Config.maxRequestBufferSize - inBuf.length() < 2)
95 return;
96
97 typedef CommCbMemFunT<Server, CommIoCbParams> Dialer;
98 reader = JobCallback(33, 5, Dialer, this, Server::doClientRead);
99 Comm::Read(clientConnection, reader);
100}
101
102void
103Server::doClientRead(const CommIoCbParams &io)
104{
105 debugs(33,5, io.conn);
106 Must(reading());
107 reader = NULL;
108
109 /* Bail out quickly on Comm::ERR_CLOSING - close handlers will tidy up */
110 if (io.flag == Comm::ERR_CLOSING) {
111 debugs(33,5, io.conn << " closing Bailout.");
112 return;
113 }
114
115 assert(Comm::IsConnOpen(clientConnection));
116 assert(io.conn->fd == clientConnection->fd);
117
118 /*
119 * Don't reset the timeout value here. The value should be
120 * counting Config.Timeout.request and applies to the request
121 * as a whole, not individual read() calls.
122 * Plus, it breaks our lame *HalfClosed() detection
123 */
124
125 maybeMakeSpaceAvailable();
126 CommIoCbParams rd(this); // will be expanded with ReadNow results
127 rd.conn = io.conn;
128 switch (Comm::ReadNow(rd, inBuf)) {
129 case Comm::INPROGRESS:
130
131 if (inBuf.isEmpty())
132 debugs(33, 2, io.conn << ": no data to process, " << xstrerr(rd.xerrno));
133 readSomeData();
134 return;
135
136 case Comm::OK:
137 statCounter.client_http.kbytes_in += rd.size;
138 if (!receivedFirstByte_)
139 receivedFirstByte();
140 // may comm_close or setReplyToError
141 if (!handleReadData())
142 return;
143
144 /* Continue to process previously read data */
145 break;
146
147 case Comm::ENDFILE: // close detected by 0-byte read
148 debugs(33, 5, io.conn << " closed?");
149
150 if (connFinishedWithConn(rd.size)) {
151 clientConnection->close();
152 return;
153 }
154
155 /* It might be half-closed, we can't tell */
156 fd_table[io.conn->fd].flags.socket_eof = true;
157 commMarkHalfClosed(io.conn->fd);
158 fd_note(io.conn->fd, "half-closed");
159
160 /* There is one more close check at the end, to detect aborted
161 * (partial) requests. At this point we can't tell if the request
162 * is partial.
163 */
164
165 /* Continue to process previously read data */
166 break;
167
168 // case Comm::COMM_ERROR:
169 default: // no other flags should ever occur
170 debugs(33, 2, io.conn << ": got flag " << rd.flag << "; " << xstrerr(rd.xerrno));
08a175bb 171 pipeline.terminateAll(rd.xerrno);
fcc444e3
AJ
172 io.conn->close();
173 return;
174 }
175
176 afterClientRead();
177}
178
21cd3227
AJ
179/** callback handling the Comm::Write completion
180 *
181 * Will call afterClientWrite(size_t) to sync the I/O state.
182 * Then writeSomeData() to initiate any followup writes that
183 * could be immediately done.
184 */
fcc444e3
AJ
185void
186Server::clientWriteDone(const CommIoCbParams &io)
187{
188 debugs(33,5, io.conn);
21cd3227
AJ
189 Must(writer != nullptr);
190 writer = nullptr;
fcc444e3
AJ
191
192 /* Bail out quickly on Comm::ERR_CLOSING - close handlers will tidy up */
21cd3227 193 if (io.flag == Comm::ERR_CLOSING || !Comm::IsConnOpen(clientConnection)) {
fcc444e3
AJ
194 debugs(33,5, io.conn << " closing Bailout.");
195 return;
196 }
197
21cd3227
AJ
198 Must(io.conn->fd == clientConnection->fd);
199
200 if (io.flag && pipeline.front())
201 pipeline.front()->initiateClose("write failure");
fcc444e3 202
21cd3227 203 afterClientWrite(io.size); // update state
fcc444e3
AJ
204 writeSomeData(); // maybe schedules another write
205}
15f8f9eb 206