diff options
-rw-r--r-- | include/HttpClient.h | 44 | ||||
-rw-r--r-- | lib/HttpClient.cc | 95 |
2 files changed, 139 insertions, 0 deletions
diff --git a/include/HttpClient.h b/include/HttpClient.h new file mode 100644 index 0000000..b2b8d22 --- /dev/null +++ b/include/HttpClient.h @@ -0,0 +1,44 @@ +#ifndef __HTTPCLIENT_H__ +#define __HTTPCLIENT_H__ + +#include <vector> + +#include <Socket.h> +#include <BString.h> +#include <Task.h> +#include <Handle.h> +#include <Buffer.h> +#include <Exceptions.h> + +typedef std::vector<String> t_headers; + +extern t_headers no_headers; + +class HttpClient : public Task { + public: + HttpClient(const String & url, Handle * out, int * http_code = 0, const String & fake_host = "", t_headers = no_headers); + virtual ~HttpClient(); + String GetStatus(); + + protected: + virtual int Do() throw (GeneralException); + + private: + void DecodeURL() throw (GeneralException); + + String url; + Handle * out; + int * http_code_p; + String fake_host; + t_headers headers; + Socket Client; + + Buffer b; + + String host, uri; + int http_code; + + Task * c; +}; + +#endif diff --git a/lib/HttpClient.cc b/lib/HttpClient.cc new file mode 100644 index 0000000..f95af79 --- /dev/null +++ b/lib/HttpClient.cc @@ -0,0 +1,95 @@ +#include <HttpClient.h> +#include <BRegex.h> +#include <CopyJob.h> +#include <ReadJob.h> + +t_headers no_headers; + +HttpClient::HttpClient(const String & _url, Handle * _out, int * _http_code_p, const String & _fake_host, t_headers _headers) : url(_url), out(_out), http_code_p(_http_code_p), fake_host(_fake_host), headers(_headers), host(""), uri("") { + DecodeURL(); + + Client.SetNonBlock(); + Client.Connect(host, 80); + + if (Client.IsConnected()) { + SetBurst(); + } else { + WaitFor(&Client, W4_WRITING); + } +} + +HttpClient::~HttpClient() { +} + +int HttpClient::Do() throw (GeneralException) { + t_headers::iterator i; + String t; + + switch (current) { + case 0: + if (Client.IsConnecting()) { + Client.FinalizeConnect(); + } + if (!Client.IsConnected()) { + return TASK_DONE; + } + current = 1; + + case 1: + b << "GET " + uri + " HTTP/1.1\r\n" + "Host: " + (fake_host == "" ? host : fake_host) + "\r\n" + "Connection: close\r\n"; + + for (i = headers.begin(); i != headers.end(); i++) { + b << *i + "\r\n"; + } + + b << "\r\n"; + + c = new CopyJob(&b, &Client); + WaitFor(c); + current = 2; + Suspend(TASK_ON_HOLD); + + case 2: + delete c; + + c = new ReadJob(&Client, &b); + WaitFor(c); + current = 3; + Suspend(TASK_ON_HOLD); + + case 3: + delete c; + + do { + b >> t; + printm(M_INFO, "Got response: " + t + "\n"); + } while (t.strlen()); + + } +} + +String HttpClient::GetStatus() { + return ""; +} + +void HttpClient::DecodeURL() throw (GeneralException) { + int p; + + static const Regex isURLValid("^http://[^/]"); + + if (!isURLValid.Match(url)) + throw GeneralException("Invalid URL."); + + String tmp = url.extract(7); + p = tmp.strchr('/'); + + if (p < 0) { + host = tmp; + return; + } + + host = tmp.extract(0, p - 1); + uri = tmp.extract(p); +} |