From 7fba0bdd417b69a308fcb07fec9db17a6b89b829 Mon Sep 17 00:00:00 2001 From: janbar Date: Sat, 25 Nov 2023 02:04:37 +0100 Subject: [PATCH] request redirection --- noson/src/private/uriparser.cpp | 5 ++++ noson/src/private/uriparser.h | 2 ++ noson/src/private/wsrequest.cpp | 49 +++++++++++++++++++++++++++++++++ noson/src/private/wsrequest.h | 5 ++++ 4 files changed, 61 insertions(+) diff --git a/noson/src/private/uriparser.cpp b/noson/src/private/uriparser.cpp index 30494de..e05220a 100644 --- a/noson/src/private/uriparser.cpp +++ b/noson/src/private/uriparser.cpp @@ -54,6 +54,11 @@ void URIParser::URIScan(char *uri, URI_t *parts) *p = '\0'; parts->fragment = ++p; } + if ((p = strchr(uri, '?')) != NULL) + { + *p = '\0'; + parts->params = ++p; + } if ((p = strchr(uri, ' ')) != NULL) *p = '\0'; diff --git a/noson/src/private/uriparser.h b/noson/src/private/uriparser.h index da11bf6..9c5fc5d 100644 --- a/noson/src/private/uriparser.h +++ b/noson/src/private/uriparser.h @@ -42,6 +42,7 @@ namespace NSROOT bool IsRelative() const { return m_parts.relative ? true : false; } const char *Path() const { return IsRelative() ? m_parts.relative : m_parts.absolute; } const char *Fragment() const { return m_parts.fragment; } + const char *Params() const { return m_parts.params; } private: // prevent copy @@ -58,6 +59,7 @@ namespace NSROOT char *absolute; char *relative; char *fragment; + char *params; } URI_t; URI_t m_parts; diff --git a/noson/src/private/wsrequest.cpp b/noson/src/private/wsrequest.cpp index 4185462..7137795 100644 --- a/noson/src/private/wsrequest.cpp +++ b/noson/src/private/wsrequest.cpp @@ -108,6 +108,55 @@ WSRequest::~WSRequest() { } +WSRequest::WSRequest(const WSRequest& o, const URIParser& redirection) +: m_server(o.m_server) +, m_port(o.m_port) +, m_secure_uri(o.m_secure_uri) +, m_service_method(o.m_service_method) +, m_charset(o.m_charset) +, m_accept(o.m_accept) +, m_contentType(o.m_contentType) +, m_contentData(o.m_contentData) +, m_headers(o.m_headers) +, m_userAgent(o.m_userAgent) +{ + if (redirection.Host()) + m_server.assign(redirection.Host()); + if (redirection.Scheme()) + { + if (strncmp(redirection.Scheme(), "https", 5) == 0) + { + m_secure_uri = true; + m_port = redirection.Port() ? redirection.Port() : 443; + } + else + { + m_secure_uri = false; + m_port = redirection.Port() ? redirection.Port() : 80; + } + } + + URIParser o_uri(m_service_url); + m_service_url = "/"; + if (redirection.Path()) + m_service_url.append(redirection.Path()); + // prior redirection fragment then original fragment + if (redirection.Fragment()) + m_service_url.append("#").append(redirection.Fragment()); + else if (o_uri.Fragment()) + m_service_url.append("#").append(o_uri.Fragment()); + // prior redirection params then original params + if (redirection.Params() && strlen(redirection.Params()) > 0) + { + m_contentData.clear(); + m_contentType = CT_FORM; + m_service_method = HRM_GET; + m_service_url.append("?").append(redirection.Params()); + } + else if (o_uri.Params() && strlen(o_uri.Params()) > 0) + m_service_url.append("?").append(o_uri.Params()); +} + void WSRequest::RequestService(const std::string& url, HRM_t method) { m_service_url = url; diff --git a/noson/src/private/wsrequest.h b/noson/src/private/wsrequest.h index f30b405..f3c9d55 100644 --- a/noson/src/private/wsrequest.h +++ b/noson/src/private/wsrequest.h @@ -56,6 +56,9 @@ namespace NSROOT WSRequest(const URIParser& uri, HRM_t method = HRM_GET); ~WSRequest(); + // Clone for redirection: see RFC-9110 section 10.2.2 Location + WSRequest(const WSRequest& o, const URIParser& redirection); + void RequestService(const std::string& url, HRM_t method = HRM_GET); void RequestAccept(CT_t contentType); void RequestAcceptEncoding(bool yesno); @@ -71,6 +74,8 @@ namespace NSROOT const std::string& GetServer() const { return m_server; } unsigned GetPort() const { return m_port; } bool IsSecureURI() const { return m_secure_uri; } + HRM_t GetMethod() const { return m_service_method; } + const std::string& GetURL() const { return m_service_url; } private: std::string m_server;