/*
- * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
*
* Squid software is distributed under GPLv2+ license and includes
* contributions from numerous individuals and organizations.
#include "htcp.h"
#include "http.h"
#include "HttpRequest.h"
-#include "HttpStateFlags.h"
#include "icmp/net_db.h"
#include "ip/tools.h"
#include "md5.h"
Countstr signature;
};
-class htcpSpecifier : public StoreClient
+class htcpSpecifier : public RefCountable, public StoreClient
{
MEMPROXY_CLASS(htcpSpecifier);
public:
- htcpSpecifier() :
- method(NULL),
- uri(NULL),
- version(NULL),
- req_hdrs(NULL),
- reqHdrsSz(0),
- request(NULL),
- checkHitRequest(NULL),
- dhdr(NULL)
- {}
- // XXX: destructor?
-
- void created (StoreEntry *newEntry);
+ typedef RefCount<htcpSpecifier> Pointer;
+
void checkHit();
- void checkedHit(StoreEntry *e);
+ void checkedHit(StoreEntry *);
+
+ void setFrom(Ip::Address &anIp) { from = anIp; }
+ void setDataHeader(htcpDataHeader *aDataHeader) {
+ dhdr = aDataHeader;
+ }
- void setFrom(Ip::Address &from);
- void setDataHeader(htcpDataHeader *);
- const char *method;
- char *uri;
- char *version;
- char *req_hdrs;
- size_t reqHdrsSz; ///< size of the req_hdrs content
- HttpRequest *request;
+ /* StoreClient API */
+ void created(StoreEntry *);
+
+public:
+ const char *method = nullptr;
+ char *uri = nullptr;
+ char *version = nullptr;
+ char *req_hdrs = nullptr;
+ size_t reqHdrsSz = 0; ///< size of the req_hdrs content
+ HttpRequest::Pointer request;
private:
- HttpRequest *checkHitRequest;
+ HttpRequest::Pointer checkHitRequest;
- Ip::Address from; // was a ptr. return to such IFF needed. otherwise copy should do.
- htcpDataHeader *dhdr;
+ Ip::Address from;
+ htcpDataHeader *dhdr = nullptr;
};
class htcpDetail {
static int old_squid_format = 0;
static ssize_t htcpBuildPacket(char *buf, size_t buflen, htcpStuff * stuff);
-static htcpSpecifier *htcpUnpackSpecifier(char *buf, int sz);
static htcpDetail *htcpUnpackDetail(char *buf, int sz);
static ssize_t htcpBuildAuth(char *buf, size_t buflen);
static ssize_t htcpBuildCountstr(char *buf, size_t buflen, const char *s, size_t len);
static ssize_t htcpBuildOpData(char *buf, size_t buflen, htcpStuff * stuff);
static ssize_t htcpBuildSpecifier(char *buf, size_t buflen, htcpStuff * stuff);
static ssize_t htcpBuildTstOpData(char *buf, size_t buflen, htcpStuff * stuff);
-static void htcpFreeSpecifier(htcpSpecifier * s);
static void htcpHandleMsg(char *buf, int sz, Ip::Address &from);
static void
htcpSend(const char *buf, int len, Ip::Address &to)
{
- debugs(31, 3, HERE << to);
+ debugs(31, 3, to);
htcpHexdump("htcpSend", buf, len);
- if (comm_udp_sendto(htcpOutgoingConn->fd, to, buf, len) < 0)
- debugs(31, 3, HERE << htcpOutgoingConn << " sendto: " << xstrerror());
- else
+ if (comm_udp_sendto(htcpOutgoingConn->fd, to, buf, len) < 0) {
+ int xerrno = errno;
+ debugs(31, 3, htcpOutgoingConn << " sendto: " << xstrerr(xerrno));
+ } else
++statCounter.htcp.pkts_sent;
}
-/*
- * STUFF FOR RECEIVING HTCP MESSAGES
- */
-
-void
-htcpSpecifier::setFrom(Ip::Address &aSocket)
-{
- from = aSocket;
-}
-
-void
-htcpSpecifier::setDataHeader(htcpDataHeader *aDataHeader)
-{
- dhdr = aDataHeader;
-}
-
-static void
-htcpFreeSpecifier(htcpSpecifier * s)
-{
- HTTPMSGUNLOCK(s->request);
-
- delete s;
-}
-
/*
* Unpack an HTCP SPECIFIER in place
* This will overwrite any following AUTH block
*/
// XXX: this needs to be turned into an Htcp1::Parser inheriting from Http1::RequestParser
// but with different first-line and block unpacking logic.
-static htcpSpecifier *
+static htcpSpecifier::Pointer
htcpUnpackSpecifier(char *buf, int sz)
{
- htcpSpecifier *s = new htcpSpecifier;
+ static const htcpSpecifier::Pointer nil;
+ htcpSpecifier::Pointer s(new htcpSpecifier);
HttpRequestMethod method;
/* Find length of METHOD */
if (l > sz) {
debugs(31, 3, "htcpUnpackSpecifier: failed to unpack METHOD");
- htcpFreeSpecifier(s);
- return NULL;
+ return nil;
}
/* Set METHOD */
if (l > sz) {
debugs(31, 3, "htcpUnpackSpecifier: failed to unpack URI");
- htcpFreeSpecifier(s);
- return NULL;
+ return nil;
}
/* Add terminating null to METHOD */
if (l > sz) {
debugs(31, 3, "htcpUnpackSpecifier: failed to unpack VERSION");
- htcpFreeSpecifier(s);
- return NULL;
+ return nil;
}
/* Add terminating null to URI */
if (l > sz) {
debugs(31, 3, "htcpUnpackSpecifier: failed to unpack REQ-HDRS");
- htcpFreeSpecifier(s);
- return NULL;
+ return nil;
}
/* Add terminating null to URI */
// Parse the request
method.HttpRequestMethodXXX(s->method);
- s->request = HttpRequest::CreateFromUrlAndMethod(s->uri, method == Http::METHOD_NONE ? HttpRequestMethod(Http::METHOD_GET) : method);
-
- if (s->request)
- HTTPMSGLOCK(s->request);
-
+ const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initHtcp);
+ s->request = HttpRequest::FromUrl(s->uri, mx, method == Http::METHOD_NONE ? HttpRequestMethod(Http::METHOD_GET) : method);
return s;
}
}
static bool
-htcpAccessAllowed(acl_access * acl, htcpSpecifier * s, Ip::Address &from)
+htcpAccessAllowed(acl_access * acl, const htcpSpecifier::Pointer &s, Ip::Address &from)
{
/* default deny if no access list present */
if (!acl)
return false;
- ACLFilledChecklist checklist(acl, s->request, NULL);
+ ACLFilledChecklist checklist(acl, s->request.getRaw(), nullptr);
checklist.src_addr = from;
checklist.my_addr.setNoAddr();
return (checklist.fastCheck() == ACCESS_ALLOWED);
if (e && e->expires > -1)
hdr.putTime(Http::HdrType::EXPIRES, e->expires);
- if (e && e->lastmod > -1)
- hdr.putTime(Http::HdrType::LAST_MODIFIED, e->lastmod);
+ if (e && e->lastModified() > -1)
+ hdr.putTime(Http::HdrType::LAST_MODIFIED, e->lastModified());
hdr.packInto(&mb);
{
checkHitRequest = request;
- if (NULL == checkHitRequest) {
+ if (!checkHitRequest) {
debugs(31, 3, "htcpCheckHit: NO; failed to parse URL");
checkedHit(NullStoreEntry::getInstance());
return;
if (!checkHitRequest->header.parse(req_hdrs, reqHdrsSz)) {
debugs(31, 3, "htcpCheckHit: NO; failed to parse request headers");
- delete checkHitRequest;
- checkHitRequest = NULL;
+ checkHitRequest = nullptr;
checkedHit(NullStoreEntry::getInstance());
return;
}
- StoreEntry::getPublicByRequest(this, checkHitRequest);
+ StoreEntry::getPublicByRequest(this, checkHitRequest.getRaw());
}
void
-htcpSpecifier::created (StoreEntry *e)
+htcpSpecifier::created(StoreEntry *e)
{
- StoreEntry *hit=NULL;
- assert (e);
+ StoreEntry *hit = nullptr;
- if (e->isNull()) {
+ if (!e || e->isNull()) {
debugs(31, 3, "htcpCheckHit: NO; public object not found");
} else if (!e->validToSend()) {
debugs(31, 3, "htcpCheckHit: NO; entry not valid to send" );
- } else if (refreshCheckHTCP(e, checkHitRequest)) {
+ } else if (refreshCheckHTCP(e, checkHitRequest.getRaw())) {
debugs(31, 3, "htcpCheckHit: NO; cached response is stale");
} else {
debugs(31, 3, "htcpCheckHit: YES!?");
hit = e;
}
- checkedHit (hit);
+ checkedHit(hit);
}
static void
}
static int
-htcpClrStore(const htcpSpecifier * s)
+htcpClrStore(const htcpSpecifier::Pointer &s)
{
- HttpRequest *request = s->request;
- StoreEntry *e = NULL;
- int released = 0;
-
- if (request == NULL) {
+ HttpRequestPointer request(s->request);
+ if (!request) {
debugs(31, 3, "htcpClrStore: failed to parse URL");
return -1;
}
return -1;
}
+ StoreEntry *e = nullptr;
+ int released = 0;
/* Lookup matching entries. This matches both GET and HEAD */
- while ((e = storeGetPublicByRequest(request)) != NULL) {
- if (e != NULL) {
- htcpClrStoreEntry(e);
- ++released;
- }
+ while ((e = storeGetPublicByRequest(request.getRaw()))) {
+ htcpClrStoreEntry(e);
+ ++released;
}
if (released) {
static void
htcpHandleTstRequest(htcpDataHeader * dhdr, char *buf, int sz, Ip::Address &from)
{
- /* buf should be a SPECIFIER */
- htcpSpecifier *s;
-
if (sz == 0) {
debugs(31, 3, "htcpHandleTst: nothing to do");
return;
if (dhdr->F1 == 0)
return;
- /* s is a new object */
- s = htcpUnpackSpecifier(buf, sz);
+ /* buf should be a SPECIFIER */
+ htcpSpecifier::Pointer s(htcpUnpackSpecifier(buf, sz));
- if (s == NULL) {
+ if (!s) {
debugs(31, 3, "htcpHandleTstRequest: htcpUnpackSpecifier failed");
htcpLogHtcp(from, dhdr->opcode, LOG_UDP_INVALID, dash_str);
return;
if (!s->request) {
debugs(31, 3, "htcpHandleTstRequest: failed to parse request");
htcpLogHtcp(from, dhdr->opcode, LOG_UDP_INVALID, dash_str);
- htcpFreeSpecifier(s);
return;
}
if (!htcpAccessAllowed(Config.accessList.htcp, s, from)) {
debugs(31, 3, "htcpHandleTstRequest: Access denied");
htcpLogHtcp(from, dhdr->opcode, LOG_UDP_DENIED, s->uri);
- htcpFreeSpecifier(s);
return;
}
htcpTstReply(dhdr, NULL, NULL, from); /* cache miss */
htcpLogHtcp(from, dhdr->opcode, LOG_UDP_MISS, uri);
}
-
- htcpFreeSpecifier(this);
}
static void
htcpHandleClr(htcpDataHeader * hdr, char *buf, int sz, Ip::Address &from)
{
- htcpSpecifier *s;
/* buf[0/1] is reserved and reason */
int reason = buf[1] << 4;
debugs(31, 2, "HTCP CLR reason: " << reason);
return;
}
- s = htcpUnpackSpecifier(buf, sz);
+ htcpSpecifier::Pointer s(htcpUnpackSpecifier(buf, sz));
- if (NULL == s) {
+ if (!s) {
debugs(31, 3, "htcpHandleClr: htcpUnpackSpecifier failed");
htcpLogHtcp(from, hdr->opcode, LOG_UDP_INVALID, dash_str);
return;
if (!s->request) {
debugs(31, 3, "htcpHandleTstRequest: failed to parse request");
htcpLogHtcp(from, hdr->opcode, LOG_UDP_INVALID, dash_str);
- htcpFreeSpecifier(s);
return;
}
if (!htcpAccessAllowed(Config.accessList.htcp_clr, s, from)) {
debugs(31, 3, "htcpHandleClr: Access denied");
htcpLogHtcp(from, hdr->opcode, LOG_UDP_DENIED, s->uri);
- htcpFreeSpecifier(s);
return;
}
default:
break;
}
-
- htcpFreeSpecifier(s);
}
/*
ssize_t pktlen;
char vbuf[32];
HttpHeader hdr(hoRequest);
- HttpStateFlags flags;
+ Http::StateFlags flags;
if (!Comm::IsConnOpen(htcpIncomingConn))
return 0;
char vbuf[32];
HttpHeader hdr(hoRequest);
MemBuf mb;
- HttpStateFlags flags;
+ Http::StateFlags flags;
if (!Comm::IsConnOpen(htcpIncomingConn))
return;