import { Builder } from '../utils/builder' import { Config, Http } from '../utils/generate' import { Client } from '../utils/registry' import { GetContentType, IsStringBody } from '../utils/utils' export default { default: true, language: 'c', client: 'libcurl', generate(config: Config, http: Http): string { const builder = new Builder({ indent: config.indent || ' ', join: config.join || '\n' }) builder.line('#include ') builder.line('#include ') builder.line() builder.line('int main(void) {') builder.indent() builder.line('CURL *curl;') builder.line('CURLcode res;') builder.line() builder.line('curl_global_init(CURL_GLOBAL_DEFAULT);') builder.line('curl = curl_easy_init();') builder.line('if(curl) {') builder.indent() // Build URL with parameters using multi-line string concatenation if (http.params && Object.keys(http.params).length > 0) { const params = new URLSearchParams() for (const [key, value] of Object.entries(http.params)) { if (Array.isArray(value)) { for (const val of value) { params.append(key, val) } } else { params.append(key, value) } } const paramString = params.toString() if (paramString) { const separator = http.url.includes('?') ? '&' : '?' const paramParts = paramString.split('&') builder.line('curl_easy_setopt(curl, CURLOPT_URL,') builder.indent() builder.line(`"${http.url}"`) builder.line(`"${separator}${paramParts[0]}"`) for (let i = 1; i < paramParts.length; i++) { builder.line(`"&${paramParts[i]}"`) } builder.outdent() builder.line(');') } else { builder.line(`curl_easy_setopt(curl, CURLOPT_URL, "${http.url}");`) } } else { builder.line(`curl_easy_setopt(curl, CURLOPT_URL, "${http.url}");`) } if (http.method.toUpperCase() === 'POST') { builder.line('curl_easy_setopt(curl, CURLOPT_POST, 1L);') } else if (http.method.toUpperCase() !== 'GET') { builder.line(`curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "${http.method.toUpperCase()}");`) } if (http.headers && Object.keys(http.headers).length > 0) { builder.line() builder.line('struct curl_slist *headers = NULL;') for (const [key, value] of Object.entries(http.headers)) { if (Array.isArray(value)) { value.forEach((val) => builder.line(`headers = curl_slist_append(headers, "${key}: ${val}");`)) } else { builder.line(`headers = curl_slist_append(headers, "${key}: ${value}");`) } } builder.line('curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);') } if (http.cookies && Object.keys(http.cookies).length > 0) { builder.line() const cookies = Object.entries(http.cookies) .map(([key, value]) => `${key}=${value}`) .join('; ') builder.line(`curl_easy_setopt(curl, CURLOPT_COOKIE, "${cookies}");`) } if (http.body) { builder.line() const contentType = GetContentType(http.headers) if (IsStringBody(http.body)) { builder.line(`curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "${http.body.replace(/"/g, '\\"')}");`) } else { // For objects (JSON or form data), stringify as JSON builder.line('curl_easy_setopt(curl, CURLOPT_POSTFIELDS, R"(') builder.json(http.body) builder.append(')");') } } builder.line() builder.line('res = curl_easy_perform(curl);') builder.line('if(res != CURLE_OK)') builder.indent() builder.line('fprintf(stderr, "failed: %s", curl_easy_strerror(res));') builder.outdent() if (http.headers && Object.keys(http.headers).length > 0) { builder.line('curl_slist_free_all(headers);') } builder.line('curl_easy_cleanup(curl);') builder.outdent() builder.line('}') builder.line() builder.line('curl_global_cleanup();') builder.line('return 0;') builder.outdent() builder.line('}') return builder.output() } } as Client