Merge pull request #138 from moteus/url_api

Support URL API
This commit is contained in:
Alexey Melnichuk 2018-12-23 10:52:06 +03:00 committed by GitHub
commit c03bade35b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 551 additions and 4 deletions

View File

@ -35,6 +35,7 @@ target('test', install, function()
run_test('test_mime.lua') run_test('test_mime.lua')
run_test('test_multi_callback.lua') run_test('test_multi_callback.lua')
run_test('test_multi_nested_callback.lua') run_test('test_multi_nested_callback.lua')
run_test('test_urlapi.lua')
if not test_summary() then if not test_summary() then
quit("test fail") quit("test fail")

View File

@ -63,7 +63,8 @@ build = {
sources = { sources = {
"src/l52util.c", "src/lceasy.c", "src/lcerror.c", "src/l52util.c", "src/lceasy.c", "src/lcerror.c",
"src/lchttppost.c", "src/lcurl.c", "src/lcutils.c", "src/lchttppost.c", "src/lcurl.c", "src/lcutils.c",
"src/lcmulti.c", "src/lcshare.c","src/lcmime.c", "src/lcmulti.c", "src/lcshare.c", "src/lcmime.c",
"src/lcurlapi.c",
}, },
incdirs = { "$(CURL_INCDIR)" }, incdirs = { "$(CURL_INCDIR)" },
libdirs = { "$(CURL_LIBDIR)" } libdirs = { "$(CURL_LIBDIR)" }

20
src/lcerr_url.h Normal file
View File

@ -0,0 +1,20 @@
#if LCURL_CURL_VER_GE(7,61,0)
ERR_ENTRY ( BAD_HANDLE )
ERR_ENTRY ( BAD_PARTPOINTER )
ERR_ENTRY ( BAD_PORT_NUMBER )
ERR_ENTRY ( MALFORMED_INPUT )
ERR_ENTRY ( NO_FRAGMENT )
ERR_ENTRY ( NO_HOST )
ERR_ENTRY ( NO_OPTIONS )
ERR_ENTRY ( NO_PASSWORD )
ERR_ENTRY ( NO_PORT )
ERR_ENTRY ( NO_QUERY )
ERR_ENTRY ( NO_SCHEME )
ERR_ENTRY ( NO_USER )
ERR_ENTRY ( OK )
ERR_ENTRY ( OUT_OF_MEMORY )
ERR_ENTRY ( UNKNOWN_PART )
ERR_ENTRY ( UNSUPPORTED_SCHEME)
ERR_ENTRY ( URLDECODE )
ERR_ENTRY ( USER_NOT_ALLOWED )
#endif

View File

@ -20,6 +20,7 @@ static const char *LCURL_ERROR = LCURL_ERROR_NAME;
#define LCURL_ERROR_MULTI_NAME "CURL-MULTI" #define LCURL_ERROR_MULTI_NAME "CURL-MULTI"
#define LCURL_ERROR_SHARE_NAME "CURL-SHARE" #define LCURL_ERROR_SHARE_NAME "CURL-SHARE"
#define LCURL_ERROR_FORM_NAME "CURL-FORM" #define LCURL_ERROR_FORM_NAME "CURL-FORM"
#define LCURL_ERROR_URL_NAME "CURL-URL"
typedef struct lcurl_error_tag{ typedef struct lcurl_error_tag{
int tp; int tp;
@ -72,12 +73,24 @@ static const char* lcurl_err_form_mnemo(int err){
#undef ERR_ENTRY #undef ERR_ENTRY
} }
static const char* lcurl_err_url_mnemo(int err){
#define ERR_ENTRY(E) case CURLUE_##E: return #E;
switch (err){
#include "lcerr_url.h"
}
return "UNKNOWN";
#undef ERR_ENTRY
}
static const char* _lcurl_err_mnemo(int tp, int err){ static const char* _lcurl_err_mnemo(int tp, int err){
switch(tp){ switch(tp){
case LCURL_ERROR_EASY : return lcurl_err_easy_mnemo (err); case LCURL_ERROR_EASY : return lcurl_err_easy_mnemo (err);
case LCURL_ERROR_MULTI: return lcurl_err_multi_mnemo(err); case LCURL_ERROR_MULTI: return lcurl_err_multi_mnemo(err);
case LCURL_ERROR_SHARE: return lcurl_err_share_mnemo(err); case LCURL_ERROR_SHARE: return lcurl_err_share_mnemo(err);
case LCURL_ERROR_FORM : return lcurl_err_form_mnemo (err); case LCURL_ERROR_FORM : return lcurl_err_form_mnemo (err);
case LCURL_ERROR_URL : return lcurl_err_url_mnemo (err);
} }
assert(0); assert(0);
return "<UNSUPPORTED ERROR TYPE>"; return "<UNSUPPORTED ERROR TYPE>";
@ -89,6 +102,7 @@ static const char* _lcurl_err_msg(int tp, int err){
case LCURL_ERROR_MULTI: return curl_multi_strerror(err); case LCURL_ERROR_MULTI: return curl_multi_strerror(err);
case LCURL_ERROR_SHARE: return curl_share_strerror(err); case LCURL_ERROR_SHARE: return curl_share_strerror(err);
case LCURL_ERROR_FORM : return lcurl_err_form_mnemo(err); case LCURL_ERROR_FORM : return lcurl_err_form_mnemo(err);
case LCURL_ERROR_URL : return lcurl_err_url_mnemo(err);
} }
assert(0); assert(0);
return "<UNSUPPORTED ERROR TYPE>"; return "<UNSUPPORTED ERROR TYPE>";
@ -100,6 +114,7 @@ static const char* _lcurl_err_category_name(int tp){
(tp == LCURL_ERROR_MULTI) || (tp == LCURL_ERROR_MULTI) ||
(tp == LCURL_ERROR_SHARE) || (tp == LCURL_ERROR_SHARE) ||
(tp == LCURL_ERROR_FORM ) || (tp == LCURL_ERROR_FORM ) ||
(tp == LCURL_ERROR_URL ) ||
0 0
); );
@ -120,6 +135,10 @@ static const char* _lcurl_err_category_name(int tp){
static const char *name = LCURL_ERROR_FORM_NAME; static const char *name = LCURL_ERROR_FORM_NAME;
return name; return name;
} }
case LCURL_ERROR_URL: {
static const char *name = LCURL_ERROR_URL_NAME;
return name;
}
} }
assert(0); assert(0);
@ -147,6 +166,7 @@ int lcurl_error_create(lua_State *L, int error_type, int no){
(error_type == LCURL_ERROR_MULTI) || (error_type == LCURL_ERROR_MULTI) ||
(error_type == LCURL_ERROR_SHARE) || (error_type == LCURL_ERROR_SHARE) ||
(error_type == LCURL_ERROR_FORM ) || (error_type == LCURL_ERROR_FORM ) ||
(error_type == LCURL_ERROR_URL ) ||
0 0
); );
@ -233,6 +253,7 @@ static const int ERROR_CATEGORIES[] = {
LCURL_ERROR_MULTI, LCURL_ERROR_MULTI,
LCURL_ERROR_SHARE, LCURL_ERROR_SHARE,
LCURL_ERROR_FORM, LCURL_ERROR_FORM,
LCURL_ERROR_URL,
}; };
static const char* ERROR_CATEGORIES_NAME[] = { static const char* ERROR_CATEGORIES_NAME[] = {
@ -240,6 +261,7 @@ static const char* ERROR_CATEGORIES_NAME[] = {
LCURL_ERROR_MULTI_NAME, LCURL_ERROR_MULTI_NAME,
LCURL_ERROR_SHARE_NAME, LCURL_ERROR_SHARE_NAME,
LCURL_ERROR_FORM_NAME, LCURL_ERROR_FORM_NAME,
LCURL_ERROR_URL_NAME,
NULL NULL
}; };
@ -297,6 +319,10 @@ static const lcurl_const_t lcurl_error_codes[] = {
#define ERR_ENTRY(N) { "E_FORM_"#N, CURL_FORMADD_##N }, #define ERR_ENTRY(N) { "E_FORM_"#N, CURL_FORMADD_##N },
#include "lcerr_form.h" #include "lcerr_form.h"
#undef ERR_ENTRY
#define ERR_ENTRY(N) { "E_URL_"#N, CURLUE_##N },
#include "lcerr_url.h"
#undef ERR_ENTRY #undef ERR_ENTRY
{NULL, 0} {NULL, 0}

View File

@ -18,6 +18,7 @@
#define LCURL_ERROR_MULTI 2 #define LCURL_ERROR_MULTI 2
#define LCURL_ERROR_SHARE 3 #define LCURL_ERROR_SHARE 3
#define LCURL_ERROR_FORM 4 #define LCURL_ERROR_FORM 4
#define LCURL_ERROR_URL 5
#define LCURL_ERROR_RETURN 1 #define LCURL_ERROR_RETURN 1
#define LCURL_ERROR_RAISE 2 #define LCURL_ERROR_RAISE 2

21
src/lcopturl.h Normal file
View File

@ -0,0 +1,21 @@
ENTRY_PART(fragment, UPART_FRAGMENT , CURLUE_NO_FRAGMENT )
ENTRY_PART(host, UPART_HOST , CURLUE_NO_HOST )
ENTRY_PART(options, UPART_OPTIONS , CURLUE_NO_OPTIONS )
ENTRY_PART(password, UPART_PASSWORD , CURLUE_NO_PASSWORD )
ENTRY_PART(path, UPART_PATH , CURLUE_OK )
ENTRY_PART(port, UPART_PORT , CURLUE_NO_PORT )
ENTRY_PART(query, UPART_QUERY , CURLUE_NO_QUERY )
ENTRY_PART(scheme, UPART_SCHEME , CURLUE_NO_SCHEME )
ENTRY_PART(url, UPART_URL , CURLUE_OK )
ENTRY_PART(user, UPART_USER , CURLUE_NO_USER )
ENTRY_FLAG(DEFAULT_PORT )
ENTRY_FLAG(NO_DEFAULT_PORT )
ENTRY_FLAG(DEFAULT_SCHEME )
ENTRY_FLAG(NON_SUPPORT_SCHEME )
ENTRY_FLAG(PATH_AS_IS )
ENTRY_FLAG(DISALLOW_USER )
ENTRY_FLAG(URLDECODE )
ENTRY_FLAG(URLENCODE )
ENTRY_FLAG(APPENDQUERY )
ENTRY_FLAG(GUESS_SCHEME )

View File

@ -15,6 +15,7 @@
#include "lcerror.h" #include "lcerror.h"
#include "lchttppost.h" #include "lchttppost.h"
#include "lcmime.h" #include "lcmime.h"
#include "lcurlapi.h"
#include "lcutils.h" #include "lcutils.h"
/*export*/ /*export*/
@ -36,10 +37,18 @@ static int lcurl_share_new_safe(lua_State *L){
return lcurl_share_create(L, LCURL_ERROR_RETURN); return lcurl_share_create(L, LCURL_ERROR_RETURN);
} }
static int lcurl_hpost_new_safe(lua_State *L){ static int lcurl_hpost_new_safe(lua_State *L) {
return lcurl_hpost_create(L, LCURL_ERROR_RETURN); return lcurl_hpost_create(L, LCURL_ERROR_RETURN);
} }
#if LCURL_CURL_VER_GE(7,62,0)
static int lcurl_url_new_safe(lua_State *L) {
return lcurl_url_create(L, LCURL_ERROR_RETURN);
}
#endif
static int lcurl_easy_new(lua_State *L){ static int lcurl_easy_new(lua_State *L){
return lcurl_easy_create(L, LCURL_ERROR_RAISE); return lcurl_easy_create(L, LCURL_ERROR_RAISE);
} }
@ -56,6 +65,14 @@ static int lcurl_hpost_new(lua_State *L){
return lcurl_hpost_create(L, LCURL_ERROR_RAISE); return lcurl_hpost_create(L, LCURL_ERROR_RAISE);
} }
#if LCURL_CURL_VER_GE(7,62,0)
static int lcurl_url_new(lua_State *L) {
return lcurl_url_create(L, LCURL_ERROR_RAISE);
}
#endif
static int lcurl_version(lua_State *L){ static int lcurl_version(lua_State *L){
lua_pushstring(L, curl_version()); lua_pushstring(L, curl_version());
return 1; return 1;
@ -170,6 +187,9 @@ static const struct luaL_Reg lcurl_functions[] = {
{"easy", lcurl_easy_new }, {"easy", lcurl_easy_new },
{"multi", lcurl_multi_new }, {"multi", lcurl_multi_new },
{"share", lcurl_share_new }, {"share", lcurl_share_new },
#if LCURL_CURL_VER_GE(7,62,0)
{"url", lcurl_url_new },
#endif
{"version", lcurl_version }, {"version", lcurl_version },
{"version_info", lcurl_version_info }, {"version_info", lcurl_version_info },
@ -182,6 +202,9 @@ static const struct luaL_Reg lcurl_functions_safe[] = {
{"easy", lcurl_easy_new_safe }, {"easy", lcurl_easy_new_safe },
{"multi", lcurl_multi_new_safe }, {"multi", lcurl_multi_new_safe },
{"share", lcurl_share_new_safe }, {"share", lcurl_share_new_safe },
#if LCURL_CURL_VER_GE(7,62,0)
{"url", lcurl_url_new_safe },
#endif
{"version", lcurl_version }, {"version", lcurl_version },
{"version_info", lcurl_version_info }, {"version_info", lcurl_version_info },
@ -258,6 +281,7 @@ static int luaopen_lcurl_(lua_State *L, const struct luaL_Reg *func){
LCURL_PUSH_NUP(L); lcurl_mime_initlib (L, NUP); LCURL_PUSH_NUP(L); lcurl_mime_initlib (L, NUP);
LCURL_PUSH_NUP(L); lcurl_multi_initlib(L, NUP); LCURL_PUSH_NUP(L); lcurl_multi_initlib(L, NUP);
LCURL_PUSH_NUP(L); lcurl_share_initlib(L, NUP); LCURL_PUSH_NUP(L); lcurl_share_initlib(L, NUP);
LCURL_PUSH_NUP(L); lcurl_url_initlib (L, NUP);
LCURL_PUSH_NUP(L); LCURL_PUSH_NUP(L);

224
src/lcurlapi.c Normal file
View File

@ -0,0 +1,224 @@
/******************************************************************************
* Author: Alexey Melnichuk <mimir@newmail.ru>
*
* Copyright (C) 2018 Alexey Melnichuk <mimir@newmail.ru>
*
* Licensed according to the included 'LICENSE' document
*
* This file is part of lua-lcurl library.
******************************************************************************/
#include "lcurlapi.h"
#include "lcurl.h"
#include "lcerror.h"
#include "lcutils.h"
#include <memory.h>
#define LCURL_URL_NAME LCURL_PREFIX" URL"
static const char *LCURL_URL = LCURL_URL_NAME;
#if LCURL_CURL_VER_GE(7,62,0)
#define lcurl_geturl(L) lcurl_geturl_at(L, 1)
typedef struct lcurl_url_tag{
CURLU *url;
int err_mode;
}lcurl_url_t;
int lcurl_url_create(lua_State *L, int error_mode){
lcurl_url_t *p;
p = lutil_newudatap(L, lcurl_url_t, LCURL_URL);
p->url = curl_url();
if(!p->url) return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_URL, CURLUE_OUT_OF_MEMORY);
p->err_mode = error_mode;
if (lua_gettop(L) > 1) {
const char *url = luaL_checkstring(L, 1);
unsigned int flags = 0;
CURLUcode code;
if (lua_gettop(L) > 2) {
flags = (unsigned int)lutil_optint64(L, 2, 0);
}
code = curl_url_set(p->url, CURLUPART_URL, url, flags);
if (code != CURLUE_OK) {
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_URL, code);
}
}
return 1;
}
static lcurl_url_t *lcurl_geturl_at(lua_State *L, int i){
lcurl_url_t *p = (lcurl_url_t *)lutil_checkudatap (L, i, LCURL_URL);
luaL_argcheck (L, p != NULL, 1, LCURL_URL_NAME" object expected");
return p;
}
static int lcurl_url_cleanup(lua_State *L){
lcurl_url_t *p = lcurl_geturl(L);
if (p->url){
curl_url_cleanup(p->url);
p->url = NULL;
}
return 0;
}
static int lcurl_url_dup(lua_State *L) {
lcurl_url_t *r = lcurl_geturl(L);
lcurl_url_t *p = lutil_newudatap(L, lcurl_url_t, LCURL_URL);
p->url = curl_url_dup(r->url);
if (!p->url) return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_URL, CURLUE_OUT_OF_MEMORY);
p->err_mode = r->err_mode;
return 1;
}
static int lcurl_url_set(lua_State *L, CURLUPart what){
lcurl_url_t *p = lcurl_geturl(L);
CURLUcode code;
const char *part;
unsigned int flags = 0;
luaL_argcheck(L, lua_type(L, 2) == LUA_TSTRING || lutil_is_null(L, 2), 2, "string expected");
part = lua_tostring(L, 2);
flags = (unsigned int)lutil_optint64(L, 3, 0);
code = curl_url_set(p->url, what, part, flags);
if (code != CURLUE_OK) {
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_URL, code);
}
lua_settop(L, 1);
return 1;
}
static int lcurl_url_get(lua_State *L, CURLUPart what, CURLUcode empty) {
lcurl_url_t *p = lcurl_geturl(L);
CURLUcode code;
char *part = NULL;
unsigned int flags = 0;
flags = (unsigned int)lutil_optint64(L, 2, 0);
code = curl_url_get(p->url, what, &part, flags);
if (code != CURLUE_OK) {
if (part) {
curl_free(part);
part = NULL;
}
if (code != empty) {
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_URL, code);
}
}
if (part == NULL) {
lutil_push_null(L);
}
else {
lua_pushstring(L, part);
curl_free(part);
}
return 1;
}
static int lcurl_url_to_s(lua_State *L) {
lcurl_url_t *p = lcurl_geturl(L);
char *part = NULL;
CURLUcode code = curl_url_get(p->url, CURLUPART_URL, &part, 0);
if (code != CURLUE_OK) {
if (part) {
curl_free(part);
}
return lcurl_fail_ex(L, LCURL_ERROR_RAISE, LCURL_ERROR_URL, code);
}
if (part == NULL) {
lua_pushliteral(L, "");
}
else {
lua_pushstring(L, part);
curl_free(part);
}
return 1;
}
#define ENTRY_PART(N, S, E) static int lcurl_url_set_##N(lua_State *L){\
return lcurl_url_set(L, CURL##S);\
}
#define ENTRY_FLAG(S)
#include "lcopturl.h"
#undef ENTRY_PART
#undef ENTRY_FLAG
#define ENTRY_PART(N, S, E) static int lcurl_url_get_##N(lua_State *L){\
return lcurl_url_get(L, CURL##S, E);\
}
#define ENTRY_FLAG(S)
#include "lcopturl.h"
#undef ENTRY_PART
#undef ENTRY_FLAG
static const struct luaL_Reg lcurl_url_methods[] = {
#define ENTRY_PART(N, S, E) { "set_"#N, lcurl_url_set_##N },
#define ENTRY_FLAG(S)
#include "lcopturl.h"
#undef ENTRY_PART
#undef ENTRY_FLAG
#define ENTRY_PART(N, S, E) { "get_"#N, lcurl_url_get_##N },
#define ENTRY_FLAG(S)
#include "lcopturl.h"
#undef ENTRY_PART
#undef ENTRY_FLAG
{ "dup", lcurl_url_dup },
{ "cleanup", lcurl_url_cleanup },
{ "__gc", lcurl_url_cleanup },
{ "__tostring", lcurl_url_to_s },
{ NULL,NULL }
};
static const lcurl_const_t lcurl_url_opt[] = {
#define ENTRY_PART(N, S, E) { #S, CURL##S },
#define ENTRY_FLAG(S) { "U_"#S, CURLU_##S },
#include "lcopturl.h"
#undef ENTRY_PART
#undef ENTRY_FLAG
{NULL, 0}
};
#endif
void lcurl_url_initlib(lua_State *L, int nup){
#if LCURL_CURL_VER_GE(7,62,0)
if(!lutil_createmetap(L, LCURL_URL, lcurl_url_methods, nup))
lua_pop(L, nup);
lua_pop(L, 1);
lcurl_util_set_const(L, lcurl_url_opt);
#else
lua_pop(L, nup);
#endif
}

22
src/lcurlapi.h Normal file
View File

@ -0,0 +1,22 @@
/******************************************************************************
* Author: Alexey Melnichuk <mimir@newmail.ru>
*
* Copyright (C) 2018 Alexey Melnichuk <mimir@newmail.ru>
*
* Licensed according to the included 'LICENSE' document
*
* This file is part of lua-lcurl library.
******************************************************************************/
#ifndef _LURL_H_
#define _LURL_H_
#include "lcurl.h"
#include "lcutils.h"
#include <stdlib.h>
void lcurl_url_initlib(lua_State *L, int nup);
int lcurl_url_create(lua_State *L, int error_mode);
#endif

View File

@ -29,5 +29,6 @@ require "test_easy"
require "test_form" require "test_form"
require "test_mime" require "test_mime"
require "test_curl" require "test_curl"
require "test_urlapi"
RUN() RUN()

206
test/test_urlapi.lua Normal file
View File

@ -0,0 +1,206 @@
local lunit, RUN = lunit do
RUN = lunit and function()end or function ()
local res = lunit.run()
if res.errors + res.failed > 0 then
os.exit(-1)
end
return os.exit(0)
end
lunit = require "lunit"
end
local _, luacov = pcall(require, "luacov")
local TEST_CASE = assert(lunit.TEST_CASE)
local skip = lunit.skip or function() end
local curl = require "cURL"
local scurl = require "cURL.safe"
local utils = require "utils"
local tostring, pcall = tostring, pcall
local function skip_case(msg) return function() skip(msg) end end
local ENABLE = true
local _ENV = TEST_CASE'urlapi' if ENABLE then
if not curl.E_URL_OK then test = skip_case('URL API avaliable since libcurl 7.62.0') else
local it = setmetatable(_ENV or _M, {__call = function(self, describe, fn)
self["test " .. describe] = fn
end})
local url
local function U(u)
url = assert_userdata(curl.url())
assert_equal(url, url:set_url(u))
return url
end
function teardown()
if url then url:cleanup() end
url = nil
end
it('should export falgs', function()
assert_number(curl.U_DEFAULT_PORT )
assert_number(curl.U_NO_DEFAULT_PORT )
assert_number(curl.U_DEFAULT_SCHEME )
assert_number(curl.U_NON_SUPPORT_SCHEME )
assert_number(curl.U_PATH_AS_IS )
assert_number(curl.U_DISALLOW_USER )
assert_number(curl.U_URLDECODE )
assert_number(curl.U_URLENCODE )
assert_number(curl.U_APPENDQUERY )
assert_number(curl.U_GUESS_SCHEME )
end)
it('should export parts', function()
assert_number(curl.UPART_URL )
assert_number(curl.UPART_SCHEME )
assert_number(curl.UPART_USER )
assert_number(curl.UPART_PASSWORD )
assert_number(curl.UPART_OPTIONS )
assert_number(curl.UPART_HOST )
assert_number(curl.UPART_PORT )
assert_number(curl.UPART_PATH )
assert_number(curl.UPART_QUERY )
assert_number(curl.UPART_FRAGMENT )
end)
it('should export methods', function()
url = curl.url()
assert_function(url.dup )
assert_function(url.cleanup )
assert_function(url.set_url )
assert_function(url.set_scheme )
assert_function(url.set_user )
assert_function(url.set_password )
assert_function(url.set_options )
assert_function(url.set_host )
assert_function(url.set_port )
assert_function(url.set_path )
assert_function(url.set_query )
assert_function(url.set_fragment )
assert_function(url.get_url )
assert_function(url.get_scheme )
assert_function(url.get_user )
assert_function(url.get_password )
assert_function(url.get_options )
assert_function(url.get_host )
assert_function(url.get_port )
assert_function(url.get_path )
assert_function(url.get_query )
assert_function(url.get_fragment )
end)
it('create and cleanup', function()
url = assert_userdata(curl.url())
assert_nil(url:cleanup())
end)
it('constructor with parameters', function()
url = assert_userdata(curl.url('http://example.com/'))
assert_equal('http://example.com/', url:get_url())
url = assert_userdata(curl.url('example.com', curl.U_GUESS_SCHEME))
assert_equal('http://example.com/', url:get_url())
end)
it('dup url', function()
url = assert_userdata(curl.url('http://example.com/'))
local u2 = url:dup()
assert_not_equal(url, u2)
assert_equal('http://example.com/', u2:get_url())
assert_equal('http://example.com/', url:get_url())
url:cleanup()
url = u2
assert_equal('http://example.com/', url:get_url())
end)
it('should convert to string', function()
assert_equal('http://example.com/', tostring(U"http://example.com/"))
end)
it('should decode url', function()
url = U"http://example.com"
assert_equal('http', url:get_scheme())
assert_equal('example.com', url:get_host())
assert_equal('/', url:get_path())
end)
it('should cast scheme to lower case', function()
url = U"HTTP://Example.com"
assert_equal('http', url:get_scheme())
assert_equal('Example.com', url:get_host())
assert_equal('/', url:get_path())
assert_equal("http://Example.com/", url:get_url())
end)
it('should append query', function()
url = U"http://example.com"
assert_equal(url, url:set_query("a=hello world", curl.U_APPENDQUERY + curl.U_URLENCODE))
assert_equal(url, url:set_query("b=A&B", curl.U_APPENDQUERY + curl.U_URLENCODE))
assert_equal("http://example.com/?a=hello+world&b=A%26B", url:get_url())
end)
it('should append only one parameter in query per call', function()
url = U"http://example.com"
assert_equal(url, url:set_query("a=hello world&b=A&B", curl.U_APPENDQUERY + curl.U_URLENCODE))
assert_equal("http://example.com/?a=hello+world%26b=A%26B", url:get_url())
end)
it('should set encoded query', function()
url = U("http://example.com/?a=hello world&b=d")
assert_equal('a=hello world&b=d', url:get_query())
end)
it('should returns NULL as empty value', function()
url = curl.url()
assert_equal(curl.null, url:get_query())
assert_equal(curl.null, url:get_host())
assert_equal(curl.null, url:get_port())
assert_equal(curl.null, url:get_password())
assert_equal(curl.null, url:get_scheme())
assert_equal(curl.null, url:get_options())
assert_equal(curl.null, url:get_fragment())
assert_equal('/', url:get_path())
end)
it('should returns nil and error for invalid url in safe mode', function()
url = scurl.url()
local _, err = assert_nil(url:get_url())
assert_equal('CURL-URL', err:cat())
end)
it('should raise error for invalid url', function()
url = curl.url()
local _, err = assert_false(pcall(url.get_url, url))
assert_match('CURL%-URL', tostring(err))
end)
it('should raise error for tostring', function()
url = curl.url()
local _, err = assert_false(pcall(tostring, url))
assert_match('CURL%-URL', tostring(err))
end)
it('should raise error for tostring in safe mode', function()
url = scurl.url()
local _, err = assert_false(pcall(tostring, url))
assert_match('CURL%-URL', tostring(err))
end)
-- it('should set encoded query', function()
-- url = U"http://example.com"
-- assert_equal(url, url:set_query("a=hello world", curl.U_URLENCODE))
-- assert_equal("http://example.com/?a=hello+world", url:get_url())
-- end)
end end
RUN()