@@ -103,7 +103,30 @@ header_cb(void *contents, size_t size, size_t nmemb, void *userp)
103
103
return realsize ;
104
104
}
105
105
106
- static int init (CURLM * cm , char * method , char * url , char * contentType , char * reqBody , int64 id , HTAB * curlDataMap )
106
+ static struct curl_slist *
107
+ header_array_to_slist (ArrayType * array , struct curl_slist * headers )
108
+ {
109
+ ArrayIterator iterator ;
110
+ Datum value ;
111
+ bool isnull ;
112
+ char * header ;
113
+
114
+ iterator = array_create_iterator (array , 0 , NULL );
115
+
116
+ while (array_iterate (iterator , & value , & isnull ))
117
+ {
118
+ if (isnull ) continue ;
119
+
120
+ header = TextDatumGetCString (value );
121
+ elog (DEBUG1 , "Request header \"%s\"\n" , header );
122
+ headers = curl_slist_append (headers , header );
123
+ }
124
+ array_free_iterator (iterator );
125
+
126
+ return headers ;
127
+ }
128
+
129
+ static int init (CURLM * cm , char * method , char * url , struct curl_slist * reqHeaders , char * reqBody , int64 id , HTAB * curlDataMap )
107
130
{
108
131
CURL * eh = curl_easy_init ();
109
132
@@ -121,11 +144,7 @@ static int init(CURLM *cm, char *method, char *url, char *contentType, char *req
121
144
cdata -> headers = headers ;
122
145
}
123
146
124
- if (contentType ) {
125
- struct curl_slist * reqHeaders = NULL ;
126
- reqHeaders = curl_slist_append (reqHeaders , contentType );
127
- curl_easy_setopt (eh , CURLOPT_HTTPHEADER , reqHeaders );
128
- }
147
+ reqHeaders = curl_slist_append (reqHeaders , "User-Agent: pg_net/0.0.1" );
129
148
130
149
if (strcasecmp (method , "GET" ) == 0 ) {
131
150
if (reqBody ) {
@@ -146,8 +165,9 @@ static int init(CURLM *cm, char *method, char *url, char *contentType, char *req
146
165
curl_easy_setopt (eh , CURLOPT_HEADERDATA , cdata -> headers );
147
166
curl_easy_setopt (eh , CURLOPT_HEADER , 0L );
148
167
curl_easy_setopt (eh , CURLOPT_URL , url );
168
+ curl_easy_setopt (eh , CURLOPT_HTTPHEADER , reqHeaders );
149
169
curl_easy_setopt (eh , CURLOPT_PRIVATE , id );
150
- curl_easy_setopt (eh , CURLOPT_VERBOSE , 0L );
170
+ // curl_easy_setopt(eh, CURLOPT_VERBOSE, 1); // for debugging
151
171
return curl_multi_add_handle (cm , eh );
152
172
}
153
173
@@ -224,7 +244,13 @@ worker_main(Datum main_arg)
224
244
225
245
appendStringInfo (& select_query , "\
226
246
SELECT\
227
- q.id, q.method, q.url, q.content_type, q.body\
247
+ q.id,\
248
+ q.method,\
249
+ q.url,\
250
+ array(\
251
+ select key || ': ' || value from jsonb_each_text(q.headers)\
252
+ ),\
253
+ q.body\
228
254
FROM net.http_request_queue q \
229
255
LEFT JOIN net._http_response r ON q.id = r.id \
230
256
WHERE r.id IS NULL" );
@@ -243,35 +269,37 @@ worker_main(Datum main_arg)
243
269
244
270
for (int j = 0 ; j < SPI_processed ; j ++ )
245
271
{
246
- StringInfoData content_type ;
272
+ struct curl_slist * headers = NULL ;
273
+ // FIXME: Need to free headers, but only *after* curl_multi stuff during cleanup.
274
+ // Maybe store in cdata?
275
+ // curl_slist_free_all(headers);
247
276
248
277
int64 id = DatumGetInt64 (SPI_getbinval (SPI_tuptable -> vals [j ], SPI_tuptable -> tupdesc , 1 , & tupIsNull ));
249
278
char * method = TextDatumGetCString (SPI_getbinval (SPI_tuptable -> vals [j ], SPI_tuptable -> tupdesc , 2 , & tupIsNull ));
250
279
char * url = TextDatumGetCString (SPI_getbinval (SPI_tuptable -> vals [j ], SPI_tuptable -> tupdesc , 3 , & tupIsNull ));
251
- Datum contentTypeBin ;
280
+
281
+ Datum headersBin ;
252
282
Datum bodyBin ;
253
- char * contentType = NULL ;
283
+ ArrayType * pgHeaders ;
254
284
char * body = NULL ;
255
285
256
- contentTypeBin = SPI_getbinval (SPI_tuptable -> vals [j ], SPI_tuptable -> tupdesc , 4 , & tupIsNull );
286
+ headersBin = SPI_getbinval (SPI_tuptable -> vals [j ], SPI_tuptable -> tupdesc , 4 , & tupIsNull );
257
287
if (!tupIsNull ) {
258
- initStringInfo (& content_type );
259
- appendStringInfo (& content_type , "Content-Type: %s" , TextDatumGetCString (contentTypeBin ));
260
- contentType = content_type .data ;
288
+ pgHeaders = DatumGetArrayTypeP (headersBin );
289
+ headers = header_array_to_slist (pgHeaders , headers );
261
290
}
262
291
bodyBin = SPI_getbinval (SPI_tuptable -> vals [j ], SPI_tuptable -> tupdesc , 5 , & tupIsNull );
263
292
if (!tupIsNull ) body = TextDatumGetCString (bodyBin );
264
293
265
294
elog (DEBUG1 , "Making a %s request to %s with id %ld" , method , url , id );
266
295
267
- res = init (cm , method , url , contentType , body , id , curlDataMap );
268
-
269
- /* pfree(content_type.data); */
296
+ res = init (cm , method , url , headers , body , id , curlDataMap );
270
297
271
298
if (res ) {
272
299
elog (ERROR , "error: init() returned %d\n" , res );
273
300
}
274
301
res = curl_multi_perform (cm , & still_running );
302
+
275
303
if (res != CURLM_OK ) {
276
304
elog (ERROR , "error: curl_multi_perform() returned %d\n" , res );
277
305
}
0 commit comments