diff options
-rw-r--r-- | include/HttpClient.h | 13 | ||||
-rw-r--r-- | lib/CopyJob.cc | 7 | ||||
-rw-r--r-- | lib/HttpClient.cc | 117 |
3 files changed, 126 insertions, 11 deletions
diff --git a/include/HttpClient.h b/include/HttpClient.h index b2b8d22..92fcb14 100644 --- a/include/HttpClient.h +++ b/include/HttpClient.h @@ -16,9 +16,12 @@ 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); + HttpClient(const String & url, Handle * out, const String & fake_host = "", t_headers = no_headers); virtual ~HttpClient(); String GetStatus(); + + t_headers reply_headers; + String reply; protected: virtual int Do() throw (GeneralException); @@ -28,16 +31,18 @@ class HttpClient : public Task { String url; Handle * out; - int * http_code_p; String fake_host; t_headers headers; Socket Client; - Buffer b; + Buffer b, b2; - String host, uri; + String host, uri, status; int http_code; + + bool chunked; + Task * c; }; diff --git a/lib/CopyJob.cc b/lib/CopyJob.cc index 0a086b9..7e7c4de 100644 --- a/lib/CopyJob.cc +++ b/lib/CopyJob.cc @@ -43,7 +43,8 @@ int CopyJob::Do() throw (GeneralException) { tr = siz >= 0 ? siz - cursiz : COPY_BUFSIZ; try { r = s->read(buffer, MIN(COPY_BUFSIZ, tr)); -// cerr << "CopyJob: read " << r << " bytes." << endl; +// std::cerr << "CopyJob: read " << r << " bytes." << std::endl; +// std::cerr << buffer; } catch (IOAgain e) { WaitFor(s, W4_READING); @@ -62,10 +63,10 @@ int CopyJob::Do() throw (GeneralException) { WaitFor(d, W4_WRITING); Suspend(TASK_ON_HOLD); } -// cerr << "CopyJob: wrote " << w << " bytes." << endl; +// std::cerr << "CopyJob: wrote " << w << " bytes." << std::endl; tw += w; if (r != tw) { -// cerr << "CopyJob: We did expect to write a total of " << r << " bytes and we achieved " << tw << " bytes so far.\n"; +// std::cerr << "CopyJob: We did expect to write a total of " << r << " bytes and we achieved " << tw << " bytes so far.\n"; WaitFor(d, W4_WRITING); Suspend(TASK_ON_HOLD); } diff --git a/lib/HttpClient.cc b/lib/HttpClient.cc index f95af79..0d55391 100644 --- a/lib/HttpClient.cc +++ b/lib/HttpClient.cc @@ -5,7 +5,7 @@ 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("") { +HttpClient::HttpClient(const String & _url, Handle * _out, const String & _fake_host, t_headers _headers) : url(_url), out(_out), fake_host(_fake_host), headers(_headers), host(""), uri("") { DecodeURL(); Client.SetNonBlock(); @@ -24,6 +24,9 @@ HttpClient::~HttpClient() { int HttpClient::Do() throw (GeneralException) { t_headers::iterator i; String t; + int l; + Regex h_reply("^HTTP/1.1 "); + Regex chunked_header("^Transfer-Encoding: chunked$"); switch (current) { case 0: @@ -62,12 +65,118 @@ int HttpClient::Do() throw (GeneralException) { case 3: delete c; - do { + b >> t; + if (!h_reply.Match(t)) { + http_code = 0; + status = "Invalid answer from HTTP server."; + return TASK_DONE; + } + reply = t.extract(9); + chunked = false; + + while (t.strlen()) { b >> t; - printm(M_INFO, "Got response: " + t + "\n"); - } while (t.strlen()); + reply_headers.push_back(t); + if (chunked_header.Match(t)) { + chunked = true; + } + } + + http_code = reply.to_int(); + + if (http_code != 200) { + status = "Reply code != 200."; + return TASK_DONE; + } + + status = "Downloading."; + + if (!chunked) { + current = 6; + c = new CopyJob(&Client, out); + WaitFor(c); + Suspend(TASK_ON_HOLD); + } + +#if 0 + c = new CopyJob(&Client, &b); + current = 4; + WaitFor(c); + Suspend(TASK_ON_HOLD); + + case 4: + delete c; + do { + do { + b >> t; + } while (t.strlen() == 0); + + t.scanf("%x", &l); + if (l) + b.copyto(&b2, l); + + } while (l); + + c = new CopyJob(&b2, out); + WaitFor(c); + current = 5; + Suspend(TASK_ON_HOLD); + + case 5: + delete c; + + status = "Downloaded."; + + return TASK_DONE; +#else + c = 0; + case 4: + if (c) + delete c; + printm(M_INFO, "Creating readjob for number header.\n"); + c = new ReadJob(&Client, &b, any); + WaitFor(c); + current = 5; + Suspend(TASK_ON_HOLD); + + case 5: + delete c; + b >> t; + if (t.strlen() == 0) { + current = 4; + printm(M_INFO, "String is empty, looping.\n"); + c = new ReadJob(&Client, &b, any); + WaitFor(c); + Suspend(TASK_ON_HOLD); + } + + printm(M_INFO, "Read string: " + t + "\n"); + + t.scanf("%x", &l); + + printm(M_INFO, "Read chunk length: " + String(l) + "\n"); + + if (l == 0) { + status = "Downloaded."; + return TASK_DONE; + } + + printm(M_INFO, "Creating copyjob to download chunk.\n"); + + c = new CopyJob(&Client, out, l); + WaitFor(c); + current = 4; + Suspend(TASK_ON_HOLD); +#endif + case 6: + delete c; + + status = "Downloaded."; + return TASK_DONE; } + + return TASK_ON_HOLD; } String HttpClient::GetStatus() { |