Skip to content

Commit

Permalink
Added basic http write referencing #23
Browse files Browse the repository at this point in the history
  • Loading branch information
FrankC01 committed Jun 8, 2019
1 parent fa68c14 commit a53135c
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 11 deletions.
4 changes: 3 additions & 1 deletion foidlrtl/fsrc/langcore.foidl
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
1 change: 1 addition & 0 deletions foidlrtl/headers/foidlrt.defs
Original file line number Diff line number Diff line change
Expand Up @@ -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]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Expand Down
50 changes: 44 additions & 6 deletions foidlrtl/src/foidl_http_channel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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

Expand All @@ -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) {
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down
11 changes: 7 additions & 4 deletions tests/selfhosted/fsrc/http_chan.foidl
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit a53135c

Please sign in to comment.