Fun 0.41.5
The programming language that makes you have fun!
Loading...
Searching...
No Matches
post.c
Go to the documentation of this file.
1/*
2 * This file is part of the Fun programming language.
3 * https://fun-lang.xyz/
4 *
5 * Copyright 2025 Johannes Findeisen <you@hanez.org>
6 * Licensed under the terms of the Apache-2.0 license.
7 * https://opensource.org/license/apache-2-0
8 */
9
10/**
11 * @file post.c
12 * @brief Fun VM opcode snippet: HTTP POST via libcurl (OP_CURL_POST).
13 *
14 * This snippet is included by vm.c and implements the OP_CURL_POST
15 * instruction. When FUN_WITH_CURL is enabled, it performs an HTTP POST
16 * to the given URL with the provided request body and pushes the response
17 * body as a string. If libcurl support is not built in, or an error occurs,
18 * an empty string is pushed instead.
19 *
20 * Stack behavior:
21 * - Pops: body:string, url:string (values are converted via value_to_string_alloc)
22 * - Pushes: body:string (server response; "" on error or when CURL is disabled)
23 *
24 * Pops the POST body and URL, performs an HTTP POST, and pushes the
25 * response as a string. Without FUN_WITH_CURL, consumes two values and
26 * pushes an empty string.
27 *
28 * Error handling:
29 * - If URL conversion fails, the opcode pushes an empty string and discards
30 * any converted body.
31 * - Follows redirects (CURLOPT_FOLLOWLOCATION = 1L).
32 * - Sets CURLOPT_POST=1L and CURLOPT_POSTFIELDS to submit the body.
33 *
34 * Notes:
35 * - Uses FunCurlBuf and fun_curl_write_cb from the curl extension helpers.
36 * - All temporary allocations (URL, body, response buffer) are freed.
37 */
38
40#ifdef FUN_WITH_CURL
41 Value vbody = pop_value(vm);
44 char *body = value_to_string_alloc(&vbody);
46 free_value(vbody);
47 if (!url) {
48 if (body) free(body);
49 push_value(vm, make_string(""));
50 break;
51 }
52 if (!body) body = strdup("");
53 FunCurlBuf buf = {NULL, 0};
54 CURL *h = curl_easy_init();
55 if (!h) {
56 free(url);
57 free(body);
58 push_value(vm, make_string(""));
59 break;
60 }
61 curl_easy_setopt(h, CURLOPT_URL, url);
62 curl_easy_setopt(h, CURLOPT_FOLLOWLOCATION, 1L);
63 curl_easy_setopt(h, CURLOPT_POST, 1L);
64 curl_easy_setopt(h, CURLOPT_POSTFIELDS, body);
65 curl_easy_setopt(h, CURLOPT_WRITEFUNCTION, fun_curl_write_cb);
66 curl_easy_setopt(h, CURLOPT_WRITEDATA, &buf);
67 CURLcode rc = curl_easy_perform(h);
71 if (rc != CURLE_OK) {
72 if (buf.d) free(buf.d);
73 push_value(vm, make_string(""));
74 break;
75 }
76 Value s = make_string(buf.d ? buf.d : "");
77 if (buf.d) free(buf.d);
79#else
80 Value a = pop_value(vm);
82 Value b = pop_value(vm);
84 push_value(vm, make_string(""));
85#endif
86 break;
87}
Value a
Definition add.c:37
uint32_t b
Definition band.c:32
@ OP_CURL_POST
Definition bytecode.h:174
static size_t fun_curl_write_cb(void *ptr, size_t sz, size_t nm, void *ud)
libcurl write callback that appends data to a FunCurlBuf.
Definition curl.c:45
CURLcode rc
Definition download.c:71
CURL * h
Definition download.c:59
Value vurl
Definition download.c:41
char * url
Definition download.c:42
FunCurlBuf buf
Definition get.c:48
char * body
Definition post.c:44
curl_easy_cleanup(h)
free_value(vurl)
curl_easy_setopt(h, CURLOPT_URL, url)
push_value(vm, s)
free(url)
uint32_t s
Definition rol.c:31
Simple growable buffer for libcurl write callbacks.
Definition curl.c:28
Tagged union representing a Fun value.
Definition value.h:68
Value make_string(const char *s)
Construct a string Value by duplicating the given C string.
Definition value.c:95
char * value_to_string_alloc(const Value *v)
Allocate a printable C string for a Value.
Definition value.c:641
static Value pop_value(VM *vm)
Pop a Value from the VM operand stack.
Definition vm.c:580