28#include "../base/PList.h"
29#include "../base/PComplexData.h"
30#include "../utility/rc_ptrs.h"
35#if HTTP_LIB == PEBL_HAPPY
50 fwrite( data,1,n, stdout );
56 printf(
"COMPLETE (%d bytes)\n",
count );
68 PEBLHTTP* http = (PEBLHTTP*)(userdata);
71 http->SetByteCount(0);
73 http->SetReason(std::string(r->
getreason()));
78 const unsigned char* data,
int n )
80 std::cout <<
"http_getdata_cb 1\n";
82 PEBLHTTP* http = (PEBLHTTP*) (userdata);
83 FILE * filestream = http->GetFileObject();
86 fwrite( data,1,n, filestream);
88 http->SetByteCount(http->GetByteCount()+n);
114 PEBLHTTP* http = (PEBLHTTP*)(userdata);
119 http->SetReason(std::string(r->
getreason()));
120 http->SetByteCount(0);
125 const unsigned char* data,
int n )
132 PEBLHTTP* http = (PEBLHTTP*) (userdata);
133 FILE * filestream = http->GetFileObject();
136 std::string * text = (http->GetTextObject());
137 text->append((
const char*)data, n);
139 std::cout <<
"tmp text:" << *text << std::endl;
141 http->SetByteCount(http->GetByteCount()+n);
146 PEBLHTTP* http = (PEBLHTTP*) userdata;
147 std::string * text = http->GetTextObject();
148 FILE * filestream = http->GetFileObject();
151 printf(
"COMPLETE (%d bytes)\n", http->GetByteCount() );
158PEBLHTTP::PEBLHTTP(
Variant host,
int port)
164 int code = WSAStartup(MAKEWORD(1, 1), &wsaData);
183int PEBLHTTP::GetHTTPFile(
Variant filename,
194 mFile = fopen(savename.
GetString().c_str(),
"wb");
197 std::cerr <<
"Error opening file \n";
201 fwrite(
"",1,0,mFile);
203 conn.setcallbacks( http_begin_cb,
205 http_complete_cb,
this);
211 std::cout <<
"trying to get file: " << filename.
GetString() << std::endl;
212 conn.request(
"GET", filename.
GetString().c_str(), 0, 0,0 );
213 while( conn.outstanding() )
227 sprintf(s,
"Exception:\n%s\n", e.
what() );
240std::string PEBLHTTP::GetHTTPText(
Variant filename)
249 conn.setcallbacks( http_begin_cb2,
251 http_complete_cb2,
this);
256 conn.request(
"GET", filename.
GetString().c_str(), 0, 0,0 );
258 while( conn.outstanding() )
269 std::cerr <<
"Wobbly caught\n";
271 sprintf(s,
"Exception:\n%s\n", e.
what() );
312 conn.putrequest(
"POST", name.
GetString().c_str());
324 std::vector<Variant>::iterator p1 = dataList->
Begin();
325 std::vector<Variant>::iterator p1end = dataList->
End();
330 std::string
head = *p1;
332 std::string value = *p1;
335 conn.putheader(
head.c_str(),value.c_str());
344 const unsigned char* body = (
unsigned char*)(body1.c_str());
347 unsigned int l = strlen(bodyx.
GetString().c_str());
353 while( conn.outstanding() )
356 std::cout <<
"outer-outstanding"<<conn.outstanding() <<
"+" <<std::endl;
361 std::cout <<
"No more ouststanding data to process\n";
369 sprintf(s,
"Exception:\n%s\n", e.
what() );
398#elif HTTP_LIB == PEBL_CURL
412#include <curl/curl.h>
416size_t write_callback(
char *ptr,
size_t size,
size_t nmemb,
void *userdata);
423static size_t WriteMemoryCallback(
void *contents,
size_t size,
424 size_t nmemb,
void *userp)
426 size_t realsize = size * nmemb;
427 struct MemoryStruct *mem = (
struct MemoryStruct *)userp;
429 mem->memory = (
char*)realloc(mem->memory, mem->size + realsize + 1);
430 if(mem->memory ==
NULL) {
432 printf(
"not enough memory (realloc returned NULL)\n");
436 memcpy(&(mem->memory[mem->size]), contents, realsize);
437 mem->size += realsize;
438 mem->memory[mem->size] = 0;
446PEBLHTTP::PEBLHTTP(
Variant host,
int port)
452 curl_global_init(CURL_GLOBAL_ALL);
467int PEBLHTTP::GetHTTPFile(
Variant filename,
473 mCurl = curl_easy_init();
478 Variant fname = mHost + filename;
479 std::cout <<
"--------------*************Getting filename:" << fname << std::endl;
480 curl_easy_setopt(mCurl, CURLOPT_URL,fname.
GetString().c_str());
483 curl_easy_setopt(mCurl, CURLOPT_PORT,mPort);
485 mFile = fopen(savename.
GetString().c_str(),
"wb");
489 fwrite(
"",1,0,mFile);
494 curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, mFile);
504 curl_easy_setopt(mCurl, CURLOPT_HTTPGET, 1L);
507 ret = curl_easy_perform(mCurl);
512 res = curl_easy_setopt(mCurl, CURLOPT_HTTPGET, 1L);
514 if((CURLE_OK == res) && ct)
515 printf(
"We received Content-Type: %s\n", ct);
518 curl_easy_getinfo(mCurl,CURLINFO_RESPONSE_CODE,&http_code);
522 curl_easy_cleanup(mCurl);
534std::string PEBLHTTP::GetHTTPText(
Variant filename)
539 curl_global_init(CURL_GLOBAL_ALL);
540 mCurl = curl_easy_init();
546 Variant fname = mHost + filename;
548 struct MemoryStruct chunk;
550 chunk.memory = (
char*)malloc(1);
558 curl_easy_setopt(mCurl, CURLOPT_URL, fname.
GetString().c_str());
561 curl_easy_setopt(mCurl, CURLOPT_PORT,mPort);
566 curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
569 curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, (
void *)&chunk);
573 curl_easy_setopt(mCurl, CURLOPT_USERAGENT,
"libcurl-agent/1.0");
576 res = curl_easy_perform(mCurl);
579 if(res != CURLE_OK) {
580 fprintf(stderr,
"curl_easy_perform() failed: %s\n",
581 curl_easy_strerror(res));
591 printf(
"%lu bytes retrieved\n", (
long)chunk.size);
592 mText = std::string((
char*)(chunk.memory));
596 curl_easy_getinfo(mCurl,CURLINFO_RESPONSE_CODE,&http_code);
601 curl_easy_cleanup(mCurl);
606 curl_global_cleanup();
630 std::string protocol =
"http://";
632 protocol =
"https://";
635 const std::string form2 = form;
636 const std::string fname2 = fname;
637 const std::string upload2 = uploadname;
643 curl_global_init(CURL_GLOBAL_ALL);
646 if(!mCurl) mCurl = curl_easy_init();
652 struct MemoryStruct chunk;
653 chunk.memory = (
char*)malloc(1);
658 curl_mime *form_mime =
NULL;
659 curl_mimepart *field =
NULL;
660 struct curl_slist *headerlist=
NULL;
668 std::vector<Variant>::iterator p1 = dataList->
Begin();
669 std::vector<Variant>::iterator p1end = dataList->
End();
671 form_mime = curl_mime_init(mCurl);
675 std::string
head = *p1;
677 std::string value = *p1;
679 field = curl_mime_addpart(form_mime);
680 curl_mime_name(field,
head.c_str());
681 curl_mime_data(field, value.c_str(), CURL_ZERO_TERMINATED);
685 field = curl_mime_addpart(form_mime);
686 curl_mime_name(field, form2.c_str());
687 curl_mime_filedata(field, upload2.c_str());
690 field = curl_mime_addpart(form_mime);
691 curl_mime_name(field,
"filename");
692 curl_mime_data(field, upload2.c_str(), CURL_ZERO_TERMINATED);
695 field = curl_mime_addpart(form_mime);
696 curl_mime_name(field,
"submit");
697 curl_mime_data(field,
"send", CURL_ZERO_TERMINATED);
700 curl_easy_setopt(mCurl, CURLOPT_URL, fname2.c_str());
702 curl_easy_setopt(mCurl, CURLOPT_VERBOSE, 1L);
704 curl_easy_setopt(mCurl, CURLOPT_HTTPHEADER, headerlist);
705 curl_easy_setopt(mCurl, CURLOPT_MIMEPOST, form_mime);
709 curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
712 curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, (
void *)(&chunk));
716 curl_easy_setopt(mCurl, CURLOPT_USERAGENT,
"libcurl-agent/1.0");
720 res = curl_easy_perform(mCurl);
726 fprintf(stderr,
"PEBL HTTP Multi File POST failed: %s\n",
727 curl_easy_strerror(res));
738 printf(
"%lu bytes retrieved\n", (
long)chunk.size);
739 mText = std::string((
char*)(chunk.memory));
746 curl_mime_free(form_mime);
747 curl_easy_cleanup(mCurl);
749 curl_global_cleanup();
771 std::string protocol =
"http://";
773 protocol =
"https://";
778 const std::string fname2 = fname;
779 const std::string upload2 = uploadname;
785 curl_global_init(CURL_GLOBAL_ALL);
788 if(!mCurl) mCurl = curl_easy_init();
794 struct MemoryStruct chunk;
795 chunk.memory = (
char*)malloc(1);
800 curl_mime *form_mime =
NULL;
801 curl_mimepart *field =
NULL;
810 std::vector<Variant>::iterator p1 = dataList->
Begin();
811 std::vector<Variant>::iterator p1end = dataList->
End();
813 form_mime = curl_mime_init(mCurl);
817 std::string
head = *p1;
819 std::string value = *p1;
821 field = curl_mime_addpart(form_mime);
822 curl_mime_name(field,
head.c_str());
823 curl_mime_data(field, value.c_str(), CURL_ZERO_TERMINATED);
827 field = curl_mime_addpart(form_mime);
828 curl_mime_name(field,
"sendfile");
829 curl_mime_filedata(field, upload2.c_str());
832 field = curl_mime_addpart(form_mime);
833 curl_mime_name(field,
"filename");
834 curl_mime_data(field, upload2.c_str(), CURL_ZERO_TERMINATED);
837 field = curl_mime_addpart(form_mime);
838 curl_mime_name(field,
"submit");
839 curl_mime_data(field,
"send", CURL_ZERO_TERMINATED);
842 curl_easy_setopt(mCurl, CURLOPT_URL, fname2.c_str());
844 curl_easy_setopt(mCurl, CURLOPT_VERBOSE, 1L);
846 curl_easy_setopt(mCurl, CURLOPT_MIMEPOST, form_mime);
850 curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
853 curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, (
void *)(&chunk));
857 curl_easy_setopt(mCurl, CURLOPT_USERAGENT,
"libcurl-agent/1.0");
861 res = curl_easy_perform(mCurl);
867 fprintf(stderr,
"PEBL HTTP Multi File POST failed: %s\n",
868 curl_easy_strerror(res));
879 printf(
"%lu bytes retrieved\n", (
long)chunk.size);
880 mText = std::string((
char*)(chunk.memory));
887 curl_mime_free(form_mime);
888 curl_easy_cleanup(mCurl);
890 curl_global_cleanup();
895#elif HTTP_LIB == PEBL_FETCH
897#include <emscripten.h>
898#include <emscripten/fetch.h>
911static volatile int upload_complete = 0;
913void uploadSucceeded(emscripten_fetch_t *fetch) {
914 printf(
"Finished uploading %llu bytes from URL %s.\n", fetch->numBytes, fetch->url);
915 printf(
"Upload succeeded with status: %d\n", fetch->status);
920void uploadFailed(emscripten_fetch_t *fetch) {
921 printf(
"Uploading %s failed, HTTP failure status code: %d.\n", fetch->url, fetch->status);
922 upload_complete = -1;
928PEBLHTTP::PEBLHTTP(
Variant host,
int port)
944int PEBLHTTP::GetHTTPFile(
Variant filename,
965 std::string protocol =
"http://";
967 protocol =
"https://";
974 emscripten_fetch_attr_t attr;
975 emscripten_fetch_attr_init(&attr);
976 strcpy(attr.requestMethod,
"GET");
978 attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY;
979 attr.onsuccess = uploadSucceeded;
980 attr.onerror = uploadFailed;
982 emscripten_fetch_t * fetch;
985 fetch = emscripten_fetch(&attr, url_str.c_str());
986 mStatus = fetch->status;
994 fwrite(fetch->data,1,fetch->numBytes,mFile);
996 emscripten_fetch_close(fetch);
998 return fetch->status;
1005std::string PEBLHTTP::GetHTTPText(
Variant filename)
1031 std::string protocol =
"http://";
1033 protocol =
"https://";
1036 std::string url_str = fname.
GetString();
1038 printf(
"GetHTTPText: Fetching URL via JavaScript fetch(): [%s]\n", url_str.c_str());
1042 Module._js_get_complete = 0;
1043 Module._js_get_status = 0;
1044 Module._js_get_response =
'';
1049 var url = UTF8ToString($0);
1056 Module._js_get_status = response.status;
1057 return response.text();
1060 Module._js_get_response = text;
1061 Module._js_get_complete = 1;
1064 console.error(
'GET error:', error);
1065 Module._js_get_status = 0;
1066 Module._js_get_complete = -1;
1070 }, url_str.c_str());
1074 int js_complete = 0;
1075 while (js_complete == 0) {
1076 js_complete = EM_ASM_INT({
1077 return Module._js_get_complete || 0;
1080 if (js_complete == 0) {
1081 emscripten_sleep(50);
1083 if (wait_count > 600) {
1084 printf(
"GetHTTPText: Request timeout after 30 seconds\n");
1092 mStatus = EM_ASM_INT({
1093 return Module._js_get_status || 0;
1096 if (js_complete < 0) {
1097 printf(
"GetHTTPText: Request failed\n");
1102 char* response_text = (
char*)EM_ASM_INT({
1103 var text = Module._js_get_response ||
'';
1104 var len = lengthBytesUTF8(text) + 1;
1105 var buffer = _malloc(len);
1106 stringToUTF8(text, buffer, len);
1110 if (response_text) {
1111 mText = std::string(response_text);
1112 printf(
"%lu bytes retrieved\n", (
unsigned long)mText.length());
1113 free(response_text);
1146 emscripten_fetch_attr_t attr;
1147 emscripten_fetch_attr_init(&attr);
1148 strcpy(attr.requestMethod,
"POST");
1150 attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY ;
1167 std::vector<Variant>::iterator p1 = dataList->
Begin();
1168 std::vector<Variant>::iterator p1end = dataList->
End();
1174 std::string
head = *p1;
1176 std::string value = *p1;
1183 std::string protocol =
"http://";
1185 protocol =
"https://";
1190 std::string url_str = fname.
GetString();
1193 const char *
const * rH;
1229 emscripten_fetch_t * fetch;
1230 fetch = emscripten_fetch(&attr, url_str.c_str());
1231 mStatus = fetch->status;
1235 char *p = (
char*)malloc((fetch->numBytes+ 1 ) );
1237 for(
int i = 0; i < fetch->numBytes; ++i)
1238 p[i] = fetch->data[i];
1239 p[fetch->numBytes+1] =
'\0';
1242 mText = std::string(p);
1247 emscripten_fetch_close(fetch);
1289 std::vector<Variant>::iterator p1 = dataList->
Begin();
1290 std::vector<Variant>::iterator p1end = dataList->
End();
1293 std::vector<std::pair<std::string, std::string>> form_fields;
1296 std::string
head = *p1;
1298 std::string value = *p1;
1300 form_fields.push_back(std::make_pair(
head, value));
1304 std::string protocol =
"http://";
1306 protocol =
"https://";
1311 std::string uploadname_str = uploadname.
GetString();
1315 int fs_size = EM_ASM_INT({
1317 var path = UTF8ToString($0);
1318 var stat = FS.stat(path);
1321 console.error(
'FS.stat error:', e);
1324 }, uploadname_str.c_str());
1331 FILE* file = fopen(uploadname_str.c_str(),
"rb");
1338 fseek(file, 0, SEEK_END);
1339 long filesize = ftell(file);
1340 fseek(file, 0, SEEK_SET);
1342 if (filesize == 0) {
1349 char* filedata = (
char*)malloc(filesize);
1356 size_t bytes_read = fread(filedata, 1, filesize, file);
1359 if (bytes_read != filesize) {
1366 std::string boundary =
"----PEBLFormBoundary7MA4YWxkTrZu0gW";
1367 std::string form_str = form.
GetString();
1370 std::string filename = uploadname_str;
1371 size_t last_slash = filename.find_last_of(
"/\\");
1372 if (last_slash != std::string::npos) {
1373 filename = filename.substr(last_slash + 1);
1380 for (
size_t i = 0; i < form_fields.size(); i++) {
1381 body +=
"--" + boundary +
"\r\n";
1382 body +=
"Content-Disposition: form-data; name=\"" + form_fields[i].first +
"\"\r\n\r\n";
1383 body += form_fields[i].second +
"\r\n";
1387 body +=
"--" + boundary +
"\r\n";
1388 body +=
"Content-Disposition: form-data; name=\"" + form_str +
"\"; filename=\"" + filename +
"\"\r\n";
1389 body +=
"Content-Type: application/octet-stream\r\n\r\n";
1390 body.append(filedata, filesize);
1394 body +=
"--" + boundary +
"\r\n";
1395 body +=
"Content-Disposition: form-data; name=\"filename\"\r\n\r\n";
1396 body += filename +
"\r\n";
1399 body +=
"--" + boundary +
"\r\n";
1400 body +=
"Content-Disposition: form-data; name=\"submit\"\r\n\r\n";
1404 body +=
"--" + boundary +
"--\r\n";
1409 std::string url_str = fname.
GetString();
1412 static std::string content_type_header;
1413 content_type_header =
"multipart/form-data; boundary=" + boundary;
1416 size_t body_len = body.length();
1417 char* persistent_body = (
char*)malloc(body_len);
1418 if (!persistent_body) {
1424 memcpy(persistent_body, body.data(), body_len);
1428 Module._js_fetch_complete = 0;
1429 Module._js_fetch_status = 0;
1430 Module._js_fetch_response =
'';
1435 var url = UTF8ToString($0);
1438 var contentType = UTF8ToString($3);
1441 var bodyData =
new Uint8Array(bodyLen);
1442 for (var i = 0; i < bodyLen; i++) {
1443 bodyData[i] = HEAPU8[bodyPtr + i];
1450 'Content-Type': contentType
1455 Module._js_fetch_status = response.status;
1456 return response.text();
1459 Module._js_fetch_response = text;
1460 Module._js_fetch_complete = 1;
1463 console.error(
'Upload error:', error);
1464 Module._js_fetch_status = 0;
1465 Module._js_fetch_complete = -1;
1469 }, url_str.c_str(), (int)persistent_body, (
int)body_len, content_type_header.c_str());
1473 int js_complete = 0;
1474 while (js_complete == 0) {
1475 js_complete = EM_ASM_INT({
1476 return Module._js_fetch_complete || 0;
1479 if (js_complete == 0) {
1480 emscripten_sleep(50);
1482 if (wait_count > 600) {
1483 free(persistent_body);
1490 free(persistent_body);
1493 mStatus = EM_ASM_INT({
1494 return Module._js_fetch_status || 0;
1497 if (js_complete < 0) {
1498 return Variant(
"Upload failed");
1502 char* response_text = (
char*)EM_ASM_INT({
1503 var text = Module._js_fetch_response ||
'';
1504 var len = lengthBytesUTF8(text) + 1;
1505 var buffer = _malloc(len);
1506 stringToUTF8(text, buffer, len);
1510 if (response_text) {
1511 mText = std::string(response_text);
1512 free(response_text);
counted_ptr< PEBLObjectBase > GetPEBLObject() const
std::vector< Variant >::const_iterator End() const
std::vector< Variant >::const_iterator Begin() const
std::string GetString() const
PComplexData * GetComplexData() const
const char * getreason() const
const char * what() const
void SignalWarning(const std::string &message)
void AssertType(Variant v, int type, const std::string &outsidemessage)
void SignalFatalError(const std::string &message)
void OnData(const happyhttp::Response *r, void *userdata, const unsigned char *data, int n)
void OnBegin(const happyhttp::Response *r, void *userdata)
void OnComplete(const happyhttp::Response *r, void *userdata)