aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/README.md1
-rw-r--r--examples/http.tm100
2 files changed, 101 insertions, 0 deletions
diff --git a/examples/README.md b/examples/README.md
index 3c8e6e15..aee5b95c 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -3,6 +3,7 @@
- [coroutine.tm](coroutine.tm): A library for coroutines similar to Lua's
(using [libaco](https://libaco.org)).
- [game/](game/): An example game using raylib.
+- [http.tm](http.tm): An HTTP library to make basic synchronous HTTP requests.
- [ini.tm](ini.tm): An INI configuration file reader tool.
- [log.tm](log.tm): A logging utility.
- [vectors.tm](vectors.tm): A math vector library.
diff --git a/examples/http.tm b/examples/http.tm
new file mode 100644
index 00000000..9590215e
--- /dev/null
+++ b/examples/http.tm
@@ -0,0 +1,100 @@
+# A simple HTTP library built using CURL
+
+use libcurl.so
+use <curl/curl.h>
+
+struct HTTPResponse(code:Int, body:Text)
+
+enum _Method(GET, POST, PUT, PATCH, DELETE)
+
+_curl := !@Memory
+
+func _send(method:_Method, url:Text, data:Text?, headers=[:Text])->HTTPResponse:
+ chunks := @[:Text]
+ save_chunk := func(chunk:CString, size:Int64, n:Int64):
+ chunks:insert(inline C (
+ Text$format("%.*s", $size*$n, $chunk)
+ ) : Text)
+ return n*size
+
+ inline C {
+ CURL *curl = curl_easy_init();
+ struct curl_slist *chunk = NULL;
+ curl_easy_setopt(curl, CURLOPT_URL, Text$as_c_string($url));
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, $save_chunk.fn);
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, $save_chunk.userdata);
+ }
+
+ when method is POST:
+ inline C {
+ curl_easy_setopt(curl, CURLOPT_POST, 1L);
+ }
+ if posting := data:
+ inline C {
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, Text$as_c_string($posting));
+ }
+ is PUT:
+ inline C {
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
+ }
+ if putting := data:
+ inline C {
+ curl_easy_setopt(curl, CURLOPT_POSTFIELDS, Text$as_c_string($putting));
+ }
+ is DELETE:
+ inline C {
+ curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE");
+ }
+ else:
+ pass
+
+ for header in headers:
+ inline C {
+ chunk = curl_slist_append(chunk, Text$as_c_string($header));
+ }
+
+ inline C {
+ if (chunk)
+ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
+ }
+
+ code := 0_i64
+ inline C {
+ CURLcode res = curl_easy_perform(curl);
+ if (res != CURLE_OK)
+ fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
+
+ curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &$code);
+ if (chunk)
+ curl_slist_free_all(chunk);
+ curl_easy_cleanup(curl);
+ }
+ return HTTPResponse(code, "":join(chunks))
+
+func get(url:Text, headers=[:Text])->HTTPResponse:
+ return _send(GET, url, !Text, headers)
+
+func post(url:Text, data="", headers=["Content-Type: application/json", "Accept: application/json"])->HTTPResponse:
+ return _send(POST, url, data, headers)
+
+func put(url:Text, data="", headers=["Content-Type: application/json", "Accept: application/json"])->HTTPResponse:
+ return _send(PUT, url, data, headers)
+
+func delete(url:Text, data=!Text, headers=["Content-Type: application/json", "Accept: application/json"])->HTTPResponse:
+ return _send(DELETE, url, data, headers)
+
+func main():
+ !! GET:
+ say(get("https://httpbin.org/get").body)
+ !! Waiting 1sec...
+ sleep(1)
+ !! POST:
+ say(post("https://httpbin.org/post", `{"key": "value"}`).body)
+ !! Waiting 1sec...
+ sleep(1)
+ !! PUT:
+ say(put("https://httpbin.org/put", `{"key": "value"}`).body)
+ !! Waiting 1sec...
+ sleep(1)
+ !! DELETE:
+ say(delete("https://httpbin.org/delete").body)