]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/m_http_client.cpp
Ok, this works except for it wont resolve hosts before full startup. argh why?!
[user/henk/code/inspircd.git] / src / modules / m_http_client.cpp
index 9f8550886018819bf41e535766d37bbd759a38fd..6a72d4eee73a9a12602e7feebbed948e11bcaab5 100644 (file)
@@ -24,7 +24,7 @@ class URL
        int port;
 };
 
-class HTTPSocket : public InspSocket
+class HTTPSocket : public BufferedSocket
 {
  private:
        InspIRCd *Server;
@@ -51,22 +51,27 @@ class HTTPResolver : public Resolver
 {
  private:
        HTTPSocket *socket;
+       std::string orig;
  public:
        HTTPResolver(HTTPSocket *socket, InspIRCd *Instance, const string &hostname, bool &cached, Module* me) : Resolver(Instance, hostname, DNS_QUERY_FORWARD, cached, me), socket(socket)
        {
-               ServerInstance->Log(DEBUG,"Resolving "+hostname);
+               ServerInstance->Log(DEBUG,"HTTPResolver::HTTPResolver");
+               orig = hostname;
        }
        
-       void OnLookupComplete(const string &result, unsigned int ttl, bool cached)
+       void OnLookupComplete(const string &result, unsigned int ttl, bool cached, int resultnum = 0)
        {
-               ServerInstance->Log(DEBUG,"Resolver done");
-               socket->Connect(result);
+               if (!resultnum)
+                       socket->Connect(result);
+               else
+                       socket->Connect(orig);
        }
        
        void OnError(ResolverError e, const string &errmsg)
        {
-               ServerInstance->Log(DEBUG,"Resolver error");
-               delete socket;
+               ServerInstance->Log(DEBUG,"HTTPResolver::OnError");
+               /*if (ServerInstance->SocketCull.find(socket) == ServerInstance->SocketCull.end())
+                       ServerInstance->SocketCull[socket] = socket;*/
        }
 };
 
@@ -78,8 +83,10 @@ class ModuleHTTPClient : public Module
        HTTPList sockets;
 
        ModuleHTTPClient(InspIRCd *Me)
-               : Module::Module(Me)
+               : Module(Me)
        {
+               Implementation eventlist[] = { I_OnRequest };
+               ServerInstance->Modules->Attach(eventlist, this, 1);
        }
        
        virtual ~ModuleHTTPClient()
@@ -93,10 +100,6 @@ class ModuleHTTPClient : public Module
                return Version(1, 0, 0, 0, VF_SERVICEPROVIDER | VF_VENDOR, API_VERSION);
        }
 
-       void Implements(char* List)
-       {
-               List[I_OnRequest] = 1;
-       }
 
        char* OnRequest(Request *req)
        {
@@ -112,9 +115,9 @@ class ModuleHTTPClient : public Module
 };
 
 HTTPSocket::HTTPSocket(InspIRCd *Instance, ModuleHTTPClient *Mod)
-               : InspSocket(Instance), Server(Instance), Mod(Mod), status(HTTP_CLOSED)
+               : BufferedSocket(Instance), Server(Instance), Mod(Mod), status(HTTP_CLOSED)
 {
-       this->ClosePending = false;
+       Instance->Log(DEBUG,"HTTPSocket::HTTPSocket");
        this->port = 80;
 }
 
@@ -133,6 +136,7 @@ HTTPSocket::~HTTPSocket()
 
 bool HTTPSocket::DoRequest(HTTPClientRequest *req)
 {
+       Instance->Log(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
@@ -140,40 +144,26 @@ bool HTTPSocket::DoRequest(HTTPClientRequest *req)
         */
        this->req = *req;
 
-       Instance->Log(DEBUG,"Request in progress");
-
        if (!ParseURL(this->req.GetURL()))
-       {
-               Instance->Log(DEBUG,"Parse failed");
                return false;
-       }
        
        this->port = url.port;
        strlcpy(this->host, url.domain.c_str(), MAXBUF);
 
-       in_addr addy1;
-#ifdef IPV6
-       in6_addr addy2;
-       if ((inet_aton(this->host, &addy1) > 0) || (inet_pton(AF_INET6, this->host, &addy2) > 0))
-#else
-       if (inet_aton(this->host, &addy1) > 0)
-#endif
-       {
-               bool cached;
-               HTTPResolver* r = new HTTPResolver(this, Server, url.domain, cached, (Module*)Mod);
-               Instance->AddResolver(r, cached);
-               return true;
-       }
-       else
-       {
-               this->Connect(url.domain);
-       }
+       /*
+       bool cached;
+       HTTPResolver* r = new HTTPResolver(this, Server, url.domain, cached, (Module*)Mod);
+       Instance->AddResolver(r, cached);
+       return true;
+       */
+       Connect(url.domain);
        
        return true;
 }
 
 bool HTTPSocket::ParseURL(const std::string &iurl)
 {
+       Instance->Log(DEBUG,"HTTPSocket::ParseURL");
        url.url = iurl;
        url.port = 80;
        url.protocol = "http";
@@ -182,10 +172,10 @@ bool HTTPSocket::ParseURL(const std::string &iurl)
        
        for (int p = 0;; p++)
        {
-               std::string part = tokenizer.GetToken();
-               if (part.empty() && tokenizer.StreamEnd())
+               std::string part;
+               if (!tokenizer.GetToken(part))
                        break;
-               
+
                if ((p == 0) && (part[part.length() - 1] == ':'))
                {
                        // Protocol ('http:')
@@ -256,6 +246,7 @@ bool HTTPSocket::ParseURL(const std::string &iurl)
 
 void HTTPSocket::Connect(const string &ip)
 {
+       Instance->Log(DEBUG,"HTTPSocket::Connect");
        strlcpy(this->IP, ip.c_str(), MAXBUF);
        
        if (!this->DoConnect())
@@ -288,13 +279,11 @@ bool HTTPSocket::OnConnected()
 
 bool HTTPSocket::OnDataReady()
 {
+       Instance->Log(DEBUG,"HTTPSocket::OnDataReady()");
        char *data = this->Read();
 
-       if (!data)
-       {
-               this->Close();
+       if (!data || !*data)
                return false;
-       }
 
        if (this->status < HTTP_DATA)
        {
@@ -310,13 +299,10 @@ bool HTTPSocket::OnDataReady()
                        {
                                this->status = HTTP_DATA;
                                this->data += this->buffer;
-                               this->buffer = "";
+                               this->buffer.clear();
                                break;
                        }
-//             while ((line = buffer.sstrstr(data, "\r\n")) != NULL)
-//             {
-//                     if (strncmp(data, "\r\n", 2) == 0)
-                       
+
                        if (this->status == HTTP_REQSENT)
                        {
                                // HTTP reply (HTTP/1.1 200 msg)
@@ -329,22 +315,16 @@ bool HTTPSocket::OnDataReady()
                        
                        if ((pos = line.find(':')) != std::string::npos)
                        {
-
-//                     char *hdata = strchr(data, ':');
-                       
-//                     if (!hdata)
-//                             continue;
-                       
-//                     *hdata = '\0';
-                       
-//                     response->AddHeader(data, hdata + 2);
                                response->AddHeader(line.substr(0, pos), line.substr(pos + 1));
-                       
-//                     data = lend + 2;
-                       } else
+                       }
+                       else
+                       {
                                continue;
+                       }
                }
-       } else {
+       }
+       else
+       {
                this->data += data;
        }
        return true;
@@ -352,6 +332,7 @@ bool HTTPSocket::OnDataReady()
 
 void HTTPSocket::OnClose()
 {
+       Instance->Log(DEBUG,"HTTPSocket::OnClose");
        if (data.empty())
                return; // notification that request failed?
 
@@ -360,24 +341,5 @@ void HTTPSocket::OnClose()
        delete response;
 }
 
-class ModuleHTTPClientFactory : public ModuleFactory
-{
- public:
-       ModuleHTTPClientFactory()
-       {
-       }
-       
-       ~ModuleHTTPClientFactory()
-       {
-       }
-       
-       Module *CreateModule(InspIRCd* Me)
-       {
-               return new ModuleHTTPClient(Me);
-       }
-};
+MODULE_INIT(ModuleHTTPClient)
 
-extern "C" void *init_module(void)
-{
-       return new ModuleHTTPClientFactory;
-}