Lua-cURLv3/src/lcurlapi.c
2018-11-04 14:15:41 +03:00

199 lines
4.5 KiB
C

/******************************************************************************
* 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 storage;
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;
}
#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_get_url },
{ 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);
#endif
}