diff options
Diffstat (limited to 'src/MySock.cpp')
| -rw-r--r-- | src/MySock.cpp | 104 |
1 files changed, 100 insertions, 4 deletions
diff --git a/src/MySock.cpp b/src/MySock.cpp index 79e407d..6f73517 100644 --- a/src/MySock.cpp +++ b/src/MySock.cpp @@ -1,7 +1,7 @@ /******************************************************************************* * File: MySock.cpp * - * Version: 0.2 * - * Date: 20081002 * + * Version: 0.4 * + * Date: 20260809 * * Author: Gaspar Fernández (helyo@totaki.com) * * * * Copyright (C) 2008 Gaspar Fernández * @@ -29,9 +29,12 @@ * Date Author Modification * 10.02.2008 Gaspar Fernández Initial release * 31.10.2010 Gaspar Fernández Bug Corrections + * 09.08.2026 Koudai Kudo fetch(1) for FreeBSD ********************************************************************************/ #include "MySock.h" #include <unistd.h> +#include <cstdio> +#include <cctype> /************************************************************* * Function: extract_key_value * ************************************************************* @@ -86,6 +89,7 @@ MySock::MySock() { this->error=NO_ERROR; this->connected=false; + this->use_external_fetch=false; } MySock::MySock(string uri) @@ -96,6 +100,7 @@ MySock::MySock(string uri) string protostr; string req; this->error=NO_ERROR; + this->use_external_fetch=false; string::size_type pos = uri.find("//", 0); string::size_type pos2; @@ -119,6 +124,15 @@ MySock::MySock(string uri) if (this->connected) this->SendData(req); } + else if (protostr=="https") + { + if(this->safe_url(uri)) + { + this->https_url=url; + this->use_external_fetch=true; + this->connection; + } + } else { this->error=NO_VALID_PROTOCOL; @@ -146,6 +160,85 @@ MySock::MySock(string uri) MySock::MySock(string server, int port) { this->MakeConnection(server, port); + this->use_external_fetch=false; +} + +/************************************************************* + * Method: is_safe_url +************************************************************** + * Description: Since https:// URIs end up inside a popen() * + * command, nad only allow a conservation character set. * + * + * Input: + * string url + *************************************************************/ +bool MySock::is_safe_url(const string &url) +{ + for (string::size_type i=0; i<url.length(); i++) + { + char c=url[i]; + if (c=='\'') + return false; + if (!(isalnum((unsigned char)c) || strchr(":/._-?=&%", c)!=NULL)) + return false; + } + return (url.length()>0) && (url.length()<2048); +} + +/************************************************************* + * Method: GetHTTPDataViaExternalFetch() * + ************************************************************* + * Description: * + * Retrieves an https:// URL by shelling out to fetch(1) * + * (FreeBSD base system) via popen(), since this class has * + * no TLS implementation of its own. fetch -o - writes the * + * response body to stdout, so unlike GetHTTPData()'s raw * + * socket path there are no HTTP headers to parse here - we * + * only know success/failure from fetch(1)'s exit status. * + * * + * Input: * + * Nothing (uses this->https_uri) * + * * + * Output: * + * HTTP_Request* - status is 200 on success, 502 if * + * fetch(1) reported an error (bad URL, network failure, * + * HTTP error status, etc); data holds the response body. * + * * + * Change History: * + * Date Author Modification * + * * + *************************************************************/ +HTTP_Request *MySock::GetHTTPDataViaExternalFetch() +{ + HTTP_Request *http; + string cmd; + FILE *pipe; + char buffer[4096]; + size_t n; + cmd=(string)HTTPS_FETCH_CMD+"'"+this->https_uri+"'"+" 2>/dev/null"; + pipe=popen(cmd.data(), "r"); + if (pipe==NULL) + { + this->error=CANT_RUN_FETCH; + return NULL; + } + http=new HTTP_Request; + http->data=""; + while ((n=fread(buffer, 1, sizeof(buffer), pipe))>0) + http->data.append(buffer, n); + int rc=pclose(pipe); + if ((rc==0) && (!http->data.empty())) + { + http->status=200; + http->statusstr="HTTP/1.1 200 OK (via fetch)"; + } + else + { + http->status=502; + http->statusstr="HTTP/1.1 502 Bad Gateway (fetch failed)"; + } + this->connected=false; // "Connection" (the popen pipe) is closed now + return http; } /************************************************************* @@ -293,6 +386,9 @@ HTTP_Request *MySock::GetHTTPData() char buf[255], buf2[255]; TKey_Value hdata; + if (this->use_external_fetch) + return this->GetHTTPDataViaExternalFetch(); + if (this->error==NO_ERROR) { txtData=this->GetTextData(); @@ -354,11 +450,11 @@ HTTP_Request *MySock::GetHTTPData() void MySock::closeConnection() { - if (connected) + if (connected && !use_external_fetch) { close(sockd); - connected=false; } + connected=false; } MySock::~MySock() |
