summaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/m_http_client.cpp378
1 files changed, 0 insertions, 378 deletions
diff --git a/src/modules/m_http_client.cpp b/src/modules/m_http_client.cpp
deleted file mode 100644
index ef036f3f2..000000000
--- a/src/modules/m_http_client.cpp
+++ /dev/null
@@ -1,378 +0,0 @@
-/* +------------------------------------+
- * | Inspire Internet Relay Chat Daemon |
- * +------------------------------------+
- *
- * InspIRCd: (C) 2002-2008 InspIRCd Development Team
- * See: http://www.inspircd.org/wiki/index.php/Credits
- *
- * This program is free but copyrighted software; see
- * the file COPYING for details.
- *
- * ---------------------------------------------------
- */
-
-#include "inspircd.h"
-#include "httpclient.h"
-
-/* $ModDesc: HTTP client service provider */
-
-class URL
-{
- public:
- std::string url;
- std::string protocol, username, password, domain, request;
- int port;
-};
-
-class HTTPSocket : public BufferedSocket
-{
- private:
- InspIRCd *Server;
- class ModuleHTTPClient *Mod;
- HTTPClientRequest req;
- HTTPClientResponse *response;
- URL url;
- enum { HTTP_CLOSED, HTTP_REQSENT, HTTP_HEADERS, HTTP_DATA } status;
- std::string data;
- std::string buffer;
- bool closed;
-
- public:
- HTTPSocket(InspIRCd *Instance, class ModuleHTTPClient *Mod);
- virtual ~HTTPSocket();
- virtual bool DoRequest(HTTPClientRequest *req);
- virtual bool ParseURL(const std::string &url);
- virtual void Connect(const std::string &ip);
- virtual bool OnConnected();
- virtual bool OnDataReady();
- virtual void OnClose();
-};
-
-class HTTPResolver : public Resolver
-{
- private:
- HTTPSocket *socket;
- std::string orig;
- public:
- HTTPResolver(HTTPSocket *s, InspIRCd *Instance, const std::string &hostname, bool &cached, Module* me) : Resolver(Instance, hostname, DNS_QUERY_FORWARD, cached, me), socket(s)
- {
- ServerInstance->Logs->Log("m_http_client",DEBUG,">>>>>>>>>>>>>>>>>> HTTPResolver::HTTPResolver <<<<<<<<<<<<<<<");
- orig = hostname;
- }
-
- void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached, int resultnum = 0)
- {
- ServerInstance->Logs->Log("m_http_client",DEBUG,"************* HTTPResolver::OnLookupComplete ***************");
- if (!resultnum)
- socket->Connect(result);
- else
- socket->OnClose();
- }
-
- void OnError(ResolverError e, const std::string &errmsg)
- {
- ServerInstance->Logs->Log("m_http_client",DEBUG,"!!!!!!!!!!!!!!!! HTTPResolver::OnError: %s", errmsg.c_str());
- socket->OnClose();
- }
-};
-
-typedef std::vector<HTTPSocket*> HTTPList;
-
-class ModuleHTTPClient : public Module
-{
- public:
- HTTPList sockets;
-
- ModuleHTTPClient(InspIRCd *Me)
- : Module(Me)
- {
- Implementation eventlist[] = { I_OnRequest };
- ServerInstance->Modules->Attach(eventlist, this, 1);
- }
-
- virtual ~ModuleHTTPClient()
- {
- for (HTTPList::iterator i = sockets.begin(); i != sockets.end(); i++)
- (*i)->Close();
- ServerInstance->BufferedSocketCull();
- }
-
- virtual Version GetVersion()
- {
- return Version(1, 0, 0, 0, VF_SERVICEPROVIDER | VF_VENDOR, API_VERSION);
- }
-
-
- virtual const char* OnRequest(Request *req)
- {
- HTTPClientRequest *httpreq = (HTTPClientRequest *)req;
- if (!strcmp(httpreq->GetId(), HTTP_CLIENT_REQUEST))
- {
- HTTPSocket *sock = new HTTPSocket(ServerInstance, this);
- sock->DoRequest(httpreq);
- // No return value
- }
- return NULL;
- }
-};
-
-HTTPSocket::HTTPSocket(InspIRCd *SI, ModuleHTTPClient *m)
- : BufferedSocket(SI), Server(SI), Mod(m), status(HTTP_CLOSED)
-{
- Instance->Logs->Log("m_http_client",DEBUG,"HTTPSocket::HTTPSocket");
- this->port = 80;
- response = NULL;
- closed = false;
- timeout_val = 10;
-}
-
-HTTPSocket::~HTTPSocket()
-{
- Close();
- for (HTTPList::iterator i = Mod->sockets.begin(); i != Mod->sockets.end(); i++)
- {
- if (*i == this)
- {
- Mod->sockets.erase(i);
- break;
- }
- }
-}
-
-bool HTTPSocket::DoRequest(HTTPClientRequest *request)
-{
- Instance->Logs->Log("m_http_client",DEBUG,"HTTPSocket::DoRequest");
- /* Tweak by brain - we take a copy of this,
- * so that the caller doesnt need to leave
- * pointers knocking around, less chance of
- * a memory leak.
- */
- this->req = *request;
-
- if (!ParseURL(this->req.GetURL()))
- return false;
-
- this->port = url.port;
- strlcpy(this->host, url.domain.c_str(), MAXBUF);
-
- Instance->Logs->Log("m_http_client",DEBUG,"Doing request for %s", url.url.c_str());
-
- in6_addr s6;
- in_addr s4;
- /* Doesnt look like an ipv4 or an ipv6 address */
- if ((inet_pton(AF_INET6, url.domain.c_str(), &s6) < 1) && (inet_pton(AF_INET, url.domain.c_str(), &s4) < 1))
- {
- bool cached;
- HTTPResolver* r = new HTTPResolver(this, Server, url.domain, cached, (Module*)Mod);
- Instance->AddResolver(r, cached);
- Instance->Logs->Log("m_http_client",DEBUG,"Resolver added, cached=%d", cached);
- }
- else
- Connect(url.domain);
-
- return true;
-}
-
-bool HTTPSocket::ParseURL(const std::string &iurl)
-{
- Instance->Logs->Log("m_http_client",DEBUG,"HTTPSocket::ParseURL %s", iurl.c_str());
- url.url = iurl;
- url.port = 80;
- url.protocol = "http";
-
- irc::sepstream tokenizer(iurl, '/');
-
- for (int p = 0;; p++)
- {
- std::string part;
- if (!tokenizer.GetToken(part))
- break;
-
- if ((p == 0) && (part[part.length() - 1] == ':'))
- {
- // Protocol ('http:')
- url.protocol = part.substr(0, part.length() - 1);
- }
- else if ((p == 1) && (part.empty()))
- {
- continue;
- }
- else if (url.domain.empty())
- {
- // Domain part: [user[:pass]@]domain[:port]
- std::string::size_type usrpos = part.find('@');
- if (usrpos != std::string::npos)
- {
- // Have a user (and possibly password) part
- std::string::size_type ppos = part.find(':');
- if ((ppos != std::string::npos) && (ppos < usrpos))
- {
- // Have password too
- url.password = part.substr(ppos + 1, usrpos - ppos - 1);
- url.username = part.substr(0, ppos);
- }
- else
- {
- url.username = part.substr(0, usrpos);
- }
-
- part = part.substr(usrpos + 1);
- }
-
- std::string::size_type popos = part.rfind(':');
- if (popos != std::string::npos)
- {
- url.port = atoi(part.substr(popos + 1).c_str());
- url.domain = part.substr(0, popos);
- }
- else
- {
- url.domain = part;
- }
- }
- else
- {
- // Request (part of it)..
- url.request.append("/");
- url.request.append(part);
- }
- }
-
- if (url.request.empty())
- url.request = "/";
-
- if ((url.domain.empty()) || (!url.port) || (url.protocol.empty()))
- {
- Instance->Logs->Log("m_http_client",DEFAULT, "Invalid URL (%s): Missing required value", iurl.c_str());
- return false;
- }
-
- if (url.protocol != "http")
- {
- Instance->Logs->Log("m_http_client",DEFAULT, "Invalid URL (%s): Unsupported protocol '%s'", iurl.c_str(), url.protocol.c_str());
- return false;
- }
-
- return true;
-}
-
-void HTTPSocket::Connect(const std::string &ip)
-{
- this->response = new HTTPClientResponse((Module*)Mod, req.GetSource() , url.url, 0, "");
-
- Instance->Logs->Log("m_http_client",DEBUG,"HTTPSocket::Connect(%s) response=%08lx", ip.c_str(), (unsigned long)response);
- strlcpy(this->IP, ip.c_str(), MAXBUF);
- strlcpy(this->host, ip.c_str(), MAXBUF);
-
- if (!this->DoConnect())
- {
- Instance->Logs->Log("m_http_client",DEBUG,"DoConnect failed, bailing");
- this->Close();
- }
-}
-
-bool HTTPSocket::OnConnected()
-{
- Instance->Logs->Log("m_http_client",DEBUG,"HTTPSocket::OnConnected");
-
- std::string request = "GET " + url.request + " HTTP/1.1\r\n";
-
- // Dump headers into the request
- HeaderMap headers = req.GetHeaders();
-
- for (HeaderMap::iterator i = headers.begin(); i != headers.end(); i++)
- request += i->first + ": " + i->second + "\r\n";
-
- // The Host header is required for HTTP 1.1 and isn't known when the request is created; if they didn't overload it
- // manually, add it here
- if (headers.find("Host") == headers.end())
- request += "Host: " + url.domain + "\r\n";
-
- request += "\r\n";
-
- this->status = HTTP_REQSENT;
-
- this->Write(request);
-
- return true;
-}
-
-bool HTTPSocket::OnDataReady()
-{
- Instance->Logs->Log("m_http_client",DEBUG,"HTTPSocket::OnDataReady() for %s", url.url.c_str());
- const char *sdata = this->Read();
-
- if (!sdata)
- return false;
-
- if (this->status < HTTP_DATA)
- {
- std::string line;
- std::string::size_type pos;
-
- this->buffer += sdata;
- while ((pos = buffer.find("\r\n")) != std::string::npos)
- {
- line = buffer.substr(0, pos);
- buffer = buffer.substr(pos + 2);
- if (line.empty())
- {
- this->status = HTTP_DATA;
- this->data += this->buffer;
- this->buffer.clear();
- break;
- }
-
- if (this->status == HTTP_REQSENT)
- {
- // HTTP reply (HTTP/1.1 200 msg)
- char const* sdata2 = line.c_str();
- sdata2 += 9;
- response->SetResponse(sdata2);
- response->SetData(sdata2 + 4);
- this->status = HTTP_HEADERS;
- continue;
- }
-
- if ((pos = line.find(':')) != std::string::npos)
- {
- response->AddHeader(line.substr(0, pos), line.substr(pos + 1));
- }
- else
- {
- continue;
- }
- }
- }
- else
- {
- this->data += data;
- }
- return true;
-}
-
-void HTTPSocket::OnClose()
-{
- if (!closed)
- {
- closed = true;
- Instance->Logs->Log("m_http_client",DEBUG,"HTTPSocket::OnClose response=%08lx", (unsigned long)response);
- std::string e;
- if (data.empty())
- {
- Instance->Logs->Log("m_http_client",DEBUG,"Send error");
- HTTPClientError* err = new HTTPClientError((Module*)Mod, req.GetSource(), req.GetURL(), 0);
- err->Send();
- delete err;
- return;
- }
-
- Instance->Logs->Log("m_http_client",DEBUG,"Set data and send, %s", response->GetURL().c_str());
- response->SetData(data);
- response->Send();
- delete response;
- }
-}
-
-MODULE_INIT(ModuleHTTPClient)
-