Skip to content

Commit 099f748

Browse files
committed
Add. cURL urlapi support
1 parent 315a2d8 commit 099f748

File tree

8 files changed

+451
-4
lines changed

8 files changed

+451
-4
lines changed

lakefile

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ target('test', install, function()
3535
run_test('test_mime.lua')
3636
run_test('test_multi_callback.lua')
3737
run_test('test_multi_nested_callback.lua')
38+
run_test('test_urlapi.lua')
3839

3940
if not test_summary() then
4041
quit("test fail")

rockspecs/lua-curl-scm-0.rockspec

+4-3
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,10 @@ build = {
6161

6262
lcurl = {
6363
sources = {
64-
"src/l52util.c", "src/lceasy.c", "src/lcerror.c",
65-
"src/lchttppost.c", "src/lcurl.c", "src/lcutils.c",
66-
"src/lcmulti.c", "src/lcshare.c","src/lcmime.c",
64+
"src/l52util.c", "src/lceasy.c", "src/lcerror.c",
65+
"src/lchttppost.c", "src/lcurl.c", "src/lcutils.c",
66+
"src/lcmulti.c", "src/lcshare.c", "src/lcmime.c",
67+
"src/lcurlapi.c",
6768
},
6869
incdirs = { "$(CURL_INCDIR)" },
6970
libdirs = { "$(CURL_LIBDIR)" }

src/lcopturl.h

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
ENTRY_PART(fragment, UPART_FRAGMENT , CURLUE_NO_FRAGMENT )
2+
ENTRY_PART(host, UPART_HOST , CURLUE_NO_HOST )
3+
ENTRY_PART(options, UPART_OPTIONS , CURLUE_NO_OPTIONS )
4+
ENTRY_PART(password, UPART_PASSWORD , CURLUE_NO_PASSWORD )
5+
ENTRY_PART(path, UPART_PATH , CURLUE_OK )
6+
ENTRY_PART(port, UPART_PORT , CURLUE_NO_PORT )
7+
ENTRY_PART(query, UPART_QUERY , CURLUE_NO_QUERY )
8+
ENTRY_PART(scheme, UPART_SCHEME , CURLUE_NO_SCHEME )
9+
ENTRY_PART(url, UPART_URL , CURLUE_OK )
10+
ENTRY_PART(user, UPART_USER , CURLUE_NO_USER )
11+
12+
ENTRY_FLAG(DEFAULT_PORT )
13+
ENTRY_FLAG(NO_DEFAULT_PORT )
14+
ENTRY_FLAG(DEFAULT_SCHEME )
15+
ENTRY_FLAG(NON_SUPPORT_SCHEME )
16+
ENTRY_FLAG(PATH_AS_IS )
17+
ENTRY_FLAG(DISALLOW_USER )
18+
ENTRY_FLAG(URLDECODE )
19+
ENTRY_FLAG(URLENCODE )
20+
ENTRY_FLAG(APPENDQUERY )
21+
ENTRY_FLAG(GUESS_SCHEME )

src/lcurl.c

+13-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "lcerror.h"
1616
#include "lchttppost.h"
1717
#include "lcmime.h"
18+
#include "lcurlapi.h"
1819
#include "lcutils.h"
1920

2021
/*export*/
@@ -36,10 +37,14 @@ static int lcurl_share_new_safe(lua_State *L){
3637
return lcurl_share_create(L, LCURL_ERROR_RETURN);
3738
}
3839

39-
static int lcurl_hpost_new_safe(lua_State *L){
40+
static int lcurl_hpost_new_safe(lua_State *L) {
4041
return lcurl_hpost_create(L, LCURL_ERROR_RETURN);
4142
}
4243

44+
static int lcurl_url_new_safe(lua_State *L) {
45+
return lcurl_url_create(L, LCURL_ERROR_RETURN);
46+
}
47+
4348
static int lcurl_easy_new(lua_State *L){
4449
return lcurl_easy_create(L, LCURL_ERROR_RAISE);
4550
}
@@ -56,6 +61,10 @@ static int lcurl_hpost_new(lua_State *L){
5661
return lcurl_hpost_create(L, LCURL_ERROR_RAISE);
5762
}
5863

64+
static int lcurl_url_new(lua_State *L) {
65+
return lcurl_url_create(L, LCURL_ERROR_RAISE);
66+
}
67+
5968
static int lcurl_version(lua_State *L){
6069
lua_pushstring(L, curl_version());
6170
return 1;
@@ -170,6 +179,7 @@ static const struct luaL_Reg lcurl_functions[] = {
170179
{"easy", lcurl_easy_new },
171180
{"multi", lcurl_multi_new },
172181
{"share", lcurl_share_new },
182+
{"url", lcurl_url_new },
173183
{"version", lcurl_version },
174184
{"version_info", lcurl_version_info },
175185

@@ -182,6 +192,7 @@ static const struct luaL_Reg lcurl_functions_safe[] = {
182192
{"easy", lcurl_easy_new_safe },
183193
{"multi", lcurl_multi_new_safe },
184194
{"share", lcurl_share_new_safe },
195+
{"url", lcurl_url_new_safe },
185196
{"version", lcurl_version },
186197
{"version_info", lcurl_version_info },
187198

@@ -258,6 +269,7 @@ static int luaopen_lcurl_(lua_State *L, const struct luaL_Reg *func){
258269
LCURL_PUSH_NUP(L); lcurl_mime_initlib (L, NUP);
259270
LCURL_PUSH_NUP(L); lcurl_multi_initlib(L, NUP);
260271
LCURL_PUSH_NUP(L); lcurl_share_initlib(L, NUP);
272+
LCURL_PUSH_NUP(L); lcurl_url_initlib (L, NUP);
261273

262274
LCURL_PUSH_NUP(L);
263275

src/lcurlapi.c

+198
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
/******************************************************************************
2+
* Author: Alexey Melnichuk <[email protected]>
3+
*
4+
* Copyright (C) 2018 Alexey Melnichuk <[email protected]>
5+
*
6+
* Licensed according to the included 'LICENSE' document
7+
*
8+
* This file is part of lua-lcurl library.
9+
******************************************************************************/
10+
11+
#include "lcurlapi.h"
12+
#include "lcurl.h"
13+
#include "lcerror.h"
14+
#include "lcutils.h"
15+
#include <memory.h>
16+
17+
#define LCURL_URL_NAME LCURL_PREFIX" URL"
18+
static const char *LCURL_URL = LCURL_URL_NAME;
19+
20+
#if LCURL_CURL_VER_GE(7,62,0)
21+
22+
#define lcurl_geturl(L) lcurl_geturl_at(L, 1)
23+
24+
typedef struct lcurl_url_tag{
25+
CURLU *url;
26+
27+
int storage;
28+
int err_mode;
29+
}lcurl_url_t;
30+
31+
int lcurl_url_create(lua_State *L, int error_mode){
32+
lcurl_url_t *p;
33+
34+
p = lutil_newudatap(L, lcurl_url_t, LCURL_URL);
35+
36+
p->url = curl_url();
37+
if(!p->url) return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_URL, CURLUE_OUT_OF_MEMORY);
38+
39+
p->err_mode = error_mode;
40+
41+
if (lua_gettop(L) > 1) {
42+
const char *url = luaL_checkstring(L, 1);
43+
unsigned int flags = 0;
44+
CURLUcode code;
45+
46+
if (lua_gettop(L) > 2) {
47+
flags = (unsigned int)lutil_optint64(L, 2, 0);
48+
}
49+
50+
code = curl_url_set(p->url, CURLUPART_URL, url, flags);
51+
if (code != CURLUE_OK) {
52+
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_URL, code);
53+
}
54+
}
55+
56+
return 1;
57+
}
58+
59+
static lcurl_url_t *lcurl_geturl_at(lua_State *L, int i){
60+
lcurl_url_t *p = (lcurl_url_t *)lutil_checkudatap (L, i, LCURL_URL);
61+
luaL_argcheck (L, p != NULL, 1, LCURL_URL_NAME" object expected");
62+
return p;
63+
}
64+
65+
static int lcurl_url_cleanup(lua_State *L){
66+
lcurl_url_t *p = lcurl_geturl(L);
67+
68+
if (p->url){
69+
curl_url_cleanup(p->url);
70+
p->url = NULL;
71+
}
72+
73+
return 0;
74+
}
75+
76+
static int lcurl_url_dup(lua_State *L) {
77+
lcurl_url_t *r = lcurl_geturl(L);
78+
lcurl_url_t *p = lutil_newudatap(L, lcurl_url_t, LCURL_URL);
79+
80+
p->url = curl_url_dup(r->url);
81+
if (!p->url) return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_URL, CURLUE_OUT_OF_MEMORY);
82+
83+
p->err_mode = r->err_mode;
84+
85+
return 1;
86+
}
87+
88+
static int lcurl_url_set(lua_State *L, CURLUPart what){
89+
lcurl_url_t *p = lcurl_geturl(L);
90+
CURLUcode code;
91+
const char *part;
92+
unsigned int flags = 0;
93+
94+
luaL_argcheck(L, lua_type(L, 2) == LUA_TSTRING || lutil_is_null(L, 2), 2, "string expected");
95+
96+
part = lua_tostring(L, 2);
97+
flags = (unsigned int)lutil_optint64(L, 3, 0);
98+
99+
code = curl_url_set(p->url, what, part, flags);
100+
if (code != CURLUE_OK) {
101+
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_URL, code);
102+
}
103+
104+
lua_settop(L, 1);
105+
return 1;
106+
}
107+
108+
static int lcurl_url_get(lua_State *L, CURLUPart what, CURLUcode empty) {
109+
lcurl_url_t *p = lcurl_geturl(L);
110+
CURLUcode code;
111+
char *part = NULL;
112+
unsigned int flags = 0;
113+
114+
flags = (unsigned int)lutil_optint64(L, 2, 0);
115+
116+
code = curl_url_get(p->url, what, &part, flags);
117+
if (code != CURLUE_OK) {
118+
if (part) {
119+
curl_free(part);
120+
part = NULL;
121+
}
122+
123+
if (code != empty) {
124+
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_URL, code);
125+
}
126+
}
127+
128+
if (part == NULL) {
129+
lutil_push_null(L);
130+
}
131+
else {
132+
lua_pushstring(L, part);
133+
curl_free(part);
134+
}
135+
136+
return 1;
137+
}
138+
139+
#define ENTRY_PART(N, S, E) static int lcurl_url_set_##N(lua_State *L){\
140+
return lcurl_url_set(L, CURL##S);\
141+
}
142+
#define ENTRY_FLAG(S)
143+
144+
#include "lcopturl.h"
145+
146+
#undef ENTRY_PART
147+
#undef ENTRY_FLAG
148+
149+
#define ENTRY_PART(N, S, E) static int lcurl_url_get_##N(lua_State *L){\
150+
return lcurl_url_get(L, CURL##S, E);\
151+
}
152+
#define ENTRY_FLAG(S)
153+
154+
#include "lcopturl.h"
155+
156+
#undef ENTRY_PART
157+
#undef ENTRY_FLAG
158+
159+
static const struct luaL_Reg lcurl_url_methods[] = {
160+
#define ENTRY_PART(N, S, E) { "set_"#N, lcurl_url_set_##N },
161+
#define ENTRY_FLAG(S)
162+
#include "lcopturl.h"
163+
#undef ENTRY_PART
164+
#undef ENTRY_FLAG
165+
166+
#define ENTRY_PART(N, S, E) { "get_"#N, lcurl_url_get_##N },
167+
#define ENTRY_FLAG(S)
168+
#include "lcopturl.h"
169+
#undef ENTRY_PART
170+
#undef ENTRY_FLAG
171+
172+
{ "dup", lcurl_url_dup },
173+
{ "cleanup", lcurl_url_cleanup },
174+
{ "__gc", lcurl_url_cleanup },
175+
{ "__tostring", lcurl_url_get_url },
176+
177+
{ NULL,NULL }
178+
};
179+
180+
static const lcurl_const_t lcurl_url_opt[] = {
181+
#define ENTRY_PART(N, S, E) { #S, CURL##S },
182+
#define ENTRY_FLAG(S) { "U_"#S, CURLU_##S },
183+
#include "lcopturl.h"
184+
#undef ENTRY_PART
185+
#undef ENTRY_FLAG
186+
{NULL, 0}
187+
};
188+
#endif
189+
190+
void lcurl_url_initlib(lua_State *L, int nup){
191+
#if LCURL_CURL_VER_GE(7,62,0)
192+
if(!lutil_createmetap(L, LCURL_URL, lcurl_url_methods, nup))
193+
lua_pop(L, nup);
194+
lua_pop(L, 1);
195+
196+
lcurl_util_set_const(L, lcurl_url_opt);
197+
#endif
198+
}

src/lcurlapi.h

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/******************************************************************************
2+
* Author: Alexey Melnichuk <[email protected]>
3+
*
4+
* Copyright (C) 2018 Alexey Melnichuk <[email protected]>
5+
*
6+
* Licensed according to the included 'LICENSE' document
7+
*
8+
* This file is part of lua-lcurl library.
9+
******************************************************************************/
10+
11+
#ifndef _LURL_H_
12+
#define _LURL_H_
13+
14+
#include "lcurl.h"
15+
#include "lcutils.h"
16+
#include <stdlib.h>
17+
18+
void lcurl_url_initlib(lua_State *L, int nup);
19+
20+
int lcurl_url_create(lua_State *L, int error_mode);
21+
22+
#endif

test/run.lua

+1
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@ require "test_easy"
2929
require "test_form"
3030
require "test_mime"
3131
require "test_curl"
32+
require "test_urlapi"
3233

3334
RUN()

0 commit comments

Comments
 (0)