diff --git a/Makefile b/Makefile index b4478ca..884d520 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ else endif EXTENSION = pg_net -EXTVERSION = 0.20.0 +EXTVERSION = 0.20.1 DATA = $(wildcard sql/*--*.sql) diff --git a/sql/pg_net--0.20.0--0.20.1.sql b/sql/pg_net--0.20.0--0.20.1.sql new file mode 100644 index 0000000..5c8be17 --- /dev/null +++ b/sql/pg_net--0.20.0--0.20.1.sql @@ -0,0 +1 @@ +-- no SQL changes in 0.20.1 diff --git a/src/errors.h b/src/errors.h index 16237fa..1831fb2 100644 --- a/src/errors.h +++ b/src/errors.h @@ -26,6 +26,21 @@ list = new_list; \ } while (0) +// curl_url_strerror is available starting from libcurl 7.80.0 +#define EREPORT_CURL_URL_SET(hdl, part, str, flags) \ + do { \ + CURLUcode rc = curl_url_set(hdl, part, str, flags); \ + if (rc != CURLUE_OK) \ + ereport(ERROR, errmsg("invalid URL \"%s\": %s", str, curl_url_strerror(rc))); \ + } while (0) + +#define EREPORT_CURL_URL_GET(hdl, part, out, flags, value) \ + do { \ + CURLUcode rc = curl_url_get(hdl, part, out, flags); \ + if (rc != CURLUE_OK) \ + ereport(ERROR, errmsg("failed to encode URL \"%s\": %s", value, curl_url_strerror(rc))); \ + } while (0) + #define EREPORT_NULL_ATTR(tupIsNull, attr) \ do { \ if (tupIsNull) ereport(ERROR, errmsg("%s cannot be null", #attr)); \ diff --git a/src/event.h b/src/event.h index 96b2f5f..a6922dd 100644 --- a/src/event.h +++ b/src/event.h @@ -1,7 +1,7 @@ #ifndef EVENT_H #define EVENT_H -#include +#include "curl_prelude.h" #include "core.h" diff --git a/src/util.c b/src/util.c index 13e8f1c..108d379 100644 --- a/src/util.c +++ b/src/util.c @@ -2,6 +2,7 @@ #include "curl_prelude.h" +#include "errors.h" #include "util.h" PG_FUNCTION_INFO_V1(_urlencode_string); @@ -33,30 +34,20 @@ Datum _encode_url_with_params_array(PG_FUNCTION_ARGS) { bool isnull; char *param; - CURLU *h = curl_url(); - CURLUcode rc = curl_url_set(h, CURLUPART_URL, url, 0); - if (rc != CURLUE_OK) { - // TODO: Use curl_url_strerror once released. - elog(ERROR, "%s", curl_easy_strerror((CURLcode)rc)); - } + CURLU *h = curl_url(); + EREPORT_CURL_URL_SET(h, CURLUPART_URL, url, 0); iterator = array_create_iterator(params, 0, NULL); while (array_iterate(iterator, &value, &isnull)) { if (isnull) continue; param = TextDatumGetCString(value); - rc = curl_url_set(h, CURLUPART_QUERY, param, CURLU_APPENDQUERY); - if (rc != CURLUE_OK) { - elog(ERROR, "curl_url returned: %d", rc); - } + EREPORT_CURL_URL_SET(h, CURLUPART_QUERY, param, CURLU_APPENDQUERY); pfree(param); } array_free_iterator(iterator); - rc = curl_url_get(h, CURLUPART_URL, &full_url, 0); - if (rc != CURLUE_OK) { - elog(ERROR, "curl_url returned: %d", rc); - } + EREPORT_CURL_URL_GET(h, CURLUPART_URL, &full_url, 0, url); pfree(url); curl_url_cleanup(h); diff --git a/test/test_http_errors.py b/test/test_http_errors.py index 2eb6e41..78cd4f3 100644 --- a/test/test_http_errors.py +++ b/test/test_http_errors.py @@ -15,7 +15,20 @@ def test_get_bad_url(sess): """ )) - assert r"resolve proxy name" in str(execinfo) + assert 'Unsupported URL scheme' in str(execinfo.value) + + +def test_http_get_rejects_relative_url(sess): + """net.http_get with a correct error when given a relative url""" + + with pytest.raises(Exception) as execinfo: + sess.execute(text( + """ + select net.http_get('/malformed_url'); + """ + )) + + assert 'invalid URL "/malformed_url"' in str(execinfo.value) def test_bad_post(sess):