WhoisGateway.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 /* DEBUG: section 75 WHOIS protocol */
10 
11 #include "squid.h"
12 #include "clients/WhoisGateway.h"
13 #include "comm.h"
14 #include "comm/Read.h"
15 #include "comm/Write.h"
16 #include "errorpage.h"
17 #include "FwdState.h"
18 #include "HttpReply.h"
19 #include "HttpRequest.h"
20 #include "SquidConfig.h"
21 #include "StatCounters.h"
22 #include "Store.h"
23 #include "tools.h"
24 
25 #include <cerrno>
26 
28 {
30 
31 public:
32  void readReply(const Comm::ConnectionPointer &, char *aBuffer, size_t aBufferLength, Comm::Flag flag, int xerrno);
33  void setReplyToOK(StoreEntry *sentry);
37  char buf[BUFSIZ+1]; /* readReply adds terminating NULL */
39 };
40 
42 
46 
47 /* PUBLIC */
48 
49 static void
50 whoisWriteComplete(const Comm::ConnectionPointer &, char *buf, size_t, Comm::Flag, int, void *)
51 {
52  xfree(buf);
53 }
54 
55 void
57 {
58  WhoisState *p = new WhoisState;
59  p->request = fwd->request;
60  p->entry = fwd->entry;
61  p->fwd = fwd;
62  p->dataWritten = false;
63 
64  p->entry->lock("whoisStart");
66 
67  size_t l = p->request->url.path().length() + 3;
68  char *buf = (char *)xmalloc(l);
69 
70  const SBuf str_print = p->request->url.path().substr(1);
71  snprintf(buf, l, SQUIDSBUFPH "\r\n", SQUIDSBUFPRINT(str_print));
72 
73  AsyncCall::Pointer writeCall = commCbCall(5,5, "whoisWriteComplete",
75  Comm::Write(fwd->serverConnection(), buf, strlen(buf), writeCall, nullptr);
76  AsyncCall::Pointer readCall = commCbCall(5,4, "whoisReadReply",
78  comm_read(fwd->serverConnection(), p->buf, BUFSIZ, readCall);
79  AsyncCall::Pointer timeoutCall = commCbCall(5, 4, "whoisTimeout",
82 }
83 
84 /* PRIVATE */
85 
86 static void
88 {
89  WhoisState *p = static_cast<WhoisState *>(io.data);
90  debugs(75, 3, io.conn << ", URL " << p->entry->url());
91  io.conn->close();
92 }
93 
94 static void
95 whoisReadReply(const Comm::ConnectionPointer &conn, char *buf, size_t len, Comm::Flag flag, int xerrno, void *data)
96 {
97  WhoisState *p = (WhoisState *)data;
98  p->readReply(conn, buf, len, flag, xerrno);
99 }
100 
101 void
103 {
104  HttpReply *reply = new HttpReply;
105  sentry->buffer();
106  reply->setHeaders(Http::scOkay, "Gatewaying", "text/plain", -1, -1, -2);
108  sentry->replaceHttpReply(reply);
109 }
110 
111 void
112 WhoisState::readReply(const Comm::ConnectionPointer &conn, char *aBuffer, size_t aBufferLength, Comm::Flag flag, int xerrno)
113 {
114  /* Bail out early on Comm::ERR_CLOSING - close handlers will tidy up for us */
115  if (flag == Comm::ERR_CLOSING)
116  return;
117 
118  aBuffer[aBufferLength] = '\0';
119  debugs(75, 3, conn << " read " << aBufferLength << " bytes");
120  debugs(75, 5, "{" << aBuffer << "}");
121 
122  // TODO: Honor delay pools.
123 
124  // XXX: Update statCounter before bailing
125  if (!entry->isAccepting()) {
126  debugs(52, 3, "terminating due to bad " << *entry);
127  // TODO: Do not abuse connection for triggering cleanup.
128  conn->close();
129  return;
130  }
131 
132  if (flag != Comm::OK) {
133  debugs(50, 2, conn << ": read failure: " << xstrerr(xerrno));
134 
135  if (ignoreErrno(xerrno)) {
136  AsyncCall::Pointer call = commCbCall(5,4, "whoisReadReply",
138  comm_read(conn, aBuffer, BUFSIZ, call);
139  } else {
141  err->xerrno = xerrno;
142  fwd->fail(err);
143  conn->close();
144  }
145  return;
146  }
147 
148  if (aBufferLength > 0) {
149  if (!dataWritten)
151 
152  statCounter.server.all.kbytes_in += aBufferLength;
153  statCounter.server.http.kbytes_in += aBufferLength;
154 
155  /* No range support, we always grab it all */
156  dataWritten = true;
157  entry->append(aBuffer, aBufferLength);
158  entry->flush();
159 
160  AsyncCall::Pointer call = commCbCall(5,4, "whoisReadReply",
162  comm_read(conn, aBuffer, BUFSIZ, call);
163  return;
164  }
165 
166  /* no bytes read. stop reading */
167  entry->timestampsSet();
168  entry->flush();
169 
170  if (!entry->makePublic())
171  entry->makePrivate(true);
172 
173  if (dataWritten) // treat zero-length responses as incomplete
174  fwd->markStoredReplyAsWhole("whois received/stored the entire response");
175  else
177 
178  fwd->complete();
179  debugs(75, 3, "whoisReadReply: Done: " << entry->url());
180  conn->close();
181 }
182 
183 static void
185 {
186  WhoisState *p = (WhoisState *)params.data;
187  debugs(75, 3, "whoisClose: FD " << params.fd);
188  // We do not own a Connection. Assume that FwdState is also monitoring.
189  p->entry->unlock("whoisClose");
190  delete p;
191 }
192 
const char * xstrerr(int error)
Definition: xstrerror.cc:83
void makePrivate(const bool shareable)
Definition: store.cc:174
AsyncCall::Pointer comm_add_close_handler(int fd, CLCB *handler, void *data)
Definition: comm.cc:952
#define BUFSIZ
Definition: defines.h:20
AnyP::Uri url
the request URI
Definition: HttpRequest.h:115
@ ERR_READ_ERROR
Definition: forward.h:28
#define xmalloc
void whoisStart(FwdState *fwd)
Definition: WhoisGateway.cc:56
bool makePublic(const KeyScope keyScope=ksDefault)
Definition: store.cc:167
const char * url() const
Definition: store.cc:1566
void append(char const *, int) override
Appends a c-string to existing packed data.
Definition: store.cc:803
struct StatCounters::@112::@122 all
void lock(const char *context)
Definition: store.cc:445
AccessLogEntryPointer al
info for the future access.log entry
Definition: FwdState.h:204
Definition: SBuf.h:93
CBDATA_CLASS_INIT(WhoisState)
int fd
FD which the call was about. Set by the async call creator.
Definition: CommCalls.h:85
struct StatCounters::@112 server
@ OK
Definition: Flag.h:16
bool isAccepting() const
Definition: store.cc:1988
void replaceHttpReply(const HttpReplyPointer &, const bool andStartWriting=true)
Definition: store.cc:1705
void CLCB(const CommCloseCbParams &params)
Definition: CommCalls.h:40
void fail(ErrorState *err)
Definition: FwdState.cc:458
@ ERR_CLOSING
Definition: Flag.h:24
static void whoisWriteComplete(const Comm::ConnectionPointer &, char *buf, size_t, Comm::Flag, int, void *)
Definition: WhoisGateway.cc:50
void comm_read(const Comm::ConnectionPointer &conn, char *buf, int len, AsyncCall::Pointer &callback)
Definition: Read.h:59
void setReplyToOK(StoreEntry *sentry)
static CTCB whoisTimeout
Definition: WhoisGateway.cc:44
struct StatCounters::@112::@122 http
time_t read
Definition: SquidConfig.h:112
#define SQUIDSBUFPRINT(s)
Definition: SBuf.h:32
void CTCB(const CommTimeoutCbParams &params)
Definition: CommCalls.h:37
const Comm::ConnectionPointer & serverConnection() const
Definition: FwdState.h:138
StoreEntry * entry
Definition: WhoisGateway.cc:34
@ scBadGateway
Definition: StatusCode.h:75
HttpRequest::Pointer request
Definition: WhoisGateway.cc:35
FwdState::Pointer fwd
Definition: WhoisGateway.cc:36
void IOCB(const Comm::ConnectionPointer &conn, char *, size_t size, Comm::Flag flag, int xerrno, void *data)
Definition: CommCalls.h:34
CBDATA_CLASS(WhoisState)
int unlock(const char *context)
Definition: store.cc:469
Comm::ConnectionPointer conn
Definition: CommCalls.h:80
CommCbFunPtrCallT< Dialer > * commCbCall(int debugSection, int debugLevel, const char *callName, const Dialer &dialer)
Definition: CommCalls.h:312
@ ERR_ZERO_SIZE_OBJECT
Definition: forward.h:46
@ srcWhois
Whois server.
Definition: Message.h:43
void buffer() override
Definition: store.cc:1601
void readReply(const Comm::ConnectionPointer &, char *aBuffer, size_t aBufferLength, Comm::Flag flag, int xerrno)
void flush() override
Definition: store.cc:1612
@ scInternalServerError
Definition: StatusCode.h:73
void Write(const Comm::ConnectionPointer &conn, const char *buf, int size, AsyncCall::Pointer &callback, FREE *free_func)
Definition: Write.cc:33
static IOCB whoisReadReply
Definition: WhoisGateway.cc:45
#define xfree
char buf[BUFSIZ+1]
Definition: WhoisGateway.cc:37
uint32_t sources
The message sources.
Definition: Message.h:99
Flag
Definition: Flag.h:15
int ignoreErrno(int ierrno)
Definition: comm.cc:1422
void path(const char *p)
Definition: Uri.h:96
void commSetConnTimeout(const Comm::ConnectionPointer &conn, time_t timeout, AsyncCall::Pointer &callback)
Definition: comm.cc:592
void complete()
Definition: FwdState.cc:526
bool timestampsSet()
Definition: store.cc:1387
static CLCB whoisClose
Definition: WhoisGateway.cc:43
struct SquidConfig::@84 Timeout
StoreEntry * entry
Definition: FwdState.h:202
void setHeaders(Http::StatusCode status, const char *reason, const char *ctype, int64_t clen, time_t lmt, time_t expires)
Definition: HttpReply.cc:170
void markStoredReplyAsWhole(const char *whyWeAreSure)
Definition: FwdState.cc:575
bool dataWritten
Definition: WhoisGateway.cc:38
@ scOkay
Definition: StatusCode.h:27
HttpRequest * request
Definition: FwdState.h:203
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192
#define SQUIDSBUFPH
Definition: SBuf.h:31
class SquidConfig Config
Definition: SquidConfig.cc:12
StatCounters statCounter
Definition: StatCounters.cc:12

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors