From a53135c2a3cf85f65a34299f87fa737a539f9f2a Mon Sep 17 00:00:00 2001 From: "Frank V. Castellucci" Date: Sat, 8 Jun 2019 05:09:37 -0400 Subject: [PATCH] Added basic http write referencing #23 --- foidlrtl/fsrc/langcore.foidl | 4 ++- foidlrtl/headers/foidlrt.defs | 1 + foidlrtl/src/foidl_http_channel.c | 50 +++++++++++++++++++++++---- tests/selfhosted/fsrc/http_chan.foidl | 11 +++--- 4 files changed, 55 insertions(+), 11 deletions(-) diff --git a/foidlrtl/fsrc/langcore.foidl b/foidlrtl/fsrc/langcore.foidl index c7e04ba..971fee1 100644 --- a/foidlrtl/fsrc/langcore.foidl +++ b/foidlrtl/fsrc/langcore.foidl @@ -124,7 +124,9 @@ func reads! [channel] func writes! [channel data] ?: io?: channel - foidl_channel_file_write!: channel data + match channel_type?: channel + | chan_file foidl_channel_file_write!: channel data + | chan_http foidl_channel_http_write!: channel data nil func closes! [channel] diff --git a/foidlrtl/headers/foidlrt.defs b/foidlrtl/headers/foidlrt.defs index 5b5ba86..087056d 100644 --- a/foidlrtl/headers/foidlrt.defs +++ b/foidlrtl/headers/foidlrt.defs @@ -360,6 +360,7 @@ func foidl_fexists? [fname] func foidl_open_http! [name args] func foidl_channel_http_read! [channel] +func foidl_channel_http_write! [channel data] func foidl_channel_http_close! [channel] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/foidlrtl/src/foidl_http_channel.c b/foidlrtl/src/foidl_http_channel.c index e68fff0..ee9446b 100644 --- a/foidlrtl/src/foidl_http_channel.c +++ b/foidlrtl/src/foidl_http_channel.c @@ -52,7 +52,7 @@ static size_t http_header_handler(char* b, size_t size, size_t nitems, void *use size_t numbytes = size * nitems; //printf("Hdr Size: %zu\n", size); //printf("Hdr Size: %zu\n", nitems); - printf("Header: %.*s\n", (int) numbytes, b); + //printf("Header: %.*s\n", (int) numbytes, b); return numbytes; } @@ -71,6 +71,43 @@ static size_t http_read_handler( return realsize; } + +PFRTAny foidl_channel_http_write_bang(PFRTAny channel, PFRTAny data) { + if(channel->ftype == http_type) { + PFRTIOHttpChannel http = (PFRTIOHttpChannel)channel; + CURL *curl = http->value; + CURLcode cres; + struct Chunk mem; + mem.memory = foidl_xall(1); + mem.size = 0; + curl_easy_setopt(curl, CURLOPT_URL, http->name->value); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&mem); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data->value); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)data->count); + //curl_easy_setopt(curl, CURLOPT_NOBODY, 1); // For debugging header only + cres = curl_easy_perform(curl); + + if(!cres) { + //printf("Download size: %u\n", (int) mem.size); + } + else { + return nil; + } + // TODO: Read handler (e.g. string, json-map, json-list, html-map, html-list) + + PFRTAny result = (PFRTAny) + allocResponse( + http_response_type, + (PFRTAny) allocStringWithCptr(mem.memory,strlen(mem.memory))); + return result; + } + else { + printf("http read requires an opened http channel\n"); + unknown_handler(); + return nil; + } +} + // foidl_channel_http_read_bang (<- foidl_channel_http_read! <- reads!) // Entry point for reading from http channel @@ -83,10 +120,8 @@ PFRTAny foidl_channel_http_read_bang(PFRTAny channel) { mem.memory = foidl_xall(1); mem.size = 0; curl_easy_setopt(curl, CURLOPT_URL, http->name->value); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_read_handler); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&mem); //curl_easy_setopt(curl, CURLOPT_NOBODY, 1); // For debugging header only - curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, http_header_handler); cres = curl_easy_perform(curl); if(!cres) { @@ -96,14 +131,14 @@ PFRTAny foidl_channel_http_read_bang(PFRTAny channel) { return nil; } // TODO: Read handler (e.g. string, json-map, json-list, html-map, html-list) - - return (PFRTAny) + PFRTAny result = (PFRTAny) allocResponse( http_response_type, (PFRTAny) allocStringWithCptr(mem.memory,strlen(mem.memory))); + return result; } else { - printf("http read requires an http channel\n"); + printf("http read requires an opened http channel\n"); unknown_handler(); return nil; } @@ -121,6 +156,9 @@ PFRTAny foidl_open_http_bang(PFRTAny name, PFRTAny args) { CURL *curl = curl_easy_init(); if(curl) { curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, http_read_handler); + curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, http_header_handler); + curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0"); res = (PFRTAny) allocHttpChannel(name,args); res->value = (void *)curl; } diff --git a/tests/selfhosted/fsrc/http_chan.foidl b/tests/selfhosted/fsrc/http_chan.foidl index cc49257..7f423d3 100644 --- a/tests/selfhosted/fsrc/http_chan.foidl +++ b/tests/selfhosted/fsrc/http_chan.foidl @@ -20,13 +20,16 @@ module http_chan -func gethttp [url] +func rwhttp [url] let chan [] opens!: {chan_target url chan_type chan_http chan_mode open_r chan_render render_string} - let s [] reads!: chan + let r [] reads!: chan + let w [] writes!: chan "Field=1&Field=2&Field=3" + printnl!: "Results of read " printnl!: response_value: r + printnl!: "Results of write " printnl!: response_value: w closes!: chan - response_value: s + response_value: r func main [argv] - printnl!: gethttp: "http://example.com" + rwhttp: "http://example.com" zero