Server.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
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"
11 #include "client_side.h"
12 #include "comm.h"
13 #include "comm/Read.h"
14 #include "debug/Stream.h"
15 #include "error/SysErrorDetail.h"
16 #include "fd.h"
17 #include "fde.h"
18 #include "http/Stream.h"
19 #include "LogTags.h"
20 #include "MasterXaction.h"
21 #include "servers/Server.h"
22 #include "SquidConfig.h"
23 #include "StatCounters.h"
24 #include "tools.h"
25 
27  AsyncJob("::Server"), // kids overwrite
28  clientConnection(xact->tcpClient),
29  transferProtocol(xact->squidPort->transport),
30  port(xact->squidPort),
31  receivedFirstByte_(false)
32 {
34 }
35 
36 bool
38 {
39  // servers are not done while the connection is open
42 }
43 
44 void
46 {
47  // TODO: shuffle activity from ConnStateData
48 }
49 
50 void
52 {
55 
57 }
58 
59 void
61 {
62  if (reading()) {
64  reader = nullptr;
65  }
66 }
67 
73 void
75 {
76  // The hard-coded parameters are arbitrary but seem reasonable.
77  // A careful study of Squid I/O and parsing patterns is needed to tune them.
78  SBufReservationRequirements requirements;
79  requirements.minSpace = 1024; // smaller I/Os are not worth their overhead
80  requirements.idealSpace = CLIENT_REQ_BUF_SZ; // we expect few larger I/Os
82  requirements.allowShared = true; // allow because inBuf is used immediately
83  inBuf.reserve(requirements);
84  if (!inBuf.spaceSize())
85  debugs(33, 4, "request buffer full: client_request_buffer_max_size=" << Config.maxRequestBufferSize);
86 }
87 
88 bool
90 {
91  // TODO: Account for bodyPipe buffering as well.
93  debugs(33, 4, "no: " << inBuf.length() << '-' << Config.maxRequestBufferSize << '=' << (inBuf.length() - Config.maxRequestBufferSize));
94  return false;
95  }
96  debugs(33, 7, "yes: " << Config.maxRequestBufferSize << '-' << inBuf.length() << '=' << (Config.maxRequestBufferSize - inBuf.length()));
97  return true;
98 }
99 
100 void
102 {
103  if (reading())
104  return;
105 
107  return;
108 
110  reader = JobCallback(33, 5, Dialer, this, Server::doClientRead);
112 }
113 
114 void
116 {
117  debugs(33,5, io.conn);
118  Must(reading());
119  reader = nullptr;
120 
121  /* Bail out quickly on Comm::ERR_CLOSING - close handlers will tidy up */
122  if (io.flag == Comm::ERR_CLOSING) {
123  debugs(33,5, io.conn << " closing Bailout.");
124  return;
125  }
126 
128  assert(io.conn->fd == clientConnection->fd);
129 
130  /*
131  * Don't reset the timeout value here. The value should be
132  * counting Config.Timeout.request and applies to the request
133  * as a whole, not individual read() calls.
134  * Plus, it breaks our lame *HalfClosed() detection
135  */
136 
137  // mayBufferMoreRequestBytes() was true during readSomeData(), but variables
138  // like Config.maxRequestBufferSize may have changed since that check
139  if (!mayBufferMoreRequestBytes()) {
140  // XXX: If we avoid Comm::ReadNow(), we should not Comm::Read() again
141  // when the wait is over; resume these doClientRead() checks instead.
142  return; // wait for noteMoreBodySpaceAvailable() or a similar inBuf draining event
143  }
146 
147  CommIoCbParams rd(this); // will be expanded with ReadNow results
148  rd.conn = io.conn;
151 
152  switch (Comm::ReadNow(rd, inBuf)) {
153  case Comm::INPROGRESS:
154 
155  if (inBuf.isEmpty())
156  debugs(33, 2, io.conn << ": no data to process, " << xstrerr(rd.xerrno));
157  readSomeData();
158  return;
159 
160  case Comm::OK:
162  if (!receivedFirstByte_)
164  // may comm_close or setReplyToError
165  if (!handleReadData())
166  return;
167 
168  /* Continue to process previously read data */
169  break;
170 
171  case Comm::ENDFILE: // close detected by 0-byte read
172  debugs(33, 5, io.conn << " closed?");
173 
174  if (shouldCloseOnEof()) {
175  LogTagsErrors lte;
176  lte.aborted = true;
178  return;
179  }
180 
181  /* It might be half-closed, we can't tell */
182  fd_table[io.conn->fd].flags.socket_eof = true;
184  fd_note(io.conn->fd, "half-closed");
185 
186  /* There is one more close check at the end, to detect aborted
187  * (partial) requests. At this point we can't tell if the request
188  * is partial.
189  */
190 
191  /* Continue to process previously read data */
192  break;
193 
194  // case Comm::COMM_ERROR:
195  default: // no other flags should ever occur
196  debugs(33, 2, io.conn << ": got flag " << rd.flag << "; " << xstrerr(rd.xerrno));
198  return;
199  }
200 
201  afterClientRead();
202 }
203 
210 void
212 {
213  debugs(33,5, io.conn);
214  Must(writer != nullptr);
215  writer = nullptr;
216 
217  /* Bail out quickly on Comm::ERR_CLOSING - close handlers will tidy up */
219  debugs(33,5, io.conn << " closing Bailout.");
220  return;
221  }
222 
223  Must(io.conn->fd == clientConnection->fd);
224 
225  if (io.flag) {
226  debugs(33, 2, "bailing after a write failure: " << xstrerr(io.xerrno));
228  return;
229  }
230 
231  afterClientWrite(io.size); // update state
232  writeSomeData(); // maybe schedules another write
233 }
234 
void Read(const Comm::ConnectionPointer &conn, AsyncCall::Pointer &callback)
Definition: Read.cc:40
const char * xstrerr(int error)
Definition: xstrerror.cc:83
bool mayBufferMoreRequestBytes() const
whether client_request_buffer_max_size allows inBuf.length() increase
Definition: Server.cc:89
size_type idealSpace
if allocating anyway, provide this much space
Definition: SBuf.h:710
@ ERR_READ_ERROR
Definition: forward.h:28
virtual bool handleReadData()=0
@ Error
Definition: ResultCode.h:19
SBuf inBuf
read I/O buffer for the client connection
Definition: Server.h:113
void fd_note(int fd, const char *s)
Definition: fd.cc:216
AsyncCall::Pointer reader
set when we are reading
Definition: Server.h:130
bool isEmpty() const
Definition: SBuf.h:435
virtual void swanSong()
Definition: AsyncJob.h:61
Comm::Flag ReadNow(CommIoCbParams &params, SBuf &buf)
Definition: Read.cc:81
size_type maxCapacity
do not allocate more than this
Definition: SBuf.h:712
@ INPROGRESS
Definition: Flag.h:21
virtual void receivedFirstByte()=0
Update flags and timeout after the first byte received.
Named SBuf::reserve() parameters. Defaults ask for and restrict nothing.
Definition: SBuf.h:700
virtual bool shouldCloseOnEof() const =0
whether to stop serving our client after reading EOF on its connection
size_type spaceSize() const
Definition: SBuf.h:397
bool IsConnOpen(const Comm::ConnectionPointer &conn)
Definition: Connection.cc:27
@ OK
Definition: Flag.h:16
@ ENDFILE
Definition: Flag.h:26
bool allowShared
whether sharing our storage with others is OK
Definition: SBuf.h:713
void maybeMakeSpaceAvailable()
grows the available read buffer space (if possible)
Definition: Server.cc:74
@ ERR_CLOSING
Definition: Flag.h:24
virtual void terminateAll(const Error &, const LogTagsErrors &)=0
abort any pending transactions and prevent new ones (by closing)
struct StatCounters::@111 client_http
int xerrno
The last errno to occur. non-zero if flag is Comm::COMM_ERROR.
Definition: CommCalls.h:83
static int port
Definition: ldap_backend.cc:70
virtual void afterClientWrite(size_t)
processing to sync state after a Comm::Write()
Definition: Server.h:86
size_type reserve(const SBufReservationRequirements &requirements)
Definition: SBuf.cc:112
void ReadCancel(int fd, AsyncCall::Pointer &callback)
Cancel the read pending on FD. No action if none pending.
Definition: Read.cc:219
ByteCounter kbytes_in
Definition: StatCounters.h:46
void leaveOrphanage()
resume relying on owner(s) to initiate an explicit connection closure
Definition: Connection.h:92
virtual bool doneAll() const
whether positive goal has been reached
Definition: AsyncJob.cc:112
static ErrorDetail::Pointer NewIfAny(const int errorNo)
#define CLIENT_REQ_BUF_SZ
Definition: defines.h:86
Comm::ConnectionPointer conn
Definition: CommCalls.h:80
#define assert(EX)
Definition: assert.h:17
Comm::Flag flag
comm layer result status.
Definition: CommCalls.h:82
void readSomeData()
maybe grow the inBuf and schedule Comm::Read()
Definition: Server.cc:101
bool reading() const
whether Comm::Read() is scheduled
Definition: Server.h:60
#define Assure(condition)
Definition: Assure.h:35
#define JobCallback(dbgSection, dbgLevel, Dialer, job, method)
Convenience macro to create a Dialer-based job callback.
Definition: AsyncJobCalls.h:70
size_type length() const
Returns the number of bytes stored in SBuf.
Definition: SBuf.h:419
Comm::ConnectionPointer clientConnection
Definition: Server.h:100
size_type minSpace
allocate [at least this much] if spaceSize() is smaller
Definition: SBuf.h:711
void doClientRead(const CommIoCbParams &io)
Definition: Server.cc:115
void stopReading()
cancels Comm::Read() if it is scheduled
Definition: Server.cc:60
#define fd_table
Definition: fde.h:189
virtual void afterClientRead()=0
processing to be done after a Comm::Read()
Server(const MasterXactionPointer &xact)
Definition: Server.cc:26
static LogTagsErrors FromErrno(int errNo)
constructs an object matching errno(3) of a failed I/O call
Definition: LogTags.cc:22
AsyncCall::Pointer writer
set when we are writing
Definition: Server.h:131
@ ERR_WRITE_ERROR
Definition: forward.h:29
@ ERR_CLIENT_GONE
Definition: forward.h:79
bool doneAll() const override
whether positive goal has been reached
Definition: Server.cc:37
void start() override
called by AsyncStart; do not call directly
Definition: Server.cc:45
#define Must(condition)
Definition: TextException.h:75
bool receivedFirstByte_
true if at least one byte received on this connection
Definition: Server.h:115
size_t maxRequestBufferSize
Definition: SquidConfig.h:136
void swanSong() override
Definition: Server.cc:51
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
void clientWriteDone(const CommIoCbParams &io)
Definition: Server.cc:211
bool aborted
_ABORTED: other abnormal termination (e.g., I/O error)
Definition: LogTags.h:29
class SquidConfig Config
Definition: SquidConfig.cc:12
virtual void writeSomeData()
maybe find some data to send and schedule a Comm::Write()
Definition: Server.h:69
void commMarkHalfClosed(int fd)
Definition: comm.h:103
StatCounters statCounter
Definition: StatCounters.cc:12

 

Introduction

Documentation

Support

Miscellaneous