Skip to content

Commit 6a24770

Browse files
authored
Merge pull request #139 from moteus/curlu_option
Add. support CURLOPT_CULRU
2 parents c03bade + 50ec433 commit 6a24770

File tree

9 files changed

+192
-35
lines changed

9 files changed

+192
-35
lines changed

appveyor.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ shallow_clone: true
77

88
environment:
99
LR_EXTERNAL: c:\external
10-
CURL_VER: 7.62.0
10+
CURL_VER: 7.63.0
1111

1212
matrix:
1313
- LUA: "lua 5.1"

src/lceasy.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "lcshare.h"
1717
#include "lcmulti.h"
1818
#include "lcmime.h"
19+
#include "lcurlapi.h"
1920
#include <memory.h>
2021

2122
static const char *LCURL_ERROR_TAG = "LCURL_ERROR_TAG";
@@ -82,6 +83,9 @@ int lcurl_easy_create(lua_State *L, int error_mode){
8283
p->multi = NULL;
8384
#if LCURL_CURL_VER_GE(7,56,0)
8485
p->mime = NULL;
86+
#endif
87+
#if LCURL_CURL_VER_GE(7,63,0)
88+
p->url = NULL;
8589
#endif
8690
p->storage = lcurl_storage_init(L);
8791
p->wr.cb_ref = p->wr.ud_ref = LUA_NOREF;
@@ -151,6 +155,10 @@ static int lcurl_easy_cleanup(lua_State *L){
151155
p->mime = NULL;
152156
#endif
153157

158+
#if LCURL_CURL_VER_GE(7,63,0)
159+
p->url = NULL;
160+
#endif
161+
154162
if(p->storage != LUA_NOREF){
155163
p->storage = lcurl_storage_free(L, p->storage);
156164
}
@@ -539,6 +547,25 @@ static int lcurl_easy_set_MIMEPOST(lua_State *L){
539547

540548
#endif
541549

550+
#if LCURL_CURL_VER_GE(7,63,0)
551+
552+
static int lcurl_easy_set_CURLU(lua_State *L) {
553+
lcurl_easy_t *p = lcurl_geteasy(L);
554+
lcurl_url_t *url = lcurl_geturl_at(L, 2);
555+
CURLcode code = curl_easy_setopt(p->curl, CURLOPT_CURLU, url->url);
556+
if (code != CURLE_OK) {
557+
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
558+
}
559+
560+
lcurl_storage_preserve_iv(L, p->storage, CURLOPT_CURLU, 2);
561+
562+
p->url = url;
563+
564+
lua_settop(L, 1);
565+
return 1;
566+
}
567+
568+
#endif
542569
//}
543570

544571
//{ unset
@@ -907,6 +934,25 @@ static int lcurl_easy_unset_MIMEPOST(lua_State *L){
907934

908935
#endif
909936

937+
#if LCURL_CURL_VER_GE(7,63,0)
938+
939+
static int lcurl_easy_unset_CURLU(lua_State *L) {
940+
lcurl_easy_t *p = lcurl_geteasy(L);
941+
CURLcode code = curl_easy_setopt(p->curl, CURLOPT_CURLU, NULL);
942+
if (code != CURLE_OK) {
943+
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
944+
}
945+
946+
lcurl_storage_remove_i(L, p->storage, CURLOPT_CURLU);
947+
948+
p->url = NULL;
949+
950+
lua_settop(L, 1);
951+
return 1;
952+
}
953+
954+
#endif
955+
910956
//}
911957

912958
//}
@@ -1731,6 +1777,9 @@ static const struct luaL_Reg lcurl_easy_methods[] = {
17311777
#if LCURL_CURL_VER_GE(7,56,0)
17321778
OPT_ENTRY(mimepost, MIMEPOST, TTT, 0, 0)
17331779
#endif
1780+
#if LCURL_CURL_VER_GE(7,63,0)
1781+
OPT_ENTRY(curlu, CURLU, TTT, 0, 0)
1782+
#endif
17341783
#undef OPT_ENTRY
17351784

17361785
#define OPT_ENTRY(L, N, T, S, D) { "unsetopt_"#L, lcurl_easy_unset_##N },
@@ -1756,6 +1805,9 @@ static const struct luaL_Reg lcurl_easy_methods[] = {
17561805
#if LCURL_CURL_VER_GE(7,56,0)
17571806
OPT_ENTRY(mimepost, MIMEPOST, TTT, 0, 0)
17581807
#endif
1808+
#if LCURL_CURL_VER_GE(7,63,0)
1809+
OPT_ENTRY(curlu, CURLU, TTT, 0, 0)
1810+
#endif
17591811
#undef OPT_ENTRY
17601812

17611813
#define OPT_ENTRY(L, N, T, S) { "getinfo_"#L, lcurl_easy_get_##N },
@@ -1813,6 +1865,9 @@ static const lcurl_const_t lcurl_easy_opt[] = {
18131865
#if LCURL_CURL_VER_GE(7,56,0)
18141866
OPT_ENTRY(mimepost, MIMEPOST, TTT, 0, 0)
18151867
#endif
1868+
#if LCURL_CURL_VER_GE(7,63,0)
1869+
OPT_ENTRY(curlu, CURLU, TTT, 0, 0)
1870+
#endif
18161871
#undef OPT_ENTRY
18171872
#undef FLG_ENTRY
18181873

src/lceasy.h

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,24 @@ enum {
3838
#define LCURL_EASY_MAGIC 0xEA
3939

4040
#if LCURL_CC_SUPPORT_FORWARD_TYPEDEF
41-
typedef struct lcurl_multi_tag lcurl_multi_t;
42-
#if LCURL_CURL_VER_GE(7,56,0)
43-
typedef struct lcurl_mime_tag lcurl_mime_t;
44-
#endif
41+
typedef struct lcurl_multi_tag lcurl_multi_t;
42+
#if LCURL_CURL_VER_GE(7,56,0)
43+
typedef struct lcurl_mime_tag lcurl_mime_t;
44+
#endif
45+
#if LCURL_CURL_VER_GE(7,63,0)
46+
typedef struct lcurl_url_tag lcurl_url_t;
47+
#endif
4548
#else
46-
struct lcurl_multi_tag;
47-
#define lcurl_multi_t struct lcurl_multi_tag
48-
#if LCURL_CURL_VER_GE(7,56,0)
49-
struct lcurl_mime_tag;
50-
#define lcurl_mime_t struct lcurl_mime_tag
51-
#endif
49+
struct lcurl_multi_tag;
50+
#define lcurl_multi_t struct lcurl_multi_tag
51+
#if LCURL_CURL_VER_GE(7,56,0)
52+
struct lcurl_mime_tag;
53+
#define lcurl_mime_t struct lcurl_mime_tag
54+
#endif
55+
#if LCURL_CURL_VER_GE(7,63,0)
56+
struct lcurl_url_tag;
57+
#define lcurl_url_t struct lcurl_url_tag
58+
#endif
5259
#endif
5360

5461
typedef struct lcurl_easy_tag{
@@ -66,6 +73,10 @@ typedef struct lcurl_easy_tag{
6673
lcurl_mime_t *mime;
6774
#endif
6875

76+
#if LCURL_CURL_VER_GE(7,63,0)
77+
lcurl_url_t *url;
78+
#endif
79+
6980
CURL *curl;
7081
int storage;
7182
int lists[LCURL_LIST_COUNT];

src/lcopteasy.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,7 @@ OPT_ENTRY( timevalue_large, TIMEVALUE_LARGE ,OFF, 0, LCURL_DEF
441441

442442
#if LCURL_CURL_VER_GE(7,60,0)
443443
OPT_ENTRY(dns_shuffle_addresses, DNS_SHUFFLE_ADDRESSES, LNG, 0, LCURL_DEFAULT_VALUE)
444-
OPT_ENTRY(haproxyprotocol, HAPROXYPROTOCOL, LNG, 0, LCURL_DEFAULT_VALUE)
444+
OPT_ENTRY(haproxyprotocol, HAPROXYPROTOCOL, LNG, 0, LCURL_DEFAULT_VALUE)
445445
#endif
446446

447447
#if LCURL_CURL_VER_GE(7,61,0)

src/lcurlapi.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,6 @@ static const char *LCURL_URL = LCURL_URL_NAME;
2121

2222
#define lcurl_geturl(L) lcurl_geturl_at(L, 1)
2323

24-
typedef struct lcurl_url_tag{
25-
CURLU *url;
26-
27-
int err_mode;
28-
}lcurl_url_t;
29-
3024
int lcurl_url_create(lua_State *L, int error_mode){
3125
lcurl_url_t *p;
3226

@@ -55,7 +49,7 @@ int lcurl_url_create(lua_State *L, int error_mode){
5549
return 1;
5650
}
5751

58-
static lcurl_url_t *lcurl_geturl_at(lua_State *L, int i){
52+
lcurl_url_t *lcurl_geturl_at(lua_State *L, int i){
5953
lcurl_url_t *p = (lcurl_url_t *)lutil_checkudatap (L, i, LCURL_URL);
6054
luaL_argcheck (L, p != NULL, 1, LCURL_URL_NAME" object expected");
6155
return p;

src/lcurlapi.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@
1717

1818
void lcurl_url_initlib(lua_State *L, int nup);
1919

20+
#if LCURL_CURL_VER_GE(7,62,0)
21+
22+
typedef struct lcurl_url_tag {
23+
CURLU *url;
24+
25+
int err_mode;
26+
}lcurl_url_t;
27+
2028
int lcurl_url_create(lua_State *L, int error_mode);
2129

30+
lcurl_url_t *lcurl_geturl_at(lua_State *L, int i);
31+
32+
#endif
33+
2234
#endif

test/test_curl.lua

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,11 @@ local fname = "./test.download"
2020

2121
local utils = require "utils"
2222

23-
local is_curl_ge = utils.is_curl_ge
24-
25-
local function weak_ptr(val)
26-
return setmetatable({value = val},{__mode = 'v'})
27-
end
28-
29-
local function gc_collect()
30-
for i = 1, 5 do
31-
collectgarbage("collect")
32-
end
33-
end
23+
local weak_ptr, gc_collect, is_curl_ge, is_curl_eq, read_file, stream, Stream, dump_request =
24+
utils.import('weak_ptr', 'gc_collect', 'is_curl_ge', 'is_curl_eq', 'read_file', 'stream', 'Stream', 'dump_request')
3425

3526
-- Bug. libcurl 7.56.0 does not add `Content-Type: text/plain`
36-
local text_plain = utils.is_curl_eq(7,56,0) and 'test/plain' or 'text/plain'
27+
local text_plain = is_curl_eq(7,56,0) and 'test/plain' or 'text/plain'
3728

3829
local GET_URL = "http://127.0.0.1:7090/get"
3930

test/test_urlapi.lua

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ local skip = lunit.skip or function() end
1515
local curl = require "cURL"
1616
local scurl = require "cURL.safe"
1717
local utils = require "utils"
18+
local json = require "dkjson"
19+
local table = table
20+
21+
local weak_ptr, gc_collect, is_curl_eq = utils.import('weak_ptr', 'gc_collect', 'is_curl_eq')
22+
23+
local GET_URL = "http://127.0.0.1:7090/get"
1824

1925
local tostring, pcall = tostring, pcall
2026

@@ -150,7 +156,11 @@ end)
150156
it('should append only one parameter in query per call', function()
151157
url = U"http://example.com"
152158
assert_equal(url, url:set_query("a=hello world&b=A&B", curl.U_APPENDQUERY + curl.U_URLENCODE))
153-
assert_equal("http://example.com/?a=hello+world%26b=A%26B", url:get_url())
159+
if is_curl_eq(7, 62, 0) then
160+
assert_equal("http://example.com/?a=hello+world%26b=A%26B", url:get_url())
161+
else
162+
assert_equal("http://example.com/?a=hello+world%26b%3dA%26B", url:get_url())
163+
end
154164
end)
155165

156166
it('should set encoded query', function()
@@ -203,4 +213,87 @@ end)
203213

204214
end end
205215

216+
local _ENV = TEST_CASE'curlu parameter' if ENABLE then
217+
218+
if not curl.OPT_CURLU then test = skip_case('CURLU option avaliable since libcurl 7.63.0') else
219+
220+
local it = setmetatable(_ENV or _M, {__call = function(self, describe, fn)
221+
self["test " .. describe] = fn
222+
end})
223+
224+
local url, easy, buffer
225+
226+
local function writer(chunk)
227+
table.insert(buffer, chunk)
228+
end
229+
230+
local function json_data()
231+
return json.decode(table.concat(buffer))
232+
end
233+
234+
local function U(u)
235+
url = assert_userdata(curl.url())
236+
assert_equal(url, url:set_url(u))
237+
return url
238+
end
239+
240+
function setup()
241+
buffer = {}
242+
end
243+
244+
function teardown()
245+
if url then url:cleanup() end
246+
if easy then easy:close() end
247+
url = nil
248+
end
249+
250+
it('easy should prevent url from gc', function()
251+
local purl
252+
do
253+
easy = curl.easy()
254+
local url = U(GET_URL)
255+
assert_equal(easy, easy:setopt_curlu(url))
256+
purl = weak_ptr(url)
257+
end
258+
259+
gc_collect()
260+
assert_not_nil(purl.value)
261+
262+
assert_equal(easy, easy:unsetopt_curlu())
263+
264+
gc_collect()
265+
assert_not_nil(purl.value)
266+
end)
267+
268+
it('should use url from curlu parameter', function()
269+
url = U(GET_URL)
270+
easy = curl.easy {curlu = url, writefunction = writer}
271+
assert_equal(easy, easy:perform())
272+
local response = assert_table(json_data())
273+
assert_equal(GET_URL, response.url)
274+
end)
275+
276+
it('should be possible reset url', function()
277+
url = U("http://example.com")
278+
easy = curl.easy {curlu = url, writefunction = writer}
279+
url:set_url(GET_URL)
280+
281+
assert_equal(easy, easy:perform())
282+
local response = assert_table(json_data())
283+
assert_equal(GET_URL, response.url)
284+
end)
285+
286+
it('should be possible reuse url', function()
287+
url = U(GET_URL)
288+
for i = 1, 5 do
289+
local easy = curl.easy {curlu = url, writefunction = writer}
290+
assert_equal(easy, easy:perform())
291+
local response = assert_table(json_data())
292+
assert_equal(GET_URL, response.url)
293+
gc_collect()
294+
end
295+
end)
296+
297+
end end
298+
206299
RUN()

test/utils.lua

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ local function weak_ptr(val)
44
return setmetatable({value = val},{__mode = 'v'})
55
end
66

7-
local function gc_collect()
8-
collectgarbage("collect")
9-
collectgarbage("collect")
7+
local function gc_collect(n)
8+
for i = 1, (n or 2) do
9+
collectgarbage("collect")
10+
end
1011
end
1112

1213
local function cver(min, maj, pat)

0 commit comments

Comments
 (0)