Skip to content

Commit

Permalink
wsresponse: private member as surrogate
Browse files Browse the repository at this point in the history
  • Loading branch information
janbar committed Nov 25, 2023
1 parent 297a12c commit 3bced6c
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 46 deletions.
65 changes: 52 additions & 13 deletions noson/src/private/wsresponse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,45 @@

using namespace NSROOT;

WSResponse::WSResponse(const WSRequest &request, int maxRedirs, bool trustedLocation, bool followAny)
: p(0)
{
p = new _response(request);
while (maxRedirs > 0)
{
--maxRedirs;
switch (p->GetStatusCode())
{
// handle redirection
case 301:
case 302:
{
URIParser uri(p->Redirection());
bool trusted = (uri.Scheme() && strncmp("https", uri.Scheme(), 5) == 0);
if (
/* relative */ !uri.Host() ||
/* same origin */ (request.GetServer() == uri.Host() && (!trustedLocation || trusted)) ||
/* follow any */ (followAny && (!trustedLocation || trusted))
)
{
DBG(DBG_DEBUG, "%s: (%d) LOCATION = %s\n", __FUNCTION__, p->GetStatusCode(), p->Redirection().c_str());
WSRequest redir(request, uri);
delete p;
p = new _response(redir);
}
}
default:
break;
}
}
}

WSResponse::~WSResponse()
{
if (p)
delete p;
}

bool WSResponse::ReadHeaderLine(NetSocket *socket, const char *eol, std::string& line, size_t *len)
{
char buf[RESPONSE_BUFFER_SIZE];
Expand Down Expand Up @@ -88,7 +127,7 @@ bool WSResponse::ReadHeaderLine(NetSocket *socket, const char *eol, std::string&
return true;
}

WSResponse::WSResponse(const WSRequest &request)
WSResponse::_response::_response(const WSRequest &request)
: m_socket(NULL)
, m_successful(false)
, m_statusCode(0)
Expand Down Expand Up @@ -133,14 +172,14 @@ WSResponse::WSResponse(const WSRequest &request)
}
}

WSResponse::~WSResponse()
WSResponse::_response::~_response()
{
SAFE_DELETE(m_decoder);
SAFE_DELETE_ARRAY(m_chunkBuffer);
SAFE_DELETE(m_socket);
}

bool WSResponse::SendRequest(const WSRequest &request)
bool WSResponse::_response::SendRequest(const WSRequest &request)
{
std::string msg;

Expand All @@ -154,7 +193,7 @@ bool WSResponse::SendRequest(const WSRequest &request)
return true;
}

bool WSResponse::GetResponse()
bool WSResponse::_response::GetResponse()
{
size_t len;
std::string strread;
Expand All @@ -163,7 +202,7 @@ bool WSResponse::GetResponse()
bool ret = false;

token[0] = 0;
while (ReadHeaderLine(m_socket, "\r\n", strread, &len))
while (WSResponse::ReadHeaderLine(m_socket, "\r\n", strread, &len))
{
const char *line = strread.c_str(), *val = NULL;
int value_len = 0;
Expand Down Expand Up @@ -284,7 +323,7 @@ bool WSResponse::GetResponse()
return ret;
}

size_t WSResponse::ReadChunk(void *buf, size_t buflen)
size_t WSResponse::_response::ReadChunk(void *buf, size_t buflen)
{
size_t s = 0;
if (m_contentChunked)
Expand All @@ -297,7 +336,7 @@ size_t WSResponse::ReadChunk(void *buf, size_t buflen)
m_chunkBuffer = m_chunkPtr = m_chunkEOR = m_chunkEnd = NULL;
std::string strread;
size_t len = 0;
while (ReadHeaderLine(m_socket, "\r\n", strread, &len) && len == 0);
while (WSResponse::ReadHeaderLine(m_socket, "\r\n", strread, &len) && len == 0);
DBG(DBG_PROTO, "%s: chunked data (%s)\n", __FUNCTION__, strread.c_str());
std::string chunkStr("0x0");
uint32_t chunkSize;
Expand Down Expand Up @@ -327,9 +366,9 @@ size_t WSResponse::ReadChunk(void *buf, size_t buflen)
return s;
}

int WSResponse::SocketStreamReader(void *hdl, void *buf, int sz)
int WSResponse::_response::SocketStreamReader(void *hdl, void *buf, int sz)
{
WSResponse *resp = static_cast<WSResponse*>(hdl);
_response *resp = static_cast<_response*>(hdl);
if (resp == NULL)
return 0;
size_t s = 0;
Expand All @@ -345,13 +384,13 @@ int WSResponse::SocketStreamReader(void *hdl, void *buf, int sz)
return s;
}

int WSResponse::ChunkStreamReader(void *hdl, void *buf, int sz)
int WSResponse::_response::ChunkStreamReader(void *hdl, void *buf, int sz)
{
WSResponse *resp = static_cast<WSResponse*>(hdl);
_response *resp = static_cast<_response*>(hdl);
return (resp == NULL ? 0 : resp->ReadChunk(buf, sz));
}

size_t WSResponse::ReadContent(char* buf, size_t buflen)
size_t WSResponse::_response::ReadContent(char* buf, size_t buflen)
{
size_t s = 0;
if (!m_contentChunked)
Expand Down Expand Up @@ -411,7 +450,7 @@ size_t WSResponse::ReadContent(char* buf, size_t buflen)
return s;
}

bool WSResponse::GetHeaderValue(const std::string& header, std::string& value)
bool WSResponse::_response::GetHeaderValue(const std::string& header, std::string& value)
{
for (HeaderList::const_iterator it = m_headers.begin(); it != m_headers.end(); ++it)
{
Expand Down
96 changes: 63 additions & 33 deletions noson/src/private/wsresponse.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,51 +40,81 @@ namespace NSROOT
class WSResponse
{
public:
WSResponse(const WSRequest& request);
WSResponse(const WSRequest& request) : WSResponse(request, 1, true, false) { }
WSResponse(const WSRequest &request, int maxRedirs, bool trustedLocation, bool followAny);
~WSResponse();

bool IsSuccessful() const { return m_successful; }
bool IsChunkedTransfer() const { return m_contentChunked; }
size_t GetContentLength() const { return m_contentLength; }
size_t ReadContent(char *buf, size_t buflen);
size_t GetConsumed() const { return m_consumed; }
int GetStatusCode() const { return m_statusCode; }
const std::string& Redirection() const { return m_location; }
bool IsSuccessful() const { return p->IsSuccessful(); }
bool IsChunkedTransfer() const { return p->IsChunkedTransfer(); }
size_t GetContentLength() const { return p->GetContentLength(); }
size_t ReadContent(char *buf, size_t buflen) { return p->ReadContent(buf, buflen); }
size_t GetConsumed() const { return p->GetConsumed(); }
int GetStatusCode() const { return p->GetStatusCode(); }
const std::string& Redirection() const { return p->Redirection(); }

bool GetHeaderValue(const std::string& header, std::string& value);
bool GetHeaderValue(const std::string& header, std::string& value)
{
return p->GetHeaderValue(header, value);
}

// helpers
static bool ReadHeaderLine(NetSocket *socket, const char *eol, std::string& line, size_t *len);

private:
TcpSocket *m_socket;
bool m_successful;
int m_statusCode;
std::string m_serverInfo;
std::string m_etag;
std::string m_location;
CT_t m_contentType;
CE_t m_contentEncoding;
bool m_contentChunked;
size_t m_contentLength;
size_t m_consumed;
char* m_chunkBuffer; ///< The chunk data buffer
char* m_chunkPtr; ///< The next position to read data from the chunk
char* m_chunkEOR; ///< The end of received data in the chunk
char* m_chunkEnd; ///< The end of the chunk buffer
Decompressor *m_decoder;

typedef std::list<std::pair<std::string, std::string> > HeaderList;
HeaderList m_headers;

// prevent copy
WSResponse(const WSResponse&);
WSResponse& operator=(const WSResponse&);

bool SendRequest(const WSRequest& request);
bool GetResponse();
size_t ReadChunk(void *buf, size_t buflen);
static int SocketStreamReader(void *hdl, void *buf, int sz);
static int ChunkStreamReader(void *hdl, void *buf, int sz);
class _response
{
public:
_response(const WSRequest& request);
~_response();

bool IsSuccessful() const { return m_successful; }
bool IsChunkedTransfer() const { return m_contentChunked; }
size_t GetContentLength() const { return m_contentLength; }
size_t ReadContent(char *buf, size_t buflen);
size_t GetConsumed() const { return m_consumed; }
int GetStatusCode() const { return m_statusCode; }
const std::string& Redirection() const { return m_location; }

bool GetHeaderValue(const std::string& header, std::string& value);

private:
TcpSocket *m_socket;
bool m_successful;
int m_statusCode;
std::string m_serverInfo;
std::string m_etag;
std::string m_location;
CT_t m_contentType;
CE_t m_contentEncoding;
bool m_contentChunked;
size_t m_contentLength;
size_t m_consumed;
char* m_chunkBuffer; ///< The chunk data buffer
char* m_chunkPtr; ///< The next position to read data from the chunk
char* m_chunkEOR; ///< The end of received data in the chunk
char* m_chunkEnd; ///< The end of the chunk buffer
Decompressor *m_decoder;

typedef std::list<std::pair<std::string, std::string> > HeaderList;
HeaderList m_headers;

// prevent copy
_response(const _response&);
_response& operator=(const _response&);

bool SendRequest(const WSRequest& request);
bool GetResponse();
size_t ReadChunk(void *buf, size_t buflen);
static int SocketStreamReader(void *hdl, void *buf, int sz);
static int ChunkStreamReader(void *hdl, void *buf, int sz);
};

_response * p;
};

}
Expand Down

0 comments on commit 3bced6c

Please sign in to comment.