summaryrefslogtreecommitdiff
path: root/src/MySock.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/MySock.cpp')
-rw-r--r--src/MySock.cpp104
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()