Skip to content

Commit 74b63c2

Browse files
committed
try to use pgsql mem
1 parent e925600 commit 74b63c2

1 file changed

Lines changed: 68 additions & 47 deletions

File tree

http.c

Lines changed: 68 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include <miscadmin.h>
4747
#include <access/genam.h>
4848
#include <access/htup.h>
49+
#include <access/htup_details.h>
4950
#include <access/sysattr.h>
5051
#include <catalog/namespace.h>
5152
#include <catalog/pg_type.h>
@@ -66,9 +67,6 @@
6667
#include <utils/fmgroids.h>
6768
#include <utils/guc.h>
6869

69-
#if PG_VERSION_NUM >= 90300
70-
# include <access/htup_details.h>
71-
#endif
7270

7371
#if PG_VERSION_NUM >= 100000
7472
# include <utils/varlena.h>
@@ -243,7 +241,9 @@ http_progress_callback(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl
243241

244242
#endif /* 7.39.0 */
245243

246-
#undef HTTP_MEM_CALLBACKS
244+
//#undef HTTP_MEM_CALLBACKS
245+
//xxxxxx
246+
#define HTTP_MEM_CALLBACKS
247247
#ifdef HTTP_MEM_CALLBACKS
248248
static void *
249249
http_calloc(size_t a, size_t b)
@@ -947,13 +947,35 @@ set_curlopt(CURL* handle, const http_curlopt *opt)
947947
return true;
948948
}
949949

950+
static void
951+
http_close_handle(CURL *handle)
952+
{
953+
if (handle != g_http_handle)
954+
elog(ERROR,
955+
"%s called with invalid curl handle, g_http_handle(%p) != handle(%p)",
956+
__func__, g_http_handle, handle);
957+
curl_easy_cleanup(handle);
958+
g_http_handle = NULL;
959+
}
960+
961+
static void
962+
http_reset_handle(CURL *handle)
963+
{
964+
MemoryContext oldcontext;
965+
if (!handle) return;
966+
oldcontext = MemoryContextSwitchTo(TopMemoryContext);
967+
curl_easy_reset(handle);
968+
MemoryContextSwitchTo(oldcontext);
969+
}
970+
950971
/* Check/create the global CURL* handle */
951972
static CURL *
952-
http_get_handle()
973+
http_open_handle()
953974
{
954975
CURL *handle = g_http_handle;
955976
http_curlopt *opt = settable_curlopts;
956977

978+
MemoryContext oldcontext = MemoryContextSwitchTo(TopMemoryContext);
957979
/* Initialize the global handle if needed */
958980
if (!handle)
959981
{
@@ -965,6 +987,7 @@ http_get_handle()
965987
{
966988
curl_easy_reset(handle);
967989
}
990+
MemoryContextSwitchTo(oldcontext);
968991

969992
/* Always want a default fast (1 second) connection timeout */
970993
/* User can over-ride with http_set_curlopt() if they wish */
@@ -1000,8 +1023,8 @@ Datum http_reset_curlopt(PG_FUNCTION_ARGS)
10001023
{
10011024
http_curlopt *opt = settable_curlopts;
10021025
/* Set up global HTTP handle */
1003-
CURL * handle = http_get_handle();
1004-
curl_easy_reset(handle);
1026+
CURL *handle = http_open_handle();
1027+
http_reset_handle(handle);
10051028

10061029
/* Clean out the settable_curlopts global cache */
10071030
while (opt->curlopt)
@@ -1089,7 +1112,7 @@ Datum http_set_curlopt(PG_FUNCTION_ARGS)
10891112
PG_RETURN_BOOL(false);
10901113

10911114
/* Set up global HTTP handle */
1092-
handle = http_get_handle();
1115+
handle = http_open_handle();
10931116

10941117
/* Read arguments */
10951118
curlopt_txt = PG_GETARG_TEXT_P(0);
@@ -1136,6 +1159,7 @@ Datum http_request(PG_FUNCTION_ARGS)
11361159
http_method method;
11371160

11381161
/* Processing */
1162+
CURL *handle;
11391163
CURLcode err;
11401164
char http_error_buffer[CURL_ERROR_SIZE] = "\0";
11411165

@@ -1204,58 +1228,58 @@ Datum http_request(PG_FUNCTION_ARGS)
12041228
elog(DEBUG2, "pgsql-http: method_str: '%s', method: %d", method_str, method);
12051229

12061230
/* Set up global HTTP handle */
1207-
g_http_handle = http_get_handle();
1231+
handle = http_open_handle();
12081232

12091233
/* Set up the error buffer */
1210-
CURL_SETOPT(g_http_handle, CURLOPT_ERRORBUFFER, http_error_buffer);
1234+
CURL_SETOPT(handle, CURLOPT_ERRORBUFFER, http_error_buffer);
12111235

12121236
/* Set the target URL */
1213-
CURL_SETOPT(g_http_handle, CURLOPT_URL, uri);
1237+
CURL_SETOPT(handle, CURLOPT_URL, uri);
12141238

12151239

12161240
/* Restrict to just http/https. Leaving unrestricted */
12171241
/* opens possibility of users requesting file:/// urls */
12181242
/* locally */
12191243
#if LIBCURL_VERSION_NUM >= 0x075400 /* 7.84.0 */
1220-
CURL_SETOPT(g_http_handle, CURLOPT_PROTOCOLS_STR, "http,https");
1244+
CURL_SETOPT(handle, CURLOPT_PROTOCOLS_STR, "http,https");
12211245
#else
1222-
CURL_SETOPT(g_http_handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
1246+
CURL_SETOPT(handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
12231247
#endif
12241248

12251249
if ( curlopt_is_set(CURLOPT_TCP_KEEPALIVE) )
12261250
{
12271251
/* Keep sockets held open */
1228-
CURL_SETOPT(g_http_handle, CURLOPT_FORBID_REUSE, 0);
1252+
CURL_SETOPT(handle, CURLOPT_FORBID_REUSE, 0);
12291253
}
12301254
else
12311255
{
12321256
/* Keep sockets from being held open */
1233-
CURL_SETOPT(g_http_handle, CURLOPT_FORBID_REUSE, 1);
1257+
CURL_SETOPT(handle, CURLOPT_FORBID_REUSE, 1);
12341258
}
12351259

12361260
/* Set up the write-back function */
1237-
CURL_SETOPT(g_http_handle, CURLOPT_WRITEFUNCTION, http_writeback);
1261+
CURL_SETOPT(handle, CURLOPT_WRITEFUNCTION, http_writeback);
12381262

12391263
/* Set up the write-back buffer */
12401264
initStringInfo(&si_data);
12411265
initStringInfo(&si_headers);
1242-
CURL_SETOPT(g_http_handle, CURLOPT_WRITEDATA, (void*)(&si_data));
1243-
CURL_SETOPT(g_http_handle, CURLOPT_WRITEHEADER, (void*)(&si_headers));
1266+
CURL_SETOPT(handle, CURLOPT_WRITEDATA, (void*)(&si_data));
1267+
CURL_SETOPT(handle, CURLOPT_WRITEHEADER, (void*)(&si_headers));
12441268

12451269
#if LIBCURL_VERSION_NUM >= 0x072700 /* 7.39.0 */
12461270
/* Connect the progress callback for interrupt support */
1247-
CURL_SETOPT(g_http_handle, CURLOPT_XFERINFOFUNCTION, http_progress_callback);
1248-
CURL_SETOPT(g_http_handle, CURLOPT_NOPROGRESS, 0);
1271+
CURL_SETOPT(handle, CURLOPT_XFERINFOFUNCTION, http_progress_callback);
1272+
CURL_SETOPT(handle, CURLOPT_NOPROGRESS, 0);
12491273
#endif
12501274

12511275
/* Set the HTTP content encoding to all curl supports */
1252-
CURL_SETOPT(g_http_handle, CURLOPT_ACCEPT_ENCODING, "");
1276+
CURL_SETOPT(handle, CURLOPT_ACCEPT_ENCODING, "");
12531277

12541278
if ( method != HTTP_HEAD )
12551279
{
12561280
/* Follow redirects, as many as 5 */
1257-
CURL_SETOPT(g_http_handle, CURLOPT_FOLLOWLOCATION, 1);
1258-
CURL_SETOPT(g_http_handle, CURLOPT_MAXREDIRS, 5);
1281+
CURL_SETOPT(handle, CURLOPT_FOLLOWLOCATION, 1);
1282+
CURL_SETOPT(handle, CURLOPT_MAXREDIRS, 5);
12591283
}
12601284

12611285
if ( curlopt_is_set(CURLOPT_TCP_KEEPALIVE) )
@@ -1304,36 +1328,36 @@ Datum http_request(PG_FUNCTION_ARGS)
13041328
if ( method == HTTP_GET || method == HTTP_POST || method == HTTP_DELETE )
13051329
{
13061330
/* Add the content to the payload */
1307-
CURL_SETOPT(g_http_handle, CURLOPT_POST, 1);
1331+
CURL_SETOPT(handle, CURLOPT_POST, 1);
13081332
if ( method == HTTP_GET )
13091333
{
13101334
/* Force the verb to be GET */
1311-
CURL_SETOPT(g_http_handle, CURLOPT_CUSTOMREQUEST, "GET");
1335+
CURL_SETOPT(handle, CURLOPT_CUSTOMREQUEST, "GET");
13121336
}
13131337
else if( method == HTTP_DELETE )
13141338
{
13151339
/* Force the verb to be DELETE */
1316-
CURL_SETOPT(g_http_handle, CURLOPT_CUSTOMREQUEST, "DELETE");
1340+
CURL_SETOPT(handle, CURLOPT_CUSTOMREQUEST, "DELETE");
13171341
}
13181342

1319-
CURL_SETOPT(g_http_handle, CURLOPT_POSTFIELDS, (char *)(VARDATA(content_text)));
1320-
CURL_SETOPT(g_http_handle, CURLOPT_POSTFIELDSIZE, content_size);
1343+
CURL_SETOPT(handle, CURLOPT_POSTFIELDS, (char *)(VARDATA(content_text)));
1344+
CURL_SETOPT(handle, CURLOPT_POSTFIELDSIZE, content_size);
13211345
}
13221346
else if ( method == HTTP_PUT || method == HTTP_PATCH || method == HTTP_UNKNOWN )
13231347
{
13241348
if ( method == HTTP_PATCH )
1325-
CURL_SETOPT(g_http_handle, CURLOPT_CUSTOMREQUEST, "PATCH");
1349+
CURL_SETOPT(handle, CURLOPT_CUSTOMREQUEST, "PATCH");
13261350

13271351
/* Assume the user knows what they are doing and pass unchanged */
13281352
if ( method == HTTP_UNKNOWN )
1329-
CURL_SETOPT(g_http_handle, CURLOPT_CUSTOMREQUEST, method_str);
1353+
CURL_SETOPT(handle, CURLOPT_CUSTOMREQUEST, method_str);
13301354

13311355
initStringInfo(&si_read);
13321356
appendBinaryStringInfo(&si_read, VARDATA(content_text), content_size);
1333-
CURL_SETOPT(g_http_handle, CURLOPT_UPLOAD, 1);
1334-
CURL_SETOPT(g_http_handle, CURLOPT_READFUNCTION, http_readback);
1335-
CURL_SETOPT(g_http_handle, CURLOPT_READDATA, &si_read);
1336-
CURL_SETOPT(g_http_handle, CURLOPT_INFILESIZE, content_size);
1357+
CURL_SETOPT(handle, CURLOPT_UPLOAD, 1);
1358+
CURL_SETOPT(handle, CURLOPT_READFUNCTION, http_readback);
1359+
CURL_SETOPT(handle, CURLOPT_READDATA, &si_read);
1360+
CURL_SETOPT(handle, CURLOPT_INFILESIZE, content_size);
13371361
}
13381362
else
13391363
{
@@ -1343,11 +1367,11 @@ Datum http_request(PG_FUNCTION_ARGS)
13431367
}
13441368
else if ( method == HTTP_DELETE )
13451369
{
1346-
CURL_SETOPT(g_http_handle, CURLOPT_CUSTOMREQUEST, "DELETE");
1370+
CURL_SETOPT(handle, CURLOPT_CUSTOMREQUEST, "DELETE");
13471371
}
13481372
else if ( method == HTTP_HEAD )
13491373
{
1350-
CURL_SETOPT(g_http_handle, CURLOPT_NOBODY, 1);
1374+
CURL_SETOPT(handle, CURLOPT_NOBODY, 1);
13511375
}
13521376
else if ( method == HTTP_PUT || method == HTTP_POST )
13531377
{
@@ -1356,17 +1380,17 @@ Datum http_request(PG_FUNCTION_ARGS)
13561380
}
13571381
else if ( method == HTTP_UNKNOWN ){
13581382
/* Assume the user knows what they are doing and pass unchanged */
1359-
CURL_SETOPT(g_http_handle, CURLOPT_CUSTOMREQUEST, method_str);
1383+
CURL_SETOPT(handle, CURLOPT_CUSTOMREQUEST, method_str);
13601384
}
13611385

13621386
pfree(method_str);
13631387
/* Set the headers */
1364-
CURL_SETOPT(g_http_handle, CURLOPT_HTTPHEADER, headers);
1388+
CURL_SETOPT(handle, CURLOPT_HTTPHEADER, headers);
13651389

13661390
/*************************************************************************
13671391
* PERFORM THE REQUEST!
13681392
**************************************************************************/
1369-
http_return = curl_easy_perform(g_http_handle);
1393+
http_return = curl_easy_perform(handle);
13701394
elog(DEBUG2, "pgsql-http: queried '%s'", uri);
13711395
elog(DEBUG2, "pgsql-http: http_return '%d'", http_return);
13721396

@@ -1383,8 +1407,7 @@ Datum http_request(PG_FUNCTION_ARGS)
13831407
if ( http_return != CURLE_OK )
13841408
{
13851409
curl_slist_free_all(headers);
1386-
curl_easy_cleanup(g_http_handle);
1387-
g_http_handle = NULL;
1410+
http_close_handle(handle);
13881411

13891412
#if LIBCURL_VERSION_NUM >= 0x072700 /* 7.39.0 */
13901413
/*
@@ -1399,12 +1422,11 @@ Datum http_request(PG_FUNCTION_ARGS)
13991422
}
14001423

14011424
/* Read the metadata from the handle directly */
1402-
if ( (CURLE_OK != curl_easy_getinfo(g_http_handle, CURLINFO_RESPONSE_CODE, &long_status)) ||
1403-
(CURLE_OK != curl_easy_getinfo(g_http_handle, CURLINFO_CONTENT_TYPE, &content_type)) )
1425+
if ( (CURLE_OK != curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &long_status)) ||
1426+
(CURLE_OK != curl_easy_getinfo(handle, CURLINFO_CONTENT_TYPE, &content_type)) )
14041427
{
14051428
curl_slist_free_all(headers);
1406-
curl_easy_cleanup(g_http_handle);
1407-
g_http_handle = NULL;
1429+
http_close_handle(handle);
14081430
ereport(ERROR, (errmsg("CURL: Error in curl_easy_getinfo")));
14091431
}
14101432

@@ -1507,8 +1529,7 @@ Datum http_request(PG_FUNCTION_ARGS)
15071529
ReleaseTupleDesc(tup_desc);
15081530
if ( ! curlopt_is_set(CURLOPT_TCP_KEEPALIVE) )
15091531
{
1510-
curl_easy_cleanup(g_http_handle);
1511-
g_http_handle = NULL;
1532+
http_close_handle(handle);
15121533
}
15131534
curl_slist_free_all(headers);
15141535
pfree(si_headers.data);

0 commit comments

Comments
 (0)