Skip to content

Commit

Permalink
Merge branch 'lucajoos-master'
Browse files Browse the repository at this point in the history
  • Loading branch information
pramsey committed Apr 11, 2022
2 parents 4f17e83 + 488d5c1 commit 5ea01c9
Show file tree
Hide file tree
Showing 12 changed files with 95 additions and 47 deletions.
6 changes: 3 additions & 3 deletions META.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "http",
"abstract": "HTTP client for PostgreSQL",
"description": "HTTP allows you to get the content of a web page in a SQL function call.",
"version": "1.4.0",
"version": "1.5.0",
"maintainer": [
"Paul Ramsey <pramsey@cleverelephant.ca>"
],
Expand All @@ -21,9 +21,9 @@
},
"provides": {
"http": {
"file": "http--1.4.sql",
"file": "http--1.5.sql",
"docfile": "README.md",
"version": "1.4.0",
"version": "1.5.0",
"abstract": "HTTP client for PostgreSQL"
}
},
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ As seen in the examples, you can unspool the array of `http_header` tuples into
* `http_post(uri VARCHAR, data JSONB)` returns `http_response`
* `http_put(uri VARCHAR, content VARCHAR, content_type VARCHAR)` returns `http_response`
* `http_patch(uri VARCHAR, content VARCHAR, content_type VARCHAR)` returns `http_response`
* `http_delete(uri VARCHAR)` returns `http_response`
* `http_delete(uri VARCHAR, content VARCHAR, content_type VARCHAR))` returns `http_response`
* `http_head(uri VARCHAR)` returns `http_response`
* `http_set_curlopt(curlopt VARCHAR, value varchar)` returns `boolean`
* `http_reset_curlopt()` returns `boolean`
Expand Down
66 changes: 41 additions & 25 deletions expected/http.out
Original file line number Diff line number Diff line change
Expand Up @@ -62,60 +62,64 @@ from http(('GET', 'https://httpbin.org/anything', NULL, 'application/json', '{"s

-- DELETE
SELECT status,
content::json->'args' AS args,
content::json->'args'->>'foo' AS args,
content::json->'url' AS url,
content::json->'method' AS method
FROM http_delete('https://httpbin.org/anything?foo=bar');
status | args | url | method
--------+------------------+----------------------------------------+----------
200 | { +| "https://httpbin.org/anything?foo=bar" | "DELETE"
| "foo": "bar"+| |
| } | |
status | args | url | method
--------+------+----------------------------------------+----------
200 | bar | "https://httpbin.org/anything?foo=bar" | "DELETE"
(1 row)

-- DELETE with payload
SELECT status,
content::json->'args'->>'foo' AS args,
content::json->'url' AS url,
content::json->'method' AS method,
content::json->'data' AS data
FROM http_delete('https://httpbin.org/anything?foo=bar', 'payload', 'text/plain');
status | args | url | method | data
--------+------+----------------------------------------+----------+-----------
200 | bar | "https://httpbin.org/anything?foo=bar" | "DELETE" | "payload"
(1 row)

-- PUT
SELECT status,
content::json->'data' AS data,
content::json->'args' AS args,
content::json->'args'->>'foo' AS args,
content::json->'url' AS url,
content::json->'method' AS method
FROM http_put('https://httpbin.org/anything?foo=bar','payload','text/plain');
status | data | args | url | method
--------+-----------+------------------+----------------------------------------+--------
200 | "payload" | { +| "https://httpbin.org/anything?foo=bar" | "PUT"
| | "foo": "bar"+| |
| | } | |
status | data | args | url | method
--------+-----------+------+----------------------------------------+--------
200 | "payload" | bar | "https://httpbin.org/anything?foo=bar" | "PUT"
(1 row)

-- PATCH
SELECT status,
content::json->'data' AS data,
content::json->'args' AS args,
content::json->'args'->>'foo' AS args,
content::json->'url' AS url,
content::json->'method' AS method
FROM http_patch('https://httpbin.org/anything?foo=bar','{"this":"that"}','application/json');
status | data | args | url | method
--------+-----------------------+------------------+----------------------------------------+---------
200 | "{\"this\":\"that\"}" | { +| "https://httpbin.org/anything?foo=bar" | "PATCH"
| | "foo": "bar"+| |
| | } | |
status | data | args | url | method
--------+-----------------------+------+----------------------------------------+---------
200 | "{\"this\":\"that\"}" | bar | "https://httpbin.org/anything?foo=bar" | "PATCH"
(1 row)

-- POST
SELECT status,
content::json->'data' AS data,
content::json->'args' AS args,
content::json->'args'->>'foo' AS args,
content::json->'url' AS url,
content::json->'method' AS method
FROM http_post('https://httpbin.org/anything?foo=bar','payload','text/plain');
status | data | args | url | method
--------+-----------+------------------+----------------------------------------+--------
200 | "payload" | { +| "https://httpbin.org/anything?foo=bar" | "POST"
| | "foo": "bar"+| |
| | } | |
status | data | args | url | method
--------+-----------+------+----------------------------------------+--------
200 | "payload" | bar | "https://httpbin.org/anything?foo=bar" | "POST"
(1 row)

-- POST with data
-- POST with json data
SELECT status,
content::json->'form'->>'this' AS args,
content::json->'url' AS url,
Expand All @@ -126,6 +130,18 @@ FROM http_post('https://httpbin.org/anything', jsonb_build_object('this', 'that'
200 | that | "https://httpbin.org/anything" | "POST"
(1 row)

-- POST with data
SELECT status,
content::json->'form'->>'key1' AS key1,
content::json->'form'->>'key2' AS key2,
content::json->'url' AS url,
content::json->'method' AS method
FROM http_post('https://httpbin.org/anything', 'key1=value1&key2=value2','application/x-www-form-urlencoded');
status | key1 | key2 | url | method
--------+--------+--------+--------------------------------+--------
200 | value1 | value2 | "https://httpbin.org/anything" | "POST"
(1 row)

-- HEAD
SELECT lower(field) AS field, value
FROM (
Expand Down
10 changes: 5 additions & 5 deletions http--1.0--1.1.sql
Original file line number Diff line number Diff line change
Expand Up @@ -43,26 +43,26 @@ CREATE OR REPLACE FUNCTION http(request http_request)

CREATE OR REPLACE FUNCTION http_get(uri VARCHAR)
RETURNS http_response
AS $$ SELECT http(('GET', $1, NULL, NULL, NULL)::http_request) $$
AS $$ SELECT @extschema@.http(('GET', $1, NULL, NULL, NULL)::http_request) $$
LANGUAGE 'sql';

CREATE OR REPLACE FUNCTION http_post(uri VARCHAR, content VARCHAR, content_type VARCHAR)
RETURNS http_response
AS $$ SELECT http(('POST', $1, NULL, $3, $2)::http_request) $$
AS $$ SELECT @extschema@.http(('POST', $1, NULL, $3, $2)::http_request) $$
LANGUAGE 'sql';

CREATE OR REPLACE FUNCTION http_put(uri VARCHAR, content VARCHAR, content_type VARCHAR)
RETURNS http_response
AS $$ SELECT http(('PUT', $1, NULL, $3, $2)::http_request) $$
AS $$ SELECT @extschema@.http(('PUT', $1, NULL, $3, $2)::http_request) $$
LANGUAGE 'sql';

CREATE OR REPLACE FUNCTION http_delete(uri VARCHAR)
RETURNS http_response
AS $$ SELECT http(('DELETE', $1, NULL, NULL, NULL)::http_request) $$
AS $$ SELECT @extschema@.http(('DELETE', $1, NULL, NULL, NULL)::http_request) $$
LANGUAGE 'sql';

CREATE OR REPLACE FUNCTION urlencode(string VARCHAR)
RETURNS TEXT
AS 'MODULE_PATHNAME'
LANGUAGE 'c'
IMMUTABLE STRICT;
IMMUTABLE STRICT;
2 changes: 1 addition & 1 deletion http--1.1--1.2.sql
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ALTER DOMAIN http_method ADD CHECK (

CREATE OR REPLACE FUNCTION http_head(uri VARCHAR)
RETURNS http_response
AS $$ SELECT http(('HEAD', $1, NULL, NULL, NULL)::http_request) $$
AS $$ SELECT @extschema@.http(('HEAD', $1, NULL, NULL, NULL)::http_request) $$
LANGUAGE 'sql';

CREATE OR REPLACE FUNCTION http_set_curlopt (curlopt VARCHAR, value VARCHAR)
Expand Down
2 changes: 1 addition & 1 deletion http--1.2--1.3.sql
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ ALTER DOMAIN http_method ADD CHECK (

CREATE OR REPLACE FUNCTION http_patch(uri VARCHAR, content VARCHAR, content_type VARCHAR)
RETURNS http_response
AS $$ SELECT http(('PATCH', $1, NULL, $3, $2)::http_request) $$
AS $$ SELECT @extschema@.http(('PATCH', $1, NULL, $3, $2)::http_request) $$
LANGUAGE 'sql';
4 changes: 2 additions & 2 deletions http--1.3--1.4.sql
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ CREATE OR REPLACE FUNCTION urlencode(data JSONB)

CREATE OR REPLACE FUNCTION http_get(uri VARCHAR, data JSONB)
RETURNS http_response
AS $$ SELECT http(('GET', $1 || '?' || urlencode($2), NULL, NULL, NULL)::http_request) $$
AS $$ SELECT @extschema@.http(('GET', $1 || '?' || urlencode($2), NULL, NULL, NULL)::http_request) $$
LANGUAGE 'sql';

CREATE OR REPLACE FUNCTION http_post(uri VARCHAR, data JSONB)
RETURNS http_response
AS $$ SELECT http(('POST', $1, NULL, 'application/x-www-form-urlencoded', urlencode($2))::http_request) $$
AS $$ SELECT @extschema@.http(('POST', $1, NULL, 'application/x-www-form-urlencoded', urlencode($2))::http_request) $$
LANGUAGE 'sql';
5 changes: 5 additions & 0 deletions http--1.4--1.5.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

CREATE OR REPLACE FUNCTION http_delete(uri VARCHAR, content VARCHAR, content_type VARCHAR)
RETURNS http_response
AS $$ SELECT @extschema@.http(('DELETE', $1, NULL, $3, $2)::@extschema@.http_request) $$
LANGUAGE 'sql';
5 changes: 5 additions & 0 deletions http--1.4.sql → http--1.5.sql
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ CREATE OR REPLACE FUNCTION http_delete(uri VARCHAR)
AS $$ SELECT @extschema@.http(('DELETE', $1, NULL, NULL, NULL)::@extschema@.http_request) $$
LANGUAGE 'sql';

CREATE OR REPLACE FUNCTION http_delete(uri VARCHAR, content VARCHAR, content_type VARCHAR)
RETURNS http_response
AS $$ SELECT @extschema@.http(('DELETE', $1, NULL, $3, $2)::@extschema@.http_request) $$
LANGUAGE 'sql';

CREATE OR REPLACE FUNCTION http_head(uri VARCHAR)
RETURNS http_response
AS $$ SELECT @extschema@.http(('HEAD', $1, NULL, NULL, NULL)::@extschema@.http_request) $$
Expand Down
12 changes: 9 additions & 3 deletions http.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
***********************************************************************/

/* Constants */
#define HTTP_VERSION "1.4.0"
#define HTTP_VERSION "1.5.0"
#define HTTP_ENCODING "gzip"
#define CURL_MIN_VERSION 0x071400 /* 7.20.0 */

Expand Down Expand Up @@ -1138,7 +1138,7 @@ Datum http_request(PG_FUNCTION_ARGS)
headers = header_array_to_slist(array, headers);
}

/* If we have a payload we send it, assuming we're either POST, GET or PUT */
/* If we have a payload we send it, assuming we're either POST, GET, PATCH, PUT or DELETE */
if ( ! nulls[REQ_CONTENT] && values[REQ_CONTENT] )
{
text *content_text;
Expand All @@ -1160,15 +1160,21 @@ Datum http_request(PG_FUNCTION_ARGS)
content_text = DatumGetTextP(values[REQ_CONTENT]);
content_size = VARSIZE_ANY_EXHDR(content_text);

if ( method == HTTP_GET || method == HTTP_POST )
if ( method == HTTP_GET || method == HTTP_POST || method == HTTP_DELETE )
{
/* Add the content to the payload */
CURL_SETOPT(g_http_handle, CURLOPT_POST, 1);
if ( method == HTTP_GET )
{
/* Force the verb to be GET */
CURL_SETOPT(g_http_handle, CURLOPT_CUSTOMREQUEST, "GET");
}
else if( method == HTTP_DELETE )
{
/* Force the verb to be DELETE */
CURL_SETOPT(g_http_handle, CURLOPT_CUSTOMREQUEST, "DELETE");
}

CURL_SETOPT(g_http_handle, CURLOPT_POSTFIELDS, text_to_cstring(content_text));
}
else if ( method == HTTP_PUT || method == HTTP_PATCH )
Expand Down
2 changes: 1 addition & 1 deletion http.control
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
default_version = '1.4'
default_version = '1.5'
module_pathname = '$libdir/http'
comment = 'HTTP client for PostgreSQL, allows web page retrieval inside the database.'
26 changes: 21 additions & 5 deletions sql/http.sql
Original file line number Diff line number Diff line change
Expand Up @@ -39,42 +39,58 @@ from http(('GET', 'https://httpbin.org/anything', NULL, 'application/json', '{"s

-- DELETE
SELECT status,
content::json->'args' AS args,
content::json->'args'->>'foo' AS args,
content::json->'url' AS url,
content::json->'method' AS method
FROM http_delete('https://httpbin.org/anything?foo=bar');

-- DELETE with payload
SELECT status,
content::json->'args'->>'foo' AS args,
content::json->'url' AS url,
content::json->'method' AS method,
content::json->'data' AS data
FROM http_delete('https://httpbin.org/anything?foo=bar', 'payload', 'text/plain');

-- PUT
SELECT status,
content::json->'data' AS data,
content::json->'args' AS args,
content::json->'args'->>'foo' AS args,
content::json->'url' AS url,
content::json->'method' AS method
FROM http_put('https://httpbin.org/anything?foo=bar','payload','text/plain');

-- PATCH
SELECT status,
content::json->'data' AS data,
content::json->'args' AS args,
content::json->'args'->>'foo' AS args,
content::json->'url' AS url,
content::json->'method' AS method
FROM http_patch('https://httpbin.org/anything?foo=bar','{"this":"that"}','application/json');

-- POST
SELECT status,
content::json->'data' AS data,
content::json->'args' AS args,
content::json->'args'->>'foo' AS args,
content::json->'url' AS url,
content::json->'method' AS method
FROM http_post('https://httpbin.org/anything?foo=bar','payload','text/plain');

-- POST with data
-- POST with json data
SELECT status,
content::json->'form'->>'this' AS args,
content::json->'url' AS url,
content::json->'method' AS method
FROM http_post('https://httpbin.org/anything', jsonb_build_object('this', 'that'));

-- POST with data
SELECT status,
content::json->'form'->>'key1' AS key1,
content::json->'form'->>'key2' AS key2,
content::json->'url' AS url,
content::json->'method' AS method
FROM http_post('https://httpbin.org/anything', 'key1=value1&key2=value2','application/x-www-form-urlencoded');

-- HEAD
SELECT lower(field) AS field, value
FROM (
Expand Down

0 comments on commit 5ea01c9

Please # to comment.