BEGIN; SET LOCAL client_min_messages = WARNING; CREATE EXTENSION IF NOT EXISTS pg_curl; END; DO $plpgsql$ BEGIN BEGIN PERFORM curl_easy_reset(); PERFORM curl_easy_setopt_timeout(1); PERFORM curl_easy_setopt_url('http://localhost/status/202'); PERFORM curl_easy_perform(); PERFORM curl_easy_getinfo_http_connectcode(); SET pg_curl.httpbin = 'http://localhost'; EXCEPTION WHEN OTHERS THEN SET pg_curl.httpbin = 'https://httpbin.org'; END; END;$plpgsql$; BEGIN; select curl_easy_reset(); curl_easy_reset ----------------- t (1 row) select curl_easy_setopt_url(current_setting('pg_curl.httpbin') || '/get?'); curl_easy_setopt_url ---------------------- t (1 row) select curl_url_append('a', 'b'); curl_url_append ----------------- t (1 row) select curl_url_append('c', ''); curl_url_append ----------------- t (1 row) select curl_url_append('d'); curl_url_append ----------------- t (1 row) select curl_easy_perform(); curl_easy_perform ------------------- t (1 row) with s as ( select regexp_matches(curl_easy_getinfo_header_in(), E'([^ \t\r\n\f]+): ?([^\t\r\n\f]+)', 'g') as s ) select lower(s[1]) as key, s[2] as value from s where lower(s[1]) not in ('date', 'server', 'content-length', 'connection'); key | value ----------------------------------+------------------ content-type | application/json access-control-allow-origin | * access-control-allow-credentials | true (3 rows) -- args/headers are selected explicitly (rather than deleting the noisy keys -- with jsonb's -/#- operators, which only exist since PostgreSQL 9.5) so this -- keeps working back to PostgreSQL 9.4, which has -> and json_build_object with j as ( select convert_from(curl_easy_getinfo_data_in(), 'utf-8')::jsonb as data ) select json_build_object( 'args', j.data->'args', 'headers', json_build_object('Accept', j.data->'headers'->>'Accept') ) from j; json_build_object ------------------------------------------------------------------------- {"args" : {"a": "b", "c": "", "d": ""}, "headers" : {"Accept" : "*/*"}} (1 row) select curl_easy_getinfo_errcode(), curl_easy_getinfo_errdesc(), curl_easy_getinfo_errbuf(); curl_easy_getinfo_errcode | curl_easy_getinfo_errdesc | curl_easy_getinfo_errbuf ---------------------------+---------------------------+-------------------------- 0 | No error | (1 row) END; BEGIN; select curl_easy_reset(); curl_easy_reset ----------------- t (1 row) select curl_easy_setopt_postfields(convert_to('{"e":"f","g":"","h":null}', 'utf-8')); curl_easy_setopt_postfields ----------------------------- t (1 row) select curl_easy_setopt_url(current_setting('pg_curl.httpbin') || '/post?'); curl_easy_setopt_url ---------------------- t (1 row) select curl_url_append('a', 'b'); curl_url_append ----------------- t (1 row) select curl_url_append('c', ''); curl_url_append ----------------- t (1 row) select curl_url_append('d'); curl_url_append ----------------- t (1 row) select curl_header_append('Content-Type', 'application/json; charset=utf-8'); curl_header_append -------------------- t (1 row) select curl_easy_perform(); curl_easy_perform ------------------- t (1 row) with s as ( select regexp_matches(curl_easy_getinfo_header_in(), E'([^ \t\r\n\f]+): ?([^\t\r\n\f]+)', 'g') as s ) select lower(s[1]) as key, s[2] as value from s where lower(s[1]) not in ('date', 'server', 'content-length', 'connection'); key | value ----------------------------------+------------------ content-type | application/json access-control-allow-origin | * access-control-allow-credentials | true (3 rows) with j as ( select convert_from(curl_easy_getinfo_data_in(), 'utf-8')::jsonb as data ) select json_build_object( 'args', j.data->'args', 'data', j.data->>'data', 'form', j.data->'form', 'json', j.data->'json', 'files', j.data->'files', 'headers', json_build_object( 'Accept', j.data->'headers'->>'Accept', 'Content-Type', j.data->'headers'->>'Content-Type', 'Content-Length', j.data->'headers'->>'Content-Length' ) ) from j; json_build_object -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- {"args" : {"a": "b", "c": "", "d": ""}, "data" : "{\"e\":\"f\",\"g\":\"\",\"h\":null}", "form" : {}, "json" : {"e": "f", "g": "", "h": null}, "files" : {}, "headers" : {"Accept" : "*/*", "Content-Type" : "application/json; charset=utf-8", "Content-Length" : "25"}} (1 row) select curl_easy_getinfo_errcode(), curl_easy_getinfo_errdesc(), curl_easy_getinfo_errbuf(); curl_easy_getinfo_errcode | curl_easy_getinfo_errdesc | curl_easy_getinfo_errbuf ---------------------------+---------------------------+-------------------------- 0 | No error | (1 row) END; BEGIN; select curl_easy_reset(); curl_easy_reset ----------------- t (1 row) select curl_postfield_append('e', 'f'); curl_postfield_append ----------------------- t (1 row) select curl_postfield_append('g', ''); curl_postfield_append ----------------------- t (1 row) select curl_postfield_append('h'); curl_postfield_append ----------------------- t (1 row) select curl_easy_setopt_url(current_setting('pg_curl.httpbin') || '/post?'); curl_easy_setopt_url ---------------------- t (1 row) select curl_url_append('a', 'b'); curl_url_append ----------------- t (1 row) select curl_url_append('c', ''); curl_url_append ----------------- t (1 row) select curl_url_append('d'); curl_url_append ----------------- t (1 row) select curl_easy_perform(); curl_easy_perform ------------------- t (1 row) with s as ( select regexp_matches(curl_easy_getinfo_header_in(), E'([^ \t\r\n\f]+): ?([^\t\r\n\f]+)', 'g') as s ) select lower(s[1]) as key, s[2] as value from s where lower(s[1]) not in ('date', 'server', 'content-length', 'connection'); key | value ----------------------------------+------------------ content-type | application/json access-control-allow-origin | * access-control-allow-credentials | true (3 rows) with j as ( select convert_from(curl_easy_getinfo_data_in(), 'utf-8')::jsonb as data ) select json_build_object( 'args', j.data->'args', 'data', j.data->>'data', 'form', j.data->'form', 'json', j.data->'json', 'files', j.data->'files', 'headers', json_build_object( 'Accept', j.data->'headers'->>'Accept', 'Content-Type', j.data->'headers'->>'Content-Type', 'Content-Length', j.data->'headers'->>'Content-Length' ) ) from j; json_build_object ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- {"args" : {"a": "b", "c": "", "d": ""}, "data" : "", "form" : {"e": "f", "g": "", "h": ""}, "json" : null, "files" : {}, "headers" : {"Accept" : "*/*", "Content-Type" : "application/x-www-form-urlencoded", "Content-Length" : "8"}} (1 row) select curl_easy_getinfo_errcode(), curl_easy_getinfo_errdesc(), curl_easy_getinfo_errbuf(); curl_easy_getinfo_errcode | curl_easy_getinfo_errdesc | curl_easy_getinfo_errbuf ---------------------------+---------------------------+-------------------------- 0 | No error | (1 row) END; BEGIN; select curl_easy_reset(); curl_easy_reset ----------------- t (1 row) select curl_easy_setopt_url(current_setting('pg_curl.httpbin') || '/post?'); curl_easy_setopt_url ---------------------- t (1 row) select curl_url_append('a', 'b'); curl_url_append ----------------- t (1 row) select curl_url_append('c', ''); curl_url_append ----------------- t (1 row) select curl_url_append('d'); curl_url_append ----------------- t (1 row) select curl_mime_data('f', name:='e'); curl_mime_data ---------------- t (1 row) select curl_mime_data('', name:='g'); curl_mime_data ---------------- t (1 row) select curl_mime_data(null, name:='h'); curl_mime_data ---------------- t (1 row) select curl_mime_data('content', name:='filename.txt', file:='filename.txt'); curl_mime_data ---------------- t (1 row) select curl_easy_perform(); curl_easy_perform ------------------- t (1 row) with s as ( select regexp_matches(curl_easy_getinfo_header_in(), E'([^ \t\r\n\f]+): ?([^\t\r\n\f]+)', 'g') as s ) select lower(s[1]) as key, s[2] as value from s where lower(s[1]) not in ('date', 'server', 'content-length', 'connection'); key | value ----------------------------------+------------------ content-type | application/json access-control-allow-origin | * access-control-allow-credentials | true (3 rows) with j as ( select convert_from(curl_easy_getinfo_data_in(), 'utf-8')::jsonb as data ) select json_build_object( 'args', j.data->'args', 'data', j.data->>'data', 'form', j.data->'form', 'json', j.data->'json', 'files', j.data->'files', 'headers', json_build_object('Accept', j.data->'headers'->>'Accept') ) from j; json_build_object ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- {"args" : {"a": "b", "c": "", "d": ""}, "data" : "", "form" : {"e": "f", "g": "", "h": ""}, "json" : null, "files" : {"filename.txt": "content"}, "headers" : {"Accept" : "*/*"}} (1 row) select curl_easy_getinfo_errcode(), curl_easy_getinfo_errdesc(), curl_easy_getinfo_errbuf(); curl_easy_getinfo_errcode | curl_easy_getinfo_errdesc | curl_easy_getinfo_errbuf ---------------------------+---------------------------+-------------------------- 0 | No error | (1 row) END;