]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/servers/Server.cc
2 * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
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.
10 #include "anyp/PortCfg.h"
11 #include "client_side.h"
13 #include "comm/Read.h"
17 #include "MasterXaction.h"
18 #include "servers/Server.h"
19 #include "SquidConfig.h"
20 #include "StatCounters.h"
23 Server::Server(const MasterXaction::Pointer
&xact
) :
24 AsyncJob("::Server"), // kids overwrite
25 clientConnection(xact
->tcpClient
),
26 port(xact
->squidPort
),
27 receivedFirstByte_(false)
29 if (xact
->squidPort
!= NULL
)
30 transferProtocol
= xact
->squidPort
->transport
;
34 Server::doneAll() const
36 // servers are not done while the connection is open
37 return !Comm::IsConnOpen(clientConnection
) &&
38 BodyProducer::doneAll();
44 // TODO: shuffle activity from ConnStateData
50 if (Comm::IsConnOpen(clientConnection
))
51 clientConnection
->close();
53 BodyProducer::swanSong();
60 Comm::ReadCancel(clientConnection
->fd
, reader
);
66 Server::maybeMakeSpaceAvailable()
68 if (inBuf
.spaceSize() < 2) {
69 const SBuf::size_type haveCapacity
= inBuf
.length() + inBuf
.spaceSize();
70 if (haveCapacity
>= Config
.maxRequestBufferSize
) {
71 debugs(33, 4, "request buffer full: client_request_buffer_max_size=" << Config
.maxRequestBufferSize
);
74 if (haveCapacity
== 0) {
75 // haveCapacity is based on the SBuf visible window of the MemBlob buffer, which may fill up.
76 // at which point bump the buffer back to default. This allocates a new MemBlob with any un-parsed bytes.
77 inBuf
.reserveCapacity(CLIENT_REQ_BUF_SZ
);
79 const SBuf::size_type wantCapacity
= min(static_cast<SBuf::size_type
>(Config
.maxRequestBufferSize
), haveCapacity
*2);
80 inBuf
.reserveCapacity(wantCapacity
);
82 debugs(33, 2, "growing request buffer: available=" << inBuf
.spaceSize() << " used=" << inBuf
.length());
84 return (inBuf
.spaceSize() >= 2);
88 Server::readSomeData()
93 debugs(33, 4, clientConnection
<< ": reading request...");
95 // we can only read if there is more than 1 byte of space free
96 if (Config
.maxRequestBufferSize
- inBuf
.length() < 2)
99 typedef CommCbMemFunT
<Server
, CommIoCbParams
> Dialer
;
100 reader
= JobCallback(33, 5, Dialer
, this, Server::doClientRead
);
101 Comm::Read(clientConnection
, reader
);
105 Server::doClientRead(const CommIoCbParams
&io
)
107 debugs(33,5, io
.conn
);
111 /* Bail out quickly on Comm::ERR_CLOSING - close handlers will tidy up */
112 if (io
.flag
== Comm::ERR_CLOSING
) {
113 debugs(33,5, io
.conn
<< " closing Bailout.");
117 assert(Comm::IsConnOpen(clientConnection
));
118 assert(io
.conn
->fd
== clientConnection
->fd
);
121 * Don't reset the timeout value here. The value should be
122 * counting Config.Timeout.request and applies to the request
123 * as a whole, not individual read() calls.
124 * Plus, it breaks our lame *HalfClosed() detection
127 maybeMakeSpaceAvailable();
128 CommIoCbParams
rd(this); // will be expanded with ReadNow results
130 switch (Comm::ReadNow(rd
, inBuf
)) {
131 case Comm::INPROGRESS
:
134 debugs(33, 2, io
.conn
<< ": no data to process, " << xstrerr(rd
.xerrno
));
139 statCounter
.client_http
.kbytes_in
+= rd
.size
;
140 if (!receivedFirstByte_
)
142 // may comm_close or setReplyToError
143 if (!handleReadData())
146 /* Continue to process previously read data */
149 case Comm::ENDFILE
: // close detected by 0-byte read
150 debugs(33, 5, io
.conn
<< " closed?");
152 if (connFinishedWithConn(rd
.size
)) {
153 clientConnection
->close();
157 /* It might be half-closed, we can't tell */
158 fd_table
[io
.conn
->fd
].flags
.socket_eof
= true;
159 commMarkHalfClosed(io
.conn
->fd
);
160 fd_note(io
.conn
->fd
, "half-closed");
162 /* There is one more close check at the end, to detect aborted
163 * (partial) requests. At this point we can't tell if the request
167 /* Continue to process previously read data */
170 // case Comm::COMM_ERROR:
171 default: // no other flags should ever occur
172 debugs(33, 2, io
.conn
<< ": got flag " << rd
.flag
<< "; " << xstrerr(rd
.xerrno
));
173 pipeline
.terminateAll(rd
.xerrno
);
181 /** callback handling the Comm::Write completion
183 * Will call afterClientWrite(size_t) to sync the I/O state.
184 * Then writeSomeData() to initiate any followup writes that
185 * could be immediately done.
188 Server::clientWriteDone(const CommIoCbParams
&io
)
190 debugs(33,5, io
.conn
);
191 Must(writer
!= nullptr);
194 /* Bail out quickly on Comm::ERR_CLOSING - close handlers will tidy up */
195 if (io
.flag
== Comm::ERR_CLOSING
|| !Comm::IsConnOpen(clientConnection
)) {
196 debugs(33,5, io
.conn
<< " closing Bailout.");
200 Must(io
.conn
->fd
== clientConnection
->fd
);
202 if (io
.flag
&& pipeline
.front())
203 pipeline
.front()->initiateClose("write failure");
205 afterClientWrite(io
.size
); // update state
206 writeSomeData(); // maybe schedules another write