Add unix socket support
This commit is contained in:
@ -8,11 +8,20 @@ int main(int argc, char** argv)
|
||||
if(argc < 3)
|
||||
{
|
||||
printf("USAGE: %s <url> <path>\n",argv[0]);
|
||||
printf("USAGE: %s <unixSocket> <url> <path>\n",argv[0]);
|
||||
return 1;
|
||||
}
|
||||
std::string path = argv[2];
|
||||
Tesses::Framework::Http::DownloadToFileSimple(argv[1],path);
|
||||
|
||||
if(argc >= 4)
|
||||
{
|
||||
std::string unixSocket = argv[1];
|
||||
std::string url = argv[2];
|
||||
std::string path = argv[3];
|
||||
Tesses::Framework::Http::DownloadUnixSocketToFileSimple(unixSocket,url,path);
|
||||
}
|
||||
else {
|
||||
std::string path = argv[2];
|
||||
Tesses::Framework::Http::DownloadToFileSimple(argv[1],path);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -45,10 +45,12 @@ namespace Tesses::Framework::Http
|
||||
|
||||
std::string method;
|
||||
std::string url;
|
||||
std::string unixSocket;
|
||||
HttpDictionary requestHeaders;
|
||||
HttpRequestBody* body;
|
||||
|
||||
static Tesses::Framework::Streams::Stream* EstablishConnection(Uri uri,bool ignoreSSLErrors,std::string trusted_root_cert_bundle);
|
||||
static Tesses::Framework::Streams::Stream* EstablishUnixPathConnection(std::string unixPath, Uri uri, bool ignoreSSLErrors, std::string trusted_root_cert_bundle);
|
||||
|
||||
void SendRequest(Tesses::Framework::Streams::Stream* strm);
|
||||
};
|
||||
@ -77,8 +79,22 @@ namespace Tesses::Framework::Http
|
||||
void DownloadToFileSimple(std::string url, Tesses::Framework::Filesystem::VFS& vfs, Tesses::Framework::Filesystem::VFSPath path);
|
||||
void DownloadToFileSimple(std::string url, Tesses::Framework::Filesystem::VFSPath path);
|
||||
std::string DownloadToStringSimple(std::string url);
|
||||
|
||||
bool WebSocketClientSuccessDefault(HttpDictionary& dict,bool v);
|
||||
void WebSocketClient(std::string url, HttpDictionary& requestHeaders, WebSocketConnection& wsc, std::function<bool(HttpDictionary&,bool)> cb=WebSocketClientSuccessDefault);
|
||||
void WebSocketClient(std::string url, HttpDictionary& requestHeaders, WebSocketConnection* wsc, std::function<bool(HttpDictionary&,bool)> cb=WebSocketClientSuccessDefault);
|
||||
|
||||
|
||||
void DownloadUnixSocketToStreamSimple(std::string unixSocket,std::string url, Tesses::Framework::Streams::Stream* strm);
|
||||
void DownloadUnixSocketToStreamSimple(std::string unixSocket,std::string url, Tesses::Framework::Streams::Stream& strm);
|
||||
|
||||
void DownloadUnixSocketToFileSimple(std::string unixSocket,std::string url, Tesses::Framework::Filesystem::VFS* vfs, Tesses::Framework::Filesystem::VFSPath path);
|
||||
void DownloadUnixSocketToFileSimple(std::string unixSocket,std::string url, Tesses::Framework::Filesystem::VFS& vfs, Tesses::Framework::Filesystem::VFSPath path);
|
||||
|
||||
void DownloadUnixSocketToFileSimple(std::string unixSocket,std::string url, Tesses::Framework::Filesystem::VFSPath path);
|
||||
std::string DownloadUnixSocketToStringSimple(std::string unixSocket,std::string url);
|
||||
|
||||
|
||||
void WebSocketUnixSocketClient(std::string unixSocket,std::string url, HttpDictionary& requestHeaders, WebSocketConnection& wsc, std::function<bool(HttpDictionary&,bool)> cb=WebSocketClientSuccessDefault);
|
||||
void WebSocketUnixSocketClient(std::string unixSocket,std::string url,HttpDictionary& requestHeaders, WebSocketConnection* wsc, std::function<bool(HttpDictionary&,bool)> cb=WebSocketClientSuccessDefault);
|
||||
}
|
||||
@ -88,6 +88,7 @@ namespace Tesses::Framework::Http
|
||||
bool ownsTCP;
|
||||
bool ownsHttp;
|
||||
bool showIPs;
|
||||
bool showARTL;
|
||||
|
||||
public:
|
||||
HttpServer(Tesses::Framework::Streams::TcpServer& tcpServer, IHttpServer& http, bool showIPs=true);
|
||||
@ -96,6 +97,8 @@ namespace Tesses::Framework::Http
|
||||
HttpServer(Tesses::Framework::Streams::TcpServer* tcpServer, bool ownsTCP, IHttpServer* http, bool ownsHttpServer, bool showIPs=true);
|
||||
HttpServer(uint16_t port, IHttpServer& http, bool showIPs=true);
|
||||
HttpServer(uint16_t port, IHttpServer* http, bool owns, bool showIPs=true);
|
||||
HttpServer(std::string unixPath, IHttpServer& http);
|
||||
HttpServer(std::string unixPath, IHttpServer* http, bool owns);
|
||||
uint16_t GetPort();
|
||||
void StartAccepting();
|
||||
static void Process(Tesses::Framework::Streams::Stream& strm, IHttpServer& server, std::string ip, uint16_t port, bool encrypted);
|
||||
|
||||
@ -14,6 +14,7 @@ namespace Tesses::Framework::Streams
|
||||
TcpServer(int32_t sock,bool owns);
|
||||
TcpServer(uint16_t port, int32_t backlog);
|
||||
TcpServer(std::string ip, uint16_t port, int32_t backlog);
|
||||
TcpServer(std::string unixPath,int32_t backlog);
|
||||
NetworkStream* GetStream(std::string& ip, uint16_t& port);
|
||||
uint16_t GetPort();
|
||||
~TcpServer();
|
||||
@ -30,6 +31,7 @@ namespace Tesses::Framework::Streams
|
||||
bool CanRead();
|
||||
bool CanWrite();
|
||||
NetworkStream(bool ipV6,bool datagram);
|
||||
NetworkStream(std::string unixPath,bool isServer);
|
||||
NetworkStream(std::string ipOrFqdn, uint16_t port, bool datagram,bool broadcast,bool supportIPv6);
|
||||
NetworkStream(int32_t sock, bool owns);
|
||||
uint16_t GetPort();
|
||||
|
||||
@ -117,7 +117,6 @@ namespace Tesses::Framework::Http
|
||||
body->Write(strm);
|
||||
}
|
||||
}
|
||||
|
||||
Stream* HttpRequest::EstablishConnection(Uri uri, bool ignoreSSLErrors, std::string trusted_root_cert_bundle)
|
||||
{
|
||||
if(uri.scheme == "http:" || uri.scheme == "ws:")
|
||||
@ -127,7 +126,22 @@ namespace Tesses::Framework::Http
|
||||
else if(uri.scheme == "https:" || uri.scheme == "wss:")
|
||||
{
|
||||
auto netStrm = new NetworkStream(uri.host,uri.GetPort(),false,false,false);
|
||||
if(netStrm == nullptr) return netStrm;
|
||||
if(netStrm == nullptr) return nullptr;
|
||||
return new ClientTLSStream(netStrm, true, ignoreSSLErrors,uri.host, trusted_root_cert_bundle);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
Stream* HttpRequest::EstablishUnixPathConnection(std::string unixPath,Uri uri, bool ignoreSSLErrors, std::string trusted_root_cert_bundle)
|
||||
{
|
||||
if(uri.scheme == "http:" || uri.scheme == "ws:")
|
||||
{
|
||||
return new NetworkStream(unixPath,false);
|
||||
}
|
||||
else if(uri.scheme == "https:" || uri.scheme == "wss:")
|
||||
{
|
||||
auto netStrm = new NetworkStream(unixPath,false);
|
||||
if(netStrm == nullptr) return nullptr;
|
||||
return new ClientTLSStream(netStrm, true, ignoreSSLErrors,uri.host, trusted_root_cert_bundle);
|
||||
}
|
||||
|
||||
@ -182,7 +196,7 @@ namespace Tesses::Framework::Http
|
||||
Uri uri;
|
||||
while(Uri::TryParse(url, uri))
|
||||
{
|
||||
auto strm = HttpRequest::EstablishConnection(uri, req.ignoreSSLErrors,req.trusted_root_cert_bundle);
|
||||
auto strm = req.unixSocket.empty() ? HttpRequest::EstablishConnection(uri, req.ignoreSSLErrors,req.trusted_root_cert_bundle) : HttpRequest::EstablishUnixPathConnection(req.unixSocket,uri, req.ignoreSSLErrors,req.trusted_root_cert_bundle);
|
||||
if(strm == nullptr) return;
|
||||
auto reqHeaders = req.requestHeaders;
|
||||
|
||||
@ -284,50 +298,84 @@ namespace Tesses::Framework::Http
|
||||
return new HttpStream(this->handleStrm,false,length,true,version=="HTTP/1.1");
|
||||
}
|
||||
|
||||
void DownloadToStreamSimple(std::string url, Tesses::Framework::Streams::Stream* strm)
|
||||
void DownloadUnixSocketToStreamSimple(std::string unixSocket,std::string url, Tesses::Framework::Streams::Stream* strm)
|
||||
{
|
||||
if(strm == nullptr) throw TextException("strm is null");
|
||||
HttpRequest request;
|
||||
request.url = url;
|
||||
request.unixSocket = unixSocket;
|
||||
request.followRedirects=true;
|
||||
request.method = "GET";
|
||||
HttpResponse response(request);
|
||||
if(response.statusCode < 200 || response.statusCode > 299) throw TextException("Status code does not indicate success: " + std::to_string(response.statusCode) + " " + HttpUtils::StatusCodeString(response.statusCode));
|
||||
response.CopyToStream(strm);
|
||||
}
|
||||
void DownloadToStreamSimple(std::string url, Tesses::Framework::Streams::Stream& strm)
|
||||
void DownloadUnixSocketToStreamSimple(std::string unixSocket,std::string url, Tesses::Framework::Streams::Stream& strm)
|
||||
{
|
||||
DownloadToStreamSimple(url,&strm);
|
||||
DownloadUnixSocketToStreamSimple(unixSocket,url,&strm);
|
||||
}
|
||||
|
||||
void DownloadToFileSimple(std::string url, Tesses::Framework::Filesystem::VFS* vfs, Tesses::Framework::Filesystem::VFSPath path)
|
||||
void DownloadUnixSocketToFileSimple(std::string unixSocket,std::string url, Tesses::Framework::Filesystem::VFS* vfs, Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
if(vfs == nullptr) throw TextException("vfs is null");
|
||||
auto strm = vfs->OpenFile(path,"wb");
|
||||
if(strm == nullptr) throw TextException("strm is null");
|
||||
DownloadToStreamSimple(url,strm);
|
||||
DownloadUnixSocketToStreamSimple(unixSocket,url,strm);
|
||||
delete strm;
|
||||
}
|
||||
void DownloadToFileSimple(std::string url, Tesses::Framework::Filesystem::VFS& vfs, Tesses::Framework::Filesystem::VFSPath path)
|
||||
void DownloadUnixSocketToFileSimple(std::string unixSocket,std::string url, Tesses::Framework::Filesystem::VFS& vfs, Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
auto strm = vfs.OpenFile(path,"wb");
|
||||
if(strm == nullptr) throw TextException("strm is null");
|
||||
DownloadToStreamSimple(url,strm);
|
||||
DownloadUnixSocketToStreamSimple(unixSocket,url,strm);
|
||||
delete strm;
|
||||
}
|
||||
void DownloadUnixSocketToFileSimple(std::string unixSocket,std::string url, Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
DownloadUnixSocketToFileSimple(unixSocket,url,Tesses::Framework::Filesystem::LocalFS,path);
|
||||
}
|
||||
std::string DownloadUnixSocketToStringSimple(std::string unixSocket,std::string url)
|
||||
{
|
||||
HttpRequest request;
|
||||
request.url = url;
|
||||
request.unixSocket = unixSocket;
|
||||
request.followRedirects=true;
|
||||
request.method = "GET";
|
||||
HttpResponse response(request);
|
||||
if(response.statusCode < 200 || response.statusCode > 299) throw TextException("Status code does not indicate success: " + std::to_string(response.statusCode) + " " + HttpUtils::StatusCodeString(response.statusCode));
|
||||
return response.ReadAsString();
|
||||
}
|
||||
void DownloadToStreamSimple(std::string url, Tesses::Framework::Streams::Stream* strm)
|
||||
{
|
||||
DownloadUnixSocketToStreamSimple("",url,strm);
|
||||
}
|
||||
void DownloadToStreamSimple(std::string url, Tesses::Framework::Streams::Stream& strm)
|
||||
{
|
||||
DownloadUnixSocketToStreamSimple("",url,strm);
|
||||
}
|
||||
|
||||
void DownloadToFileSimple(std::string url, Tesses::Framework::Filesystem::VFS* vfs, Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
DownloadUnixSocketToFileSimple("",url,vfs,path);
|
||||
}
|
||||
void DownloadToFileSimple(std::string url, Tesses::Framework::Filesystem::VFS& vfs, Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
DownloadUnixSocketToFileSimple("",url,vfs,path);
|
||||
}
|
||||
void DownloadToFileSimple(std::string url, Tesses::Framework::Filesystem::VFSPath path)
|
||||
{
|
||||
DownloadToFileSimple(url,Tesses::Framework::Filesystem::LocalFS,path);
|
||||
DownloadUnixSocketToFileSimple("",url,path);
|
||||
}
|
||||
std::string DownloadToStringSimple(std::string url)
|
||||
{
|
||||
HttpRequest request;
|
||||
HttpRequest request;
|
||||
request.url = url;
|
||||
request.followRedirects=true;
|
||||
request.method = "GET";
|
||||
HttpResponse response(request);
|
||||
if(response.statusCode < 200 || response.statusCode > 299) throw TextException("Status code does not indicate success: " + std::to_string(response.statusCode) + " " + HttpUtils::StatusCodeString(response.statusCode));
|
||||
return response.ReadAsString();
|
||||
|
||||
}
|
||||
bool WebSocketClientSuccessDefault(HttpDictionary& dict,bool v)
|
||||
{
|
||||
@ -335,7 +383,11 @@ namespace Tesses::Framework::Http
|
||||
}
|
||||
void WebSocketClient(std::string url, HttpDictionary& requestHeaders, WebSocketConnection& wsc, std::function<bool(HttpDictionary&,bool)> cb)
|
||||
{
|
||||
WebSocketClient(url,requestHeaders, &wsc,cb);
|
||||
WebSocketUnixSocketClient("",url,requestHeaders,wsc,cb);
|
||||
}
|
||||
void WebSocketUnixSocketClient(std::string unixSocket,std::string url, HttpDictionary& requestHeaders, WebSocketConnection& wsc, std::function<bool(HttpDictionary&,bool)> cb)
|
||||
{
|
||||
WebSocketUnixSocketClient(unixSocket,url,requestHeaders, &wsc,cb);
|
||||
}
|
||||
|
||||
class WSClient {
|
||||
@ -574,13 +626,18 @@ namespace Tesses::Framework::Http
|
||||
};
|
||||
|
||||
|
||||
|
||||
void WebSocketClient(std::string url, HttpDictionary& requestHeaders, WebSocketConnection* wsc, std::function<bool(HttpDictionary&,bool)> cb)
|
||||
{
|
||||
WebSocketUnixSocketClient("",url,requestHeaders,wsc,cb);
|
||||
}
|
||||
|
||||
void WebSocketUnixSocketClient(std::string unixSocket,std::string url, HttpDictionary& requestHeaders, WebSocketConnection* wsc, std::function<bool(HttpDictionary&,bool)> cb)
|
||||
{
|
||||
HttpRequest req;
|
||||
req.url = url;
|
||||
req.requestHeaders = requestHeaders;
|
||||
req.followRedirects=true;
|
||||
req.unixSocket = unixSocket;
|
||||
|
||||
std::string hash = "";
|
||||
|
||||
|
||||
@ -550,6 +550,7 @@ namespace Tesses::Framework::Http
|
||||
this->ownsHttp = ownsHttpServer;
|
||||
this->showIPs = showIPs;
|
||||
this->thrd=nullptr;
|
||||
this->showARTL = showIPs;
|
||||
}
|
||||
|
||||
|
||||
@ -561,6 +562,15 @@ namespace Tesses::Framework::Http
|
||||
{
|
||||
|
||||
}
|
||||
HttpServer::HttpServer(std::string unixPath, IHttpServer* http, bool owns) : HttpServer(new TcpServer(unixPath,10),true,http,owns,false)
|
||||
{
|
||||
this->showARTL=true;
|
||||
}
|
||||
HttpServer::HttpServer(std::string unixPath, IHttpServer& http) : HttpServer(unixPath,&http,false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
uint16_t HttpServer::GetPort()
|
||||
{
|
||||
if(server != nullptr)
|
||||
@ -633,6 +643,11 @@ namespace Tesses::Framework::Http
|
||||
std::cout << "\x1B[35mhttp://";
|
||||
std::cout << _ip.second << ":" << std::to_string(this->GetPort()) << "/\n";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if(this->showARTL)
|
||||
{
|
||||
if(!svr->IsValid()) std::cout << "\x1B[31mError, we failed to bind or something\x1B[39m\n" << std::endl;
|
||||
std::cout << "\x1B[31mAlmost Ready to Listen\x1B[39m\n";
|
||||
}
|
||||
|
||||
@ -93,6 +93,7 @@ namespace Tesses::Framework::Http {
|
||||
uri.port=0;
|
||||
auto firstPart = HttpUtils::SplitString(url,"//",2);
|
||||
if(firstPart.size() == 2)
|
||||
|
||||
uri.scheme=firstPart[0];
|
||||
else if(firstPart.empty())
|
||||
return false;
|
||||
|
||||
@ -34,6 +34,9 @@ extern "C" {
|
||||
#include <netdb.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#if defined(AF_UNIX)
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if defined(GEKKO)
|
||||
@ -264,6 +267,81 @@ namespace Tesses::Framework::Streams {
|
||||
uint32_t addr;
|
||||
uint8_t addr_parts[4];
|
||||
} my_addr_t;
|
||||
NetworkStream::NetworkStream(std::string unixPath,bool isServer)
|
||||
{
|
||||
this->endOfStream=false;
|
||||
this->owns = true;
|
||||
this->success=false;
|
||||
#if defined(AF_UNIX)
|
||||
this->sock = NETWORK_SOCKET(AF_UNIX,SOCK_STREAM,0);
|
||||
if(this->sock < 0)
|
||||
{
|
||||
this->success=false;
|
||||
return;
|
||||
}
|
||||
struct sockaddr_un unx;
|
||||
|
||||
memset(&unx, 0, sizeof(unx));
|
||||
unx.sun_family = AF_UNIX;
|
||||
|
||||
strncpy(unx.sun_path, unixPath.c_str(),sizeof(unx.sun_path)-1);
|
||||
|
||||
if(isServer)
|
||||
{
|
||||
unlink(unixPath.c_str());
|
||||
if(NETWORK_BIND(this->sock, (const sockaddr*)&unx, (socklen_t)sizeof(unx)) != 0)
|
||||
{
|
||||
std::cout << "FAILED TO BIND: " << strerror(errno) << std::endl;
|
||||
this->success = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(NETWORK_CONNECT(this->sock,(const sockaddr*)&unx, (socklen_t)sizeof(unx)) != 0)
|
||||
{
|
||||
this->success=false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
TcpServer::TcpServer(std::string unixPath,int32_t backlog)
|
||||
{
|
||||
|
||||
|
||||
this->owns=true;
|
||||
this->valid=false;
|
||||
#if defined(AF_UNIX)
|
||||
this->sock = NETWORK_SOCKET(AF_UNIX,SOCK_STREAM,0);
|
||||
if(this->sock < 0)
|
||||
{
|
||||
this->valid=false;
|
||||
return;
|
||||
}
|
||||
struct sockaddr_un unx;
|
||||
|
||||
memset(&unx, 0, sizeof(unx));
|
||||
unx.sun_family = AF_UNIX;
|
||||
unlink(unixPath.c_str());
|
||||
strncpy(unx.sun_path, unixPath.c_str(),sizeof(unx.sun_path)-1);
|
||||
if(NETWORK_BIND(this->sock, (const sockaddr*)&unx, (socklen_t)sizeof(unx)) != 0)
|
||||
{
|
||||
std::cout << "FAILED TO BIND: " << strerror(errno) << std::endl;
|
||||
this->valid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(NETWORK_LISTEN(this->sock, backlog) != 0)
|
||||
{
|
||||
std::cout << "FAILED TO LISTEN FOR SOME REASON" << std::endl;
|
||||
this->valid = false;
|
||||
return;
|
||||
}
|
||||
this->valid = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
TcpServer::TcpServer(uint16_t port, int32_t backlog)
|
||||
{
|
||||
@ -302,7 +380,7 @@ namespace Tesses::Framework::Streams {
|
||||
}
|
||||
if(NETWORK_BIND(this->sock, (const sockaddr*)&addr, (socklen_t)sizeof(addr)) != 0)
|
||||
{
|
||||
std::cout << "FAILED TO BIND FOR SOME REASON" << std::endl;
|
||||
std::cout << "FAILED TO BIND: " << strerror(errno) << std::endl;
|
||||
this->valid = false;
|
||||
return;
|
||||
}
|
||||
@ -387,6 +465,8 @@ namespace Tesses::Framework::Streams {
|
||||
|
||||
if(NETWORK_BIND(this->sock, (const sockaddr*)&addr, (socklen_t)sizeof(addr)) != 0)
|
||||
{
|
||||
|
||||
std::cout << "FAILED TO BIND: " << strerror(errno) << std::endl;
|
||||
this->valid = false;
|
||||
return;
|
||||
}
|
||||
@ -557,6 +637,8 @@ namespace Tesses::Framework::Streams {
|
||||
int r = NETWORK_BIND(this->sock, (struct sockaddr*)&addr, sizeof(addr));
|
||||
if(r != 0)
|
||||
{
|
||||
|
||||
std::cout << "FAILED TO BIND: " << strerror(errno) << std::endl;
|
||||
this->success=false;
|
||||
if(this->owns)
|
||||
NETWORK_CLOSE(this->sock);
|
||||
@ -683,6 +765,10 @@ TcpServer::TcpServer(uint16_t port, int32_t backlog)
|
||||
TcpServer::TcpServer(std::string ip, uint16_t port, int32_t backlog)
|
||||
{
|
||||
|
||||
}
|
||||
TcpServer::TcpServer(std::string unixPath,int32_t backlog)
|
||||
{
|
||||
|
||||
}
|
||||
NetworkStream* TcpServer::GetStream(std::string& ip, uint16_t& port)
|
||||
{
|
||||
@ -717,6 +803,10 @@ NetworkStream::NetworkStream(bool ipV6,bool datagram)
|
||||
NetworkStream::NetworkStream(std::string ipOrFqdn, uint16_t port, bool datagram,bool broadcast,bool supportIPv6)
|
||||
{
|
||||
|
||||
}
|
||||
NetworkStream::NetworkStream(std::string unixPath, bool isServer)
|
||||
{
|
||||
|
||||
}
|
||||
NetworkStream::NetworkStream(int32_t sock, bool owns)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user