Init commit
This commit is contained in:
parent
5458154562
commit
b46fc0ad25
60
README.md
Normal file
60
README.md
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
# Lua binding to [libcurl](http://curl.haxx.se/libcurl)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```Lua
|
||||||
|
-- HTTP Get
|
||||||
|
curl:easy()
|
||||||
|
:setopt_url('http://httpbin.org/get')
|
||||||
|
:setopt_httpheader{
|
||||||
|
"X-Test-Header1: Header-Data1",
|
||||||
|
"X-Test-Header2: Header-Data2",
|
||||||
|
}
|
||||||
|
:setopt_writefunction(io.stderr)
|
||||||
|
:perform()
|
||||||
|
:close()
|
||||||
|
```
|
||||||
|
|
||||||
|
```Lua
|
||||||
|
-- HTTP Post
|
||||||
|
curl:easy()
|
||||||
|
:setopt_url('http://posttestserver.com/post.php')
|
||||||
|
:setopt_writefunction(io.write)
|
||||||
|
:setopt_httppost(curl.httppost()
|
||||||
|
:add_content("test_content", "some data", {
|
||||||
|
"MyHeader: SomeValue"
|
||||||
|
})
|
||||||
|
:add_buffer("test_file", "filename", "text data", "text/plain", {
|
||||||
|
"Description: my file description"
|
||||||
|
})
|
||||||
|
:add_file("test_file2", "BuildLog.htm", "application/octet-stream", {
|
||||||
|
"Description: my file description"
|
||||||
|
})
|
||||||
|
)
|
||||||
|
:perform()
|
||||||
|
:close()
|
||||||
|
```
|
||||||
|
|
||||||
|
```Lua
|
||||||
|
-- FTP Upload
|
||||||
|
local function get_bin_by(str,n)
|
||||||
|
local pos = 1 - n
|
||||||
|
return function()
|
||||||
|
pos = pos + n
|
||||||
|
return (str:sub(pos,pos+n-1))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
curl:easy()
|
||||||
|
:setopt_url("ftp://moteus:123456@127.0.0.1/test.dat")
|
||||||
|
:setopt_upload(true)
|
||||||
|
:setopt_readfunction(
|
||||||
|
get_bin_by(("0123456789"):rep(4), 9)
|
||||||
|
)
|
||||||
|
:perform()
|
||||||
|
:close()
|
||||||
|
|
||||||
|
```
|
||||||
|
|
145
doc/lcurl.ldoc
Normal file
145
doc/lcurl.ldoc
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
---
|
||||||
|
-- @module lcurl
|
||||||
|
|
||||||
|
|
||||||
|
--- Create HTTP multipart object.
|
||||||
|
--
|
||||||
|
-- @treturn[1] httppost new curl HTTP Post object context
|
||||||
|
function httppost() end
|
||||||
|
|
||||||
|
|
||||||
|
--- HTTP multipart/formdata object
|
||||||
|
-- @type httppost
|
||||||
|
--
|
||||||
|
do
|
||||||
|
|
||||||
|
--- Add new part to form.
|
||||||
|
--
|
||||||
|
-- @tparam string name provide the name of this part
|
||||||
|
-- @tparam string content actual data to send
|
||||||
|
-- @tparam[opt] string type provides the content-type for this part
|
||||||
|
-- @tparam[opt] table headers specifies extra headers for the form POST section
|
||||||
|
-- @return[1] self
|
||||||
|
function httppost:add_content() end
|
||||||
|
|
||||||
|
--- Add new part to form.
|
||||||
|
--
|
||||||
|
-- @tparam string name provide the name of this part
|
||||||
|
-- @tparam string filename provides the filename field in the content header
|
||||||
|
-- @tparam string content actual data to send
|
||||||
|
-- @tparam[opt] string type provides the content-type for this part
|
||||||
|
-- @tparam[opt] table headers specifies extra headers for the form POST section
|
||||||
|
-- @return[1] self
|
||||||
|
function httppost:add_buffer() end
|
||||||
|
|
||||||
|
--- Add new part to form.
|
||||||
|
--
|
||||||
|
-- @tparam string name provide the name of this part
|
||||||
|
-- @tparam string path path to file that contain actual data to send
|
||||||
|
-- @tparam[opt] string type provides the content-type for this part
|
||||||
|
-- @tparam[opt] string filename provides the filename field in the content header.
|
||||||
|
-- By default it is basename of path.
|
||||||
|
-- @tparam[opt] table headers specifies extra headers for the form POST section
|
||||||
|
-- @return[1] self
|
||||||
|
function httppost:add_file() end
|
||||||
|
|
||||||
|
--- Serialize multipart/formdata HTTP POST chain.
|
||||||
|
--
|
||||||
|
-- @return[1] string serialized data
|
||||||
|
--
|
||||||
|
-- @usage print(post:get())
|
||||||
|
--
|
||||||
|
function httppost:get() end
|
||||||
|
|
||||||
|
--- Serialize multipart/formdata HTTP POST chain.
|
||||||
|
--
|
||||||
|
-- Writer function can return true or number of written bytes.
|
||||||
|
-- Also if function does not return anything is considered as success.
|
||||||
|
--
|
||||||
|
-- @tparam function writer
|
||||||
|
-- @param[opt] context writer context
|
||||||
|
-- @return[1] self
|
||||||
|
--
|
||||||
|
-- @usage
|
||||||
|
-- t = {}
|
||||||
|
-- post:get(table.insert, t)
|
||||||
|
-- print(table.concat(t))
|
||||||
|
--
|
||||||
|
function httppost:get() end
|
||||||
|
|
||||||
|
--- Serialize multipart/formdata HTTP POST chain.
|
||||||
|
--
|
||||||
|
-- This call same as httppost:get(writer.write, writer)
|
||||||
|
--
|
||||||
|
-- @tparam object writer
|
||||||
|
-- @return[1] self
|
||||||
|
--
|
||||||
|
-- @usage
|
||||||
|
-- f = io.open(...)
|
||||||
|
-- post:get(f)
|
||||||
|
--
|
||||||
|
function httppost:get() end
|
||||||
|
|
||||||
|
--- Free multipart/formdata.
|
||||||
|
--
|
||||||
|
function httppost:free() end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Easy curl object
|
||||||
|
-- @type easy
|
||||||
|
--
|
||||||
|
do
|
||||||
|
|
||||||
|
--- Set writer function.
|
||||||
|
--
|
||||||
|
-- @tparam function writer
|
||||||
|
-- @param[opt] context writer context
|
||||||
|
-- @return[1] self
|
||||||
|
--
|
||||||
|
function easy:setopt_writefunction() end
|
||||||
|
|
||||||
|
--- Set writer function.
|
||||||
|
--
|
||||||
|
-- This call same as easy:set_writefunction(writer.write, writer)
|
||||||
|
--
|
||||||
|
-- @tparam object writer
|
||||||
|
-- @return[1] self
|
||||||
|
--
|
||||||
|
function easy:setopt_writefunction() end
|
||||||
|
|
||||||
|
--- Set reader function.
|
||||||
|
--
|
||||||
|
-- @tparam function reader
|
||||||
|
-- @param[opt] context reader context
|
||||||
|
-- @return[1] self
|
||||||
|
--
|
||||||
|
function easy:setopt_readfunction() end
|
||||||
|
|
||||||
|
--- Set reader function.
|
||||||
|
--
|
||||||
|
-- This call same as easy:set_readfunction(reader.read, reader)
|
||||||
|
--
|
||||||
|
-- @tparam object reader
|
||||||
|
-- @return[1] self
|
||||||
|
--
|
||||||
|
function easy:setopt_readfunction() end
|
||||||
|
|
||||||
|
--- Set HTTP multipart/formdata
|
||||||
|
--
|
||||||
|
-- @tparam httppost data
|
||||||
|
-- @return[1] self
|
||||||
|
function easy:setopt_httppost() end
|
||||||
|
|
||||||
|
--- Set HTTP multipart/formdata
|
||||||
|
--
|
||||||
|
-- @tparam string data
|
||||||
|
-- @tparam[opt=#data] number length
|
||||||
|
-- @return[1] self
|
||||||
|
function easy:setopt_postfields() end
|
||||||
|
|
||||||
|
--- End easy session
|
||||||
|
--
|
||||||
|
function easy:close() end
|
||||||
|
|
||||||
|
end
|
20
msvc/lcurl.sln
Normal file
20
msvc/lcurl.sln
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||||
|
# Visual Studio 2008
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lcurl", "lcurl.vcproj", "{200D5C0C-8123-48F6-9EA0-CF0E6A6943F2}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Win32 = Debug|Win32
|
||||||
|
Release|Win32 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{200D5C0C-8123-48F6-9EA0-CF0E6A6943F2}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
|
{200D5C0C-8123-48F6-9EA0-CF0E6A6943F2}.Debug|Win32.Build.0 = Debug|Win32
|
||||||
|
{200D5C0C-8123-48F6-9EA0-CF0E6A6943F2}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
|
{200D5C0C-8123-48F6-9EA0-CF0E6A6943F2}.Release|Win32.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
240
msvc/lcurl.vcproj
Normal file
240
msvc/lcurl.vcproj
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
<?xml version="1.0" encoding="windows-1251"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="9.00"
|
||||||
|
Name="lcurl"
|
||||||
|
ProjectGUID="{200D5C0C-8123-48F6-9EA0-CF0E6A6943F2}"
|
||||||
|
RootNamespace="lcurl"
|
||||||
|
Keyword="Win32Proj"
|
||||||
|
TargetFrameworkVersion="196613"
|
||||||
|
>
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"
|
||||||
|
/>
|
||||||
|
</Platforms>
|
||||||
|
<ToolFiles>
|
||||||
|
</ToolFiles>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="$(CPPLIB_DIR)\curl\7.37.1\include;$(LUA_DIR)\include"
|
||||||
|
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;LCURL_EXPORTS"
|
||||||
|
MinimalRebuild="true"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="3"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="4"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
AdditionalDependencies="lua5.1.lib libcurl.lib"
|
||||||
|
LinkIncremental="2"
|
||||||
|
AdditionalLibraryDirectories=""$(CPPLIB_DIR)\curl\7.37.1\lib";"$(LUA_DIR)\lib""
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||||
|
IntermediateDirectory="$(ConfigurationName)"
|
||||||
|
ConfigurationType="2"
|
||||||
|
CharacterSet="1"
|
||||||
|
WholeProgramOptimization="1"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="2"
|
||||||
|
EnableIntrinsicFunctions="true"
|
||||||
|
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;LCURL_EXPORTS"
|
||||||
|
RuntimeLibrary="2"
|
||||||
|
EnableFunctionLevelLinking="true"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
DebugInformationFormat="3"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
LinkIncremental="1"
|
||||||
|
GenerateDebugInformation="true"
|
||||||
|
SubSystem="2"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCALinkTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManifestTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXDCMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCBscMakeTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCFxCopTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAppVerifierTool"
|
||||||
|
/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"
|
||||||
|
/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\l52util.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\lceasy.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\lcerror.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\lchttppost.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\lcurl.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\lcutils.c"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<Filter
|
||||||
|
Name="Resource Files"
|
||||||
|
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||||
|
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||||
|
>
|
||||||
|
</Filter>
|
||||||
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Header Files"
|
||||||
|
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||||
|
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\l52util.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\lceasy.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\lcerror.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\lchttppost.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\lcurl.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\src\lcutils.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
147
src/l52util.c
Normal file
147
src/l52util.c
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
#include "l52util.h"
|
||||||
|
|
||||||
|
#include <memory.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#if LUA_VERSION_NUM >= 502
|
||||||
|
|
||||||
|
int luaL_typerror (lua_State *L, int narg, const char *tname) {
|
||||||
|
const char *msg = lua_pushfstring(L, "%s expected, got %s", tname,
|
||||||
|
luaL_typename(L, narg));
|
||||||
|
return luaL_argerror(L, narg, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef luaL_register
|
||||||
|
|
||||||
|
void luaL_register (lua_State *L, const char *libname, const luaL_Reg *l){
|
||||||
|
if(libname) lua_newtable(L);
|
||||||
|
luaL_setfuncs(L, l, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup){
|
||||||
|
luaL_checkstack(L, nup, "too many upvalues");
|
||||||
|
for (; l->name != NULL; l++) { /* fill the table with given functions */
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < nup; i++) /* copy upvalues to the top */
|
||||||
|
lua_pushvalue(L, -nup);
|
||||||
|
lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */
|
||||||
|
lua_setfield(L, -(nup + 2), l->name);
|
||||||
|
}
|
||||||
|
lua_pop(L, nup); /* remove upvalues */
|
||||||
|
}
|
||||||
|
|
||||||
|
void lua_rawgetp(lua_State *L, int index, const void *p){
|
||||||
|
index = lua_absindex(L, index);
|
||||||
|
lua_pushlightuserdata(L, (void *)p);
|
||||||
|
lua_rawget(L, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lua_rawsetp (lua_State *L, int index, const void *p){
|
||||||
|
index = lua_absindex(L, index);
|
||||||
|
lua_pushlightuserdata(L, (void *)p);
|
||||||
|
lua_insert(L, -2);
|
||||||
|
lua_rawset(L, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
int luaL_getmetafield (lua_State *L, int obj, const char *event) {
|
||||||
|
if (!lua_getmetatable(L, obj)) /* no metatable? */
|
||||||
|
return 0;
|
||||||
|
lua_pushstring(L, event);
|
||||||
|
lua_rawget(L, -2);
|
||||||
|
if (lua_isnil(L, -1)) {
|
||||||
|
lua_pop(L, 2); /* remove metatable and metafield */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lua_remove(L, -2); /* remove only metatable */
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int luaL_callmeta (lua_State *L, int obj, const char *event) {
|
||||||
|
obj = lua_absindex(L, obj);
|
||||||
|
if (!luaL_getmetafield(L, obj, event)) /* no metafield? */
|
||||||
|
return 0;
|
||||||
|
lua_pushvalue(L, obj);
|
||||||
|
lua_call(L, 1, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int lutil_newmetatablep (lua_State *L, const void *p) {
|
||||||
|
lua_rawgetp(L, LUA_REGISTRYINDEX, p);
|
||||||
|
if (!lua_isnil(L, -1)) /* name already in use? */
|
||||||
|
return 0; /* leave previous value on top, but return 0 */
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
lua_newtable(L); /* create metatable */
|
||||||
|
lua_pushvalue(L, -1); /* duplicate metatable to set*/
|
||||||
|
lua_rawsetp(L, LUA_REGISTRYINDEX, p);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lutil_getmetatablep (lua_State *L, const void *p) {
|
||||||
|
lua_rawgetp(L, LUA_REGISTRYINDEX, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lutil_setmetatablep (lua_State *L, const void *p) {
|
||||||
|
lutil_getmetatablep(L, p);
|
||||||
|
assert(lua_istable(L,-1));
|
||||||
|
lua_setmetatable (L, -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int lutil_isudatap (lua_State *L, int ud, const void *p) {
|
||||||
|
if (lua_isuserdata(L, ud)){
|
||||||
|
if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
|
||||||
|
int res;
|
||||||
|
lutil_getmetatablep(L,p); /* get correct metatable */
|
||||||
|
res = lua_rawequal(L, -1, -2); /* does it have the correct mt? */
|
||||||
|
lua_pop(L, 2); /* remove both metatables */
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *lutil_checkudatap (lua_State *L, int ud, const void *p) {
|
||||||
|
void *up = lua_touserdata(L, ud);
|
||||||
|
if (up != NULL) { /* value is a userdata? */
|
||||||
|
if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
|
||||||
|
lutil_getmetatablep(L,p); /* get correct metatable */
|
||||||
|
if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
|
||||||
|
lua_pop(L, 2); /* remove both metatables */
|
||||||
|
return up;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
luaL_typerror(L, ud, p); /* else error */
|
||||||
|
return NULL; /* to avoid warnings */
|
||||||
|
}
|
||||||
|
|
||||||
|
int lutil_createmetap (lua_State *L, const void *p, const luaL_Reg *methods, int nup) {
|
||||||
|
if (!lutil_newmetatablep(L, p)){
|
||||||
|
lua_insert(L, -1 - nup); /* move mt prior upvalues */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_insert(L, -1 - nup); /* move mt prior upvalues */
|
||||||
|
luaL_setfuncs (L, methods, nup); /* define methods */
|
||||||
|
lua_pushliteral (L, "__index"); /* define metamethods */
|
||||||
|
lua_pushvalue (L, -2);
|
||||||
|
lua_settable (L, -3);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *lutil_newudatap_impl(lua_State *L, size_t size, const void *p){
|
||||||
|
void *obj = lua_newuserdata (L, size);
|
||||||
|
memset(obj, 0, size);
|
||||||
|
lutil_setmetatablep(L, p);
|
||||||
|
return obj;
|
||||||
|
}
|
55
src/l52util.h
Normal file
55
src/l52util.h
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#ifndef _L52UTIL_H_
|
||||||
|
#define _L52UTIL_H_
|
||||||
|
|
||||||
|
#include "lua.h"
|
||||||
|
#include "lauxlib.h"
|
||||||
|
|
||||||
|
#if LUA_VERSION_NUM >= 502 // lua 5.2
|
||||||
|
|
||||||
|
// lua_rawgetp
|
||||||
|
// lua_rawsetp
|
||||||
|
// luaL_setfuncs
|
||||||
|
// lua_absindex
|
||||||
|
#ifndef lua_objlen
|
||||||
|
|
||||||
|
#define lua_objlen lua_rawlen
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int luaL_typerror (lua_State *L, int narg, const char *tname);
|
||||||
|
|
||||||
|
#ifndef luaL_register
|
||||||
|
|
||||||
|
void luaL_register (lua_State *L, const char *libname, const luaL_Reg *l);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else // lua 5.1
|
||||||
|
|
||||||
|
// functions form lua 5.2
|
||||||
|
|
||||||
|
# define lua_absindex(L, i) (((i)>0)?(i):((i)<=LUA_REGISTRYINDEX?(i):(lua_gettop(L)+(i)+1)))
|
||||||
|
# define lua_rawlen lua_objlen
|
||||||
|
|
||||||
|
void lua_rawgetp (lua_State *L, int index, const void *p);
|
||||||
|
void lua_rawsetp (lua_State *L, int index, const void *p);
|
||||||
|
void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup);
|
||||||
|
|
||||||
|
int luaL_getmetafield (lua_State *L, int obj, const char *event);
|
||||||
|
int luaL_callmeta (lua_State *L, int obj, const char *event);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int lutil_newmetatablep (lua_State *L, const void *p);
|
||||||
|
void lutil_getmetatablep (lua_State *L, const void *p);
|
||||||
|
void lutil_setmetatablep (lua_State *L, const void *p);
|
||||||
|
|
||||||
|
#define lutil_newudatap(L, TTYPE, TNAME) (TTYPE *)lutil_newudatap_impl(L, sizeof(TTYPE), TNAME)
|
||||||
|
int lutil_isudatap (lua_State *L, int ud, const void *p);
|
||||||
|
void *lutil_checkudatap (lua_State *L, int ud, const void *p);
|
||||||
|
int lutil_createmetap (lua_State *L, const void *p, const luaL_Reg *methods, int nup);
|
||||||
|
|
||||||
|
void *lutil_newudatap_impl (lua_State *L, size_t size, const void *p);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
569
src/lceasy.c
Normal file
569
src/lceasy.c
Normal file
@ -0,0 +1,569 @@
|
|||||||
|
#include "lcurl.h"
|
||||||
|
#include "lceasy.h"
|
||||||
|
#include "lcerror.h"
|
||||||
|
#include "lcutils.h"
|
||||||
|
#include "lchttppost.h"
|
||||||
|
|
||||||
|
#define LCURL_EASY_NAME LCURL_PREFIX" Easy"
|
||||||
|
static const char *LCURL_EASY = LCURL_EASY_NAME;
|
||||||
|
|
||||||
|
typedef struct lcurl_callback_tag{
|
||||||
|
int cb_ref;
|
||||||
|
int ud_ref;
|
||||||
|
}lcurl_callback_t;
|
||||||
|
|
||||||
|
typedef struct lcurl_read_buffer_tag{
|
||||||
|
int ref;
|
||||||
|
int off;
|
||||||
|
}lcurl_read_buffer_t;
|
||||||
|
|
||||||
|
|
||||||
|
#define LCURL_LST_INDEX(N) LCURL_##N##_LIST,
|
||||||
|
#define LCURL_STR_INDEX(N)
|
||||||
|
#define LCURL_LNG_INDEX(N)
|
||||||
|
#define OPT_ENTRY(L, N, T, S) LCURL_##T##_INDEX(N)
|
||||||
|
|
||||||
|
enum {
|
||||||
|
LCURL_LISY_DUMMY = -1,
|
||||||
|
|
||||||
|
#include"lcopteasy.h"
|
||||||
|
|
||||||
|
LCURL_LIST_COUNT,
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef LCURL_LST_INDEX
|
||||||
|
#undef LCURL_STR_INDEX
|
||||||
|
#undef LCURL_LNG_INDEX
|
||||||
|
#undef OPT_ENTRY
|
||||||
|
|
||||||
|
typedef struct lcurl_easy_tag{
|
||||||
|
lua_State *L;
|
||||||
|
CURL *curl;
|
||||||
|
int storage;
|
||||||
|
int lists[LCURL_LIST_COUNT];
|
||||||
|
int err_mode;
|
||||||
|
lcurl_callback_t wr;
|
||||||
|
lcurl_callback_t rd;
|
||||||
|
lcurl_read_buffer_t rbuffer;
|
||||||
|
|
||||||
|
}lcurl_easy_t;
|
||||||
|
|
||||||
|
//{
|
||||||
|
|
||||||
|
int lcurl_easy_create(lua_State *L, int error_mode){
|
||||||
|
lcurl_easy_t *p = lutil_newudatap(L, lcurl_easy_t, LCURL_EASY);
|
||||||
|
int i;
|
||||||
|
p->L = L;
|
||||||
|
p->curl = curl_easy_init();
|
||||||
|
if(!p->curl) return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, CURLE_FAILED_INIT);
|
||||||
|
p->storage = lcurl_storage_init(L);
|
||||||
|
p->err_mode = error_mode;
|
||||||
|
p->wr.cb_ref = p->wr.ud_ref = LUA_NOREF;
|
||||||
|
p->rd.cb_ref = p->rd.ud_ref = LUA_NOREF;
|
||||||
|
p->rbuffer.ref = LUA_NOREF;
|
||||||
|
for(i = 0; i < LCURL_LIST_COUNT; ++i){
|
||||||
|
p->lists[i] = LUA_NOREF;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static lcurl_easy_t *lcurl_geteasy_at(lua_State *L, int i){
|
||||||
|
lcurl_easy_t *p = (lcurl_easy_t *)lutil_checkudatap (L, i, LCURL_EASY);
|
||||||
|
luaL_argcheck (L, p != NULL, 1, LCURL_PREFIX"HTTPPost object expected");
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define lcurl_geteasy(L) lcurl_geteasy_at((L),1)
|
||||||
|
|
||||||
|
static int lcurl_easy_cleanup(lua_State *L){
|
||||||
|
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||||
|
if(p->curl){
|
||||||
|
curl_easy_cleanup(p->curl);
|
||||||
|
p->curl = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(p->storage != LUA_NOREF){
|
||||||
|
lcurl_storage_free(L, p->storage);
|
||||||
|
p->storage = LUA_NOREF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_easy_perform(lua_State *L){
|
||||||
|
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||||
|
CURLcode code;
|
||||||
|
lua_settop(L, 1);
|
||||||
|
|
||||||
|
assert(p->rbuffer.ref == LUA_NOREF);
|
||||||
|
|
||||||
|
code = curl_easy_perform(p->curl);
|
||||||
|
|
||||||
|
if(p->rbuffer.ref != LUA_NOREF){
|
||||||
|
luaL_unref(L, LCURL_LUA_REGISTRY, p->rbuffer.ref);
|
||||||
|
p->rbuffer.ref = LUA_NOREF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(code == CURLE_OK){
|
||||||
|
lua_settop(L, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(code == CURLE_WRITE_ERROR){
|
||||||
|
/* error from callback*/
|
||||||
|
if(lua_gettop(L) > 1){
|
||||||
|
if(lua_isstring(L, 2)) return lua_error(L);
|
||||||
|
return lua_gettop(L) - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(code == CURLE_ABORTED_BY_CALLBACK){
|
||||||
|
if(lua_gettop(L) > 1){
|
||||||
|
if(lua_isstring(L, 2)) return lua_error(L);
|
||||||
|
return lua_gettop(L) - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
//{ OPTIONS
|
||||||
|
|
||||||
|
static int lcurl_opt_set_long_(lua_State *L, int opt){
|
||||||
|
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||||
|
long val; CURLcode code;
|
||||||
|
|
||||||
|
if(lua_isboolean(L, 2)) val = lua_toboolean(L, 2);
|
||||||
|
else val = luaL_checklong(L, 2);
|
||||||
|
|
||||||
|
code = curl_easy_setopt(p->curl, opt, val);
|
||||||
|
if(code != CURLE_OK){
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||||
|
}
|
||||||
|
lua_settop(L, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_opt_set_string_(lua_State *L, int opt, int store){
|
||||||
|
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||||
|
const char *val = luaL_checkstring(L, 2);
|
||||||
|
CURLcode code = curl_easy_setopt(p->curl, opt, val);
|
||||||
|
if(code != CURLE_OK){
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||||
|
}
|
||||||
|
if(store)lcurl_storage_preserve_value(L, p->storage, 2);
|
||||||
|
lua_settop(L, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_opt_set_slist_(lua_State *L, int opt, int list_no){
|
||||||
|
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||||
|
struct curl_slist *list = lcurl_util_to_slist(L, 2);
|
||||||
|
CURLcode code;
|
||||||
|
int ref = p->lists[list_no];
|
||||||
|
|
||||||
|
luaL_argcheck(L, list, 2, "array expected");
|
||||||
|
|
||||||
|
if(ref != LUA_NOREF){
|
||||||
|
struct curl_slist *tmp = lcurl_storage_remove_slist(L, p->storage, ref);
|
||||||
|
curl_slist_free_all(tmp);
|
||||||
|
p->lists[list_no] = LUA_NOREF;
|
||||||
|
}
|
||||||
|
|
||||||
|
code = curl_easy_setopt(p->curl, opt, list);
|
||||||
|
|
||||||
|
if(code != CURLE_OK){
|
||||||
|
curl_slist_free_all(list);
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
p->lists[list_no] = lcurl_storage_preserve_slist(L, p->storage, list);
|
||||||
|
lua_settop(L, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LCURL_STR_OPT(N, S) static int lcurl_easy_set_##N(lua_State *L){\
|
||||||
|
return lcurl_opt_set_string_(L, CURLOPT_##N, (S)); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LCURL_LST_OPT(N, S) static int lcurl_easy_set_##N(lua_State *L){\
|
||||||
|
return lcurl_opt_set_slist_(L, CURLOPT_##N, LCURL_##N##_LIST);\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LCURL_LNG_OPT(N, S) static int lcurl_easy_set_##N(lua_State *L){\
|
||||||
|
return lcurl_opt_set_long_(L, CURLOPT_##N);\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OPT_ENTRY(L, N, T, S) LCURL_##T##_OPT(N, S)
|
||||||
|
|
||||||
|
#include "lcopteasy.h"
|
||||||
|
|
||||||
|
#undef OPT_ENTRY
|
||||||
|
|
||||||
|
static int lcurl_easy_set_POSTFIELDS(lua_State *L){
|
||||||
|
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||||
|
size_t len; const char *val = luaL_checklstring(L, 2, &len);
|
||||||
|
CURLcode code;
|
||||||
|
if(lua_isnumber(L, 3)){
|
||||||
|
size_t n = (size_t)lua_tonumber(L, 3);
|
||||||
|
luaL_argcheck(L, len <= n, 3, "data length too big");
|
||||||
|
len = n;
|
||||||
|
}
|
||||||
|
code = curl_easy_setopt(p->curl, CURLOPT_POSTFIELDS, val);
|
||||||
|
if(code != CURLE_OK){
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||||
|
}
|
||||||
|
lcurl_storage_preserve_value(L, p->storage, 2);
|
||||||
|
code = curl_easy_setopt(p->curl, CURLOPT_POSTFIELDSIZE, (long)len);
|
||||||
|
if(code != CURLE_OK){
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||||
|
}
|
||||||
|
lua_settop(L, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef LCURL_STR_OPT
|
||||||
|
#undef LCURL_LST_OPT
|
||||||
|
#undef LCURL_LNG_OPT
|
||||||
|
|
||||||
|
static int lcurl_easy_set_HTTPPOST(lua_State *L){
|
||||||
|
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||||
|
lcurl_hpost_t *post = lcurl_gethpost_at(L, 2);
|
||||||
|
CURLcode code = curl_easy_setopt(p->curl, CURLOPT_HTTPPOST, post->post);
|
||||||
|
if(code != CURLE_OK){
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
lcurl_storage_preserve_value(L, p->storage, 2);
|
||||||
|
|
||||||
|
lua_settop(L, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
//{ info
|
||||||
|
|
||||||
|
static int lcurl_info_get_long_(lua_State *L, int opt){
|
||||||
|
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||||
|
long val; CURLcode code;
|
||||||
|
|
||||||
|
code = curl_easy_getinfo(p->curl, opt, &val);
|
||||||
|
if(code != CURLE_OK){
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushnumber(L, val);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_info_get_double_(lua_State *L, int opt){
|
||||||
|
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||||
|
double val; CURLcode code;
|
||||||
|
|
||||||
|
code = curl_easy_getinfo(p->curl, opt, &val);
|
||||||
|
if(code != CURLE_OK){
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushnumber(L, val);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_info_get_string_(lua_State *L, int opt){
|
||||||
|
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||||
|
char *val; CURLcode code;
|
||||||
|
|
||||||
|
code = curl_easy_getinfo(p->curl, opt, &val);
|
||||||
|
if(code != CURLE_OK){
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushstring(L, val);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_info_get_slist_(lua_State *L, int opt){
|
||||||
|
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||||
|
struct curl_slist *val; CURLcode code;
|
||||||
|
|
||||||
|
code = curl_easy_getinfo(p->curl, opt, &val);
|
||||||
|
if(code != CURLE_OK){
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
lcurl_util_slist_to_table(L, val);
|
||||||
|
curl_slist_free_all(val);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LCURL_STR_INFO(N, S) static int lcurl_easy_get_##N(lua_State *L){\
|
||||||
|
return lcurl_info_get_string_(L, CURLINFO_##N); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LCURL_LST_INFO(N, S) static int lcurl_easy_get_##N(lua_State *L){\
|
||||||
|
return lcurl_info_get_slist_(L, CURLINFO_##N);\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LCURL_LNG_INFO(N, S) static int lcurl_easy_get_##N(lua_State *L){\
|
||||||
|
return lcurl_info_get_long_(L, CURLINFO_##N);\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LCURL_DBL_INFO(N, S) static int lcurl_easy_get_##N(lua_State *L){\
|
||||||
|
return lcurl_info_get_double_(L, CURLINFO_##N);\
|
||||||
|
}
|
||||||
|
|
||||||
|
#define OPT_ENTRY(L, N, T, S) LCURL_##T##_INFO(N, S)
|
||||||
|
|
||||||
|
#include "lcinfoeasy.h"
|
||||||
|
|
||||||
|
#undef OPT_ENTRY
|
||||||
|
|
||||||
|
#undef LCURL_STR_INFO
|
||||||
|
#undef LCURL_LST_INFO
|
||||||
|
#undef LCURL_LNG_INFO
|
||||||
|
#undef LCURL_DBL_INFO
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
//{ CallBack
|
||||||
|
|
||||||
|
static int lcurl_util_push_cb(lua_State *L, lcurl_callback_t *c){
|
||||||
|
assert(c->cb_ref != LUA_NOREF);
|
||||||
|
lua_rawgeti(L, LCURL_LUA_REGISTRY, c->cb_ref);
|
||||||
|
if(c->ud_ref != LUA_NOREF){
|
||||||
|
lua_rawgeti(L, LCURL_LUA_REGISTRY, c->ud_ref);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//{ Writer
|
||||||
|
|
||||||
|
static int lcurl_write_callback(char *ptr, size_t size, size_t nmemb, void *arg){
|
||||||
|
lcurl_easy_t *p = arg;
|
||||||
|
lua_State *L = p->L;
|
||||||
|
|
||||||
|
size_t ret = size * nmemb;
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
int n = lcurl_util_push_cb(L, &p->wr);
|
||||||
|
|
||||||
|
lua_pushlstring(L, ptr, ret);
|
||||||
|
if(lua_pcall(L, n, LUA_MULTRET, 0)) return 0;
|
||||||
|
|
||||||
|
if(lua_gettop(L) > top){
|
||||||
|
if(lua_isnil(L, top + 1)) return 0;
|
||||||
|
if(lua_isboolean(L, top + 1)){
|
||||||
|
if(!lua_toboolean(L, top + 1)) ret = 0;
|
||||||
|
}
|
||||||
|
else ret = (size_t)lua_tonumber(L, top + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_settop(L, top);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_easy_set_WRITEFUNCTION(lua_State *L){
|
||||||
|
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||||
|
lcurl_callback_t *c = &p->wr;
|
||||||
|
|
||||||
|
if(c->ud_ref != LUA_NOREF){
|
||||||
|
luaL_unref(L, LCURL_LUA_REGISTRY, c->ud_ref);
|
||||||
|
c->ud_ref = LUA_NOREF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(c->cb_ref != LUA_NOREF){
|
||||||
|
luaL_unref(L, LCURL_LUA_REGISTRY, c->cb_ref);
|
||||||
|
c->cb_ref = LUA_NOREF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lua_gettop(L) >= 3){// writer + context
|
||||||
|
lua_settop(L, 3);
|
||||||
|
luaL_argcheck(L, !lua_isnil(L, 2), 2, "no writer present");
|
||||||
|
c->ud_ref = luaL_ref(L, LCURL_LUA_REGISTRY);
|
||||||
|
c->cb_ref = luaL_ref(L, LCURL_LUA_REGISTRY);
|
||||||
|
assert(1 == lua_gettop(L));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_settop(L, 2);
|
||||||
|
|
||||||
|
if(lua_isnoneornil(L, 2)){
|
||||||
|
lua_pop(L, 1);
|
||||||
|
assert(1 == lua_gettop(L));
|
||||||
|
|
||||||
|
curl_easy_setopt(p->curl, CURLOPT_WRITEDATA, 0);
|
||||||
|
curl_easy_setopt(p->curl, CURLOPT_WRITEFUNCTION, 0);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_easy_setopt(p->curl, CURLOPT_WRITEDATA, p);
|
||||||
|
curl_easy_setopt(p->curl, CURLOPT_WRITEFUNCTION, lcurl_write_callback);
|
||||||
|
|
||||||
|
if(lua_isfunction(L, 2)){
|
||||||
|
c->cb_ref = luaL_ref(L, LCURL_LUA_REGISTRY);
|
||||||
|
assert(1 == lua_gettop(L));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lua_isuserdata(L, 2) || lua_istable(L, 2)){
|
||||||
|
lua_getfield(L, 2, "write");
|
||||||
|
luaL_argcheck(L, lua_isfunction(L, -1), 2, "write method not found in object");
|
||||||
|
c->cb_ref = luaL_ref(L, LCURL_LUA_REGISTRY);
|
||||||
|
c->ud_ref = luaL_ref(L, LCURL_LUA_REGISTRY);
|
||||||
|
assert(1 == lua_gettop(L));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushliteral(L, "invalid writer type");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
//{ Reader
|
||||||
|
|
||||||
|
static int lcurl_read_callback(char *buffer, size_t size, size_t nitems, void *arg){
|
||||||
|
lcurl_easy_t *p = arg;
|
||||||
|
lua_State *L = p->L;
|
||||||
|
|
||||||
|
const char *data; size_t data_size;
|
||||||
|
|
||||||
|
size_t ret = size * nitems;
|
||||||
|
int n, top = lua_gettop(L);
|
||||||
|
|
||||||
|
if(p->rbuffer.ref != LUA_NOREF){
|
||||||
|
lua_rawgeti(L, LCURL_LUA_REGISTRY, p->rbuffer.ref);
|
||||||
|
data = luaL_checklstring(L, -1, &data_size);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
data = data + p->rbuffer.off;
|
||||||
|
data_size -= p->rbuffer.off;
|
||||||
|
|
||||||
|
if(data_size > ret){
|
||||||
|
data_size = ret;
|
||||||
|
memcpy(buffer, data, data_size);
|
||||||
|
p->rbuffer.off += data_size;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
memcpy(buffer, data, data_size);
|
||||||
|
luaL_unref(L, LCURL_LUA_REGISTRY, p->rbuffer.ref);
|
||||||
|
p->rbuffer.ref = LUA_NOREF;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_settop(L, top);
|
||||||
|
return data_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// buffer is clean
|
||||||
|
assert(p->rbuffer.ref == LUA_NOREF);
|
||||||
|
|
||||||
|
n = lcurl_util_push_cb(L, &p->rd);
|
||||||
|
lua_pushnumber(L, ret);
|
||||||
|
if(lua_pcall(L, n, LUA_MULTRET, 0)) return CURL_READFUNC_ABORT;
|
||||||
|
|
||||||
|
if(lua_isnoneornil(L, top + 1)) return CURL_READFUNC_ABORT;
|
||||||
|
data = lua_tolstring(L, -1, &data_size);
|
||||||
|
if(!data) return CURL_READFUNC_ABORT;
|
||||||
|
|
||||||
|
if(data_size > ret){
|
||||||
|
data_size = ret;
|
||||||
|
p->rbuffer.ref = luaL_ref(L, LCURL_LUA_REGISTRY);
|
||||||
|
p->rbuffer.off = data_size;
|
||||||
|
}
|
||||||
|
memcpy(buffer, data, data_size);
|
||||||
|
|
||||||
|
lua_settop(L, top);
|
||||||
|
return data_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_easy_set_READFUNCTION(lua_State *L){
|
||||||
|
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||||
|
lcurl_callback_t *c = &p->rd;
|
||||||
|
|
||||||
|
if(c->ud_ref != LUA_NOREF){
|
||||||
|
luaL_unref(L, LCURL_LUA_REGISTRY, c->ud_ref);
|
||||||
|
c->ud_ref = LUA_NOREF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(c->cb_ref != LUA_NOREF){
|
||||||
|
luaL_unref(L, LCURL_LUA_REGISTRY, c->cb_ref);
|
||||||
|
c->cb_ref = LUA_NOREF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lua_gettop(L) >= 3){// writer + context
|
||||||
|
lua_settop(L, 3);
|
||||||
|
luaL_argcheck(L, !lua_isnil(L, 2), 2, "no writer present");
|
||||||
|
c->ud_ref = luaL_ref(L, LCURL_LUA_REGISTRY);
|
||||||
|
c->cb_ref = luaL_ref(L, LCURL_LUA_REGISTRY);
|
||||||
|
assert(1 == lua_gettop(L));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_settop(L, 2);
|
||||||
|
|
||||||
|
if(lua_isnoneornil(L, 2)){
|
||||||
|
lua_pop(L, 1);
|
||||||
|
assert(1 == lua_gettop(L));
|
||||||
|
|
||||||
|
curl_easy_setopt(p->curl, CURLOPT_READDATA, 0);
|
||||||
|
curl_easy_setopt(p->curl, CURLOPT_READFUNCTION, 0);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
curl_easy_setopt(p->curl, CURLOPT_READDATA, p);
|
||||||
|
curl_easy_setopt(p->curl, CURLOPT_READFUNCTION, lcurl_read_callback);
|
||||||
|
|
||||||
|
if(lua_isfunction(L, 2)){
|
||||||
|
c->cb_ref = luaL_ref(L, LCURL_LUA_REGISTRY);
|
||||||
|
assert(1 == lua_gettop(L));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lua_isuserdata(L, 2) || lua_istable(L, 2)){
|
||||||
|
lua_getfield(L, 2, "read");
|
||||||
|
luaL_argcheck(L, lua_isfunction(L, -1), 2, "read method not found in object");
|
||||||
|
c->cb_ref = luaL_ref(L, LCURL_LUA_REGISTRY);
|
||||||
|
c->ud_ref = luaL_ref(L, LCURL_LUA_REGISTRY);
|
||||||
|
assert(1 == lua_gettop(L));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pushliteral(L, "invalid reader type");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
#define OPT_ENTRY(L, N, T, S) { "setopt_"#L, lcurl_easy_set_##N },
|
||||||
|
static const struct luaL_Reg lcurl_easy_methods[] = {
|
||||||
|
|
||||||
|
#include "lcopteasy.h"
|
||||||
|
|
||||||
|
OPT_ENTRY(httppost, HTTPPOST, TTT, 0)
|
||||||
|
OPT_ENTRY(writefunction, WRITEFUNCTION, TTT, 0)
|
||||||
|
OPT_ENTRY(readfunction, READFUNCTION, TTT, 0)
|
||||||
|
|
||||||
|
{"getinfo_effective_url", lcurl_easy_get_EFFECTIVE_URL },
|
||||||
|
|
||||||
|
{"perform", lcurl_easy_perform },
|
||||||
|
{"close", lcurl_easy_cleanup },
|
||||||
|
{"__gc", lcurl_easy_cleanup },
|
||||||
|
|
||||||
|
{NULL,NULL}
|
||||||
|
};
|
||||||
|
#undef OPT_ENTRY
|
||||||
|
|
||||||
|
void lcurl_easy_initlib(lua_State *L, int nup){
|
||||||
|
if(!lutil_createmetap(L, LCURL_EASY, lcurl_easy_methods, nup))
|
||||||
|
lua_pop(L, nup);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
10
src/lceasy.h
Normal file
10
src/lceasy.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef _LCEASY_H_
|
||||||
|
#define _LCEASY_H_
|
||||||
|
|
||||||
|
#include "lcurl.h"
|
||||||
|
|
||||||
|
int lcurl_easy_create(lua_State *L, int error_mode);
|
||||||
|
|
||||||
|
void lcurl_easy_initlib(lua_State *L, int nup);
|
||||||
|
|
||||||
|
#endif
|
320
src/lcerror.c
Normal file
320
src/lcerror.c
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
/*
|
||||||
|
Author: Alexey Melnichuk <mimir@newmail.ru>
|
||||||
|
|
||||||
|
Copyright (C) 2013-2014 Alexey Melnichuk <mimir@newmail.ru>
|
||||||
|
|
||||||
|
Licensed according to the included 'LICENCE' document
|
||||||
|
|
||||||
|
This file is part of lua-lcurl library.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lcurl.h"
|
||||||
|
#include "lcerror.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#define LCURL_ERROR_NAME LCURL_PREFIX" Error"
|
||||||
|
static const char *LCURL_ERROR = LCURL_ERROR_NAME;
|
||||||
|
|
||||||
|
typedef struct lcurl_error_tag{
|
||||||
|
int tp;
|
||||||
|
int no;
|
||||||
|
}lcurl_error_t;
|
||||||
|
|
||||||
|
//{
|
||||||
|
|
||||||
|
static const char* lcurl_err_easy_mnemo(int err){
|
||||||
|
#define RETURN_IF(E) case CURLE_##E: return #E;
|
||||||
|
|
||||||
|
switch (err){
|
||||||
|
RETURN_IF ( OK )
|
||||||
|
RETURN_IF ( UNSUPPORTED_PROTOCOL )
|
||||||
|
RETURN_IF ( FAILED_INIT )
|
||||||
|
RETURN_IF ( URL_MALFORMAT )
|
||||||
|
RETURN_IF ( NOT_BUILT_IN )
|
||||||
|
RETURN_IF ( COULDNT_RESOLVE_PROXY )
|
||||||
|
RETURN_IF ( COULDNT_RESOLVE_HOST )
|
||||||
|
RETURN_IF ( COULDNT_CONNECT )
|
||||||
|
RETURN_IF ( FTP_WEIRD_SERVER_REPLY )
|
||||||
|
RETURN_IF ( REMOTE_ACCESS_DENIED )
|
||||||
|
RETURN_IF ( FTP_ACCEPT_FAILED )
|
||||||
|
RETURN_IF ( FTP_WEIRD_PASS_REPLY )
|
||||||
|
RETURN_IF ( FTP_ACCEPT_TIMEOUT )
|
||||||
|
RETURN_IF ( FTP_WEIRD_PASV_REPLY )
|
||||||
|
RETURN_IF ( FTP_WEIRD_227_FORMAT )
|
||||||
|
RETURN_IF ( FTP_CANT_GET_HOST )
|
||||||
|
RETURN_IF ( OBSOLETE16 )
|
||||||
|
RETURN_IF ( FTP_COULDNT_SET_TYPE )
|
||||||
|
RETURN_IF ( PARTIAL_FILE )
|
||||||
|
RETURN_IF ( FTP_COULDNT_RETR_FILE )
|
||||||
|
RETURN_IF ( OBSOLETE20 )
|
||||||
|
RETURN_IF ( QUOTE_ERROR )
|
||||||
|
RETURN_IF ( HTTP_RETURNED_ERROR )
|
||||||
|
RETURN_IF ( WRITE_ERROR )
|
||||||
|
RETURN_IF ( OBSOLETE24 )
|
||||||
|
RETURN_IF ( UPLOAD_FAILED )
|
||||||
|
RETURN_IF ( READ_ERROR )
|
||||||
|
RETURN_IF ( OUT_OF_MEMORY )
|
||||||
|
RETURN_IF ( OPERATION_TIMEDOUT )
|
||||||
|
RETURN_IF ( OBSOLETE29 )
|
||||||
|
RETURN_IF ( FTP_PORT_FAILED )
|
||||||
|
RETURN_IF ( FTP_COULDNT_USE_REST )
|
||||||
|
RETURN_IF ( OBSOLETE32 )
|
||||||
|
RETURN_IF ( RANGE_ERROR )
|
||||||
|
RETURN_IF ( HTTP_POST_ERROR )
|
||||||
|
RETURN_IF ( SSL_CONNECT_ERROR )
|
||||||
|
RETURN_IF ( BAD_DOWNLOAD_RESUME )
|
||||||
|
RETURN_IF ( FILE_COULDNT_READ_FILE )
|
||||||
|
RETURN_IF ( LDAP_CANNOT_BIND )
|
||||||
|
RETURN_IF ( LDAP_SEARCH_FAILED )
|
||||||
|
RETURN_IF ( OBSOLETE40 )
|
||||||
|
RETURN_IF ( FUNCTION_NOT_FOUND )
|
||||||
|
RETURN_IF ( ABORTED_BY_CALLBACK )
|
||||||
|
RETURN_IF ( BAD_FUNCTION_ARGUMENT )
|
||||||
|
RETURN_IF ( OBSOLETE44 )
|
||||||
|
RETURN_IF ( INTERFACE_FAILED )
|
||||||
|
RETURN_IF ( OBSOLETE46 )
|
||||||
|
RETURN_IF ( TOO_MANY_REDIRECTS )
|
||||||
|
RETURN_IF ( UNKNOWN_OPTION )
|
||||||
|
RETURN_IF ( TELNET_OPTION_SYNTAX )
|
||||||
|
RETURN_IF ( OBSOLETE50 )
|
||||||
|
RETURN_IF ( PEER_FAILED_VERIFICATION )
|
||||||
|
RETURN_IF ( GOT_NOTHING )
|
||||||
|
RETURN_IF ( SSL_ENGINE_NOTFOUND )
|
||||||
|
RETURN_IF ( SSL_ENGINE_SETFAILED )
|
||||||
|
RETURN_IF ( SEND_ERROR )
|
||||||
|
RETURN_IF ( RECV_ERROR )
|
||||||
|
RETURN_IF ( OBSOLETE57 )
|
||||||
|
RETURN_IF ( SSL_CERTPROBLEM )
|
||||||
|
RETURN_IF ( SSL_CIPHER )
|
||||||
|
RETURN_IF ( SSL_CACERT )
|
||||||
|
RETURN_IF ( BAD_CONTENT_ENCODING )
|
||||||
|
RETURN_IF ( LDAP_INVALID_URL )
|
||||||
|
RETURN_IF ( FILESIZE_EXCEEDED )
|
||||||
|
RETURN_IF ( USE_SSL_FAILED )
|
||||||
|
RETURN_IF ( SEND_FAIL_REWIND )
|
||||||
|
RETURN_IF ( SSL_ENGINE_INITFAILED )
|
||||||
|
RETURN_IF ( LOGIN_DENIED )
|
||||||
|
RETURN_IF ( TFTP_NOTFOUND )
|
||||||
|
RETURN_IF ( TFTP_PERM )
|
||||||
|
RETURN_IF ( REMOTE_DISK_FULL )
|
||||||
|
RETURN_IF ( TFTP_ILLEGAL )
|
||||||
|
RETURN_IF ( TFTP_UNKNOWNID )
|
||||||
|
RETURN_IF ( REMOTE_FILE_EXISTS )
|
||||||
|
RETURN_IF ( TFTP_NOSUCHUSER )
|
||||||
|
RETURN_IF ( CONV_FAILED )
|
||||||
|
RETURN_IF ( CONV_REQD )
|
||||||
|
RETURN_IF ( SSL_CACERT_BADFILE )
|
||||||
|
RETURN_IF ( REMOTE_FILE_NOT_FOUND )
|
||||||
|
RETURN_IF ( SSH )
|
||||||
|
RETURN_IF ( SSL_SHUTDOWN_FAILED )
|
||||||
|
RETURN_IF ( AGAIN )
|
||||||
|
RETURN_IF ( SSL_CRL_BADFILE )
|
||||||
|
RETURN_IF ( SSL_ISSUER_ERROR )
|
||||||
|
RETURN_IF ( FTP_PRET_FAILED )
|
||||||
|
RETURN_IF ( RTSP_CSEQ_ERROR )
|
||||||
|
RETURN_IF ( RTSP_SESSION_ERROR )
|
||||||
|
RETURN_IF ( FTP_BAD_FILE_LIST )
|
||||||
|
RETURN_IF ( CHUNK_FAILED )
|
||||||
|
RETURN_IF ( NO_CONNECTION_AVAILABLE )
|
||||||
|
}
|
||||||
|
return "UNKNOWN";
|
||||||
|
|
||||||
|
#undef RETURN_IF
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* lcurl_err_multi_mnemo(int err){
|
||||||
|
#define RETURN_IF(E) case CURLM_##E: return #E;
|
||||||
|
|
||||||
|
switch (err){
|
||||||
|
RETURN_IF ( OK )
|
||||||
|
RETURN_IF ( CALL_MULTI_PERFORM )
|
||||||
|
RETURN_IF ( BAD_HANDLE )
|
||||||
|
RETURN_IF ( BAD_EASY_HANDLE )
|
||||||
|
RETURN_IF ( OUT_OF_MEMORY )
|
||||||
|
RETURN_IF ( INTERNAL_ERROR )
|
||||||
|
RETURN_IF ( BAD_SOCKET )
|
||||||
|
RETURN_IF ( UNKNOWN_OPTION )
|
||||||
|
RETURN_IF ( ADDED_ALREADY )
|
||||||
|
}
|
||||||
|
return "UNKNOWN";
|
||||||
|
|
||||||
|
#undef RETURN_IF
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* lcurl_err_share_mnemo(int err){
|
||||||
|
#define RETURN_IF(E) case CURLSHE_##E: return #E;
|
||||||
|
|
||||||
|
switch (err){
|
||||||
|
RETURN_IF ( OK )
|
||||||
|
RETURN_IF ( BAD_OPTION )
|
||||||
|
RETURN_IF ( IN_USE )
|
||||||
|
RETURN_IF ( INVALID )
|
||||||
|
RETURN_IF ( NOMEM )
|
||||||
|
RETURN_IF ( NOT_BUILT_IN )
|
||||||
|
}
|
||||||
|
return "UNKNOWN";
|
||||||
|
|
||||||
|
#undef RETURN_IF
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* lcurl_err_form_mnemo(int err){
|
||||||
|
#define RETURN_IF(E) case CURL_FORMADD_##E: return #E;
|
||||||
|
|
||||||
|
switch (err){
|
||||||
|
RETURN_IF ( OK )
|
||||||
|
RETURN_IF ( MEMORY )
|
||||||
|
RETURN_IF ( OPTION_TWICE )
|
||||||
|
RETURN_IF ( NULL )
|
||||||
|
RETURN_IF ( UNKNOWN_OPTION )
|
||||||
|
RETURN_IF ( INCOMPLETE )
|
||||||
|
RETURN_IF ( ILLEGAL_ARRAY )
|
||||||
|
RETURN_IF ( DISABLED )
|
||||||
|
}
|
||||||
|
return "UNKNOWN";
|
||||||
|
|
||||||
|
#undef RETURN_IF
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* _lcurl_err_mnemo(int tp, int err){
|
||||||
|
switch(tp){
|
||||||
|
case LCURL_ERROR_EASY : return lcurl_err_easy_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_FORM : return lcurl_err_form_mnemo (err);
|
||||||
|
}
|
||||||
|
assert(0);
|
||||||
|
return "<UNSUPPORTED ERROR TYPE>";
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* _lcurl_err_msg(int tp, int err){
|
||||||
|
switch(tp){
|
||||||
|
case LCURL_ERROR_EASY : return curl_easy_strerror (err);
|
||||||
|
case LCURL_ERROR_MULTI: return curl_multi_strerror(err);
|
||||||
|
case LCURL_ERROR_SHARE: return curl_share_strerror(err);
|
||||||
|
case LCURL_ERROR_FORM : return lcurl_err_form_mnemo(err);
|
||||||
|
}
|
||||||
|
assert(0);
|
||||||
|
return "<UNSUPPORTED ERROR TYPE>";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _lcurl_err_pushstring(lua_State *L, int tp, int err){
|
||||||
|
lua_pushfstring(L, "[%s] %s (%d)",
|
||||||
|
_lcurl_err_mnemo(tp, err),
|
||||||
|
_lcurl_err_msg(tp, err),
|
||||||
|
err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
//{
|
||||||
|
|
||||||
|
int lcurl_error_create(lua_State *L, int error_type, int no){
|
||||||
|
lcurl_error_t *err = lutil_newudatap(L, lcurl_error_t, LCURL_ERROR);
|
||||||
|
|
||||||
|
assert(
|
||||||
|
(error_type == LCURL_ERROR_EASY ) ||
|
||||||
|
(error_type == LCURL_ERROR_MULTI) ||
|
||||||
|
(error_type == LCURL_ERROR_SHARE) ||
|
||||||
|
(error_type == LCURL_ERROR_FORM ) ||
|
||||||
|
0
|
||||||
|
);
|
||||||
|
|
||||||
|
err->tp = error_type;
|
||||||
|
err->no = no;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static lcurl_error_t *lcurl_geterror_at(lua_State *L, int i){
|
||||||
|
lcurl_error_t *err = (lcurl_error_t *)lutil_checkudatap (L, i, LCURL_ERROR);
|
||||||
|
luaL_argcheck (L, err != NULL, 1, LCURL_PREFIX"error object expected");
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define lcurl_geterror(L) lcurl_geterror_at((L),1)
|
||||||
|
|
||||||
|
static int lcurl_err_no(lua_State *L){
|
||||||
|
lcurl_error_t *err = lcurl_geterror(L);
|
||||||
|
lua_pushinteger(L, err->no);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_err_msg(lua_State *L){
|
||||||
|
lcurl_error_t *err = lcurl_geterror(L);
|
||||||
|
lua_pushstring(L, _lcurl_err_msg(err->tp, err->no));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_err_mnemo(lua_State *L){
|
||||||
|
lcurl_error_t *err = lcurl_geterror(L);
|
||||||
|
lua_pushstring(L, _lcurl_err_mnemo(err->tp, err->no));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_err_tostring(lua_State *L){
|
||||||
|
lcurl_error_t *err = lcurl_geterror(L);
|
||||||
|
_lcurl_err_pushstring(L, err->tp, err->no);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_err_equal(lua_State *L){
|
||||||
|
lcurl_error_t *lhs = lcurl_geterror_at(L, 1);
|
||||||
|
lcurl_error_t *rhs = lcurl_geterror_at(L, 2);
|
||||||
|
lua_pushboolean(L, ((lhs->no == rhs->no)&&(lhs->tp == rhs->tp))?1:0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
//{
|
||||||
|
|
||||||
|
int lcurl_fail_ex(lua_State *L, int mode, int error_type, int code){
|
||||||
|
if(mode == LCURL_ERROR_RETURN){
|
||||||
|
lua_pushnil(L);
|
||||||
|
lcurl_error_create(L, error_type, code);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LUA_VERSION_NUM >= 502 // lua 5.2
|
||||||
|
lcurl_error_create(L, error_type, code);
|
||||||
|
#else
|
||||||
|
_lcurl_err_pushstring(L, error_type, code);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
assert(LCURL_ERROR_RAISE == mode);
|
||||||
|
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
int lcurl_fail(lua_State *L, int error_type, int code){
|
||||||
|
return lcurl_fail_ex(L, LCURL_ERROR_RETURN, error_type, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
int lcurl_error_new(lua_State *L){
|
||||||
|
int tp = luaL_checkint(L, 1);
|
||||||
|
int no = luaL_checkint(L, 2);
|
||||||
|
|
||||||
|
//! @todo checks error type value
|
||||||
|
|
||||||
|
lcurl_error_create(L, tp, no);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct luaL_Reg lcurl_err_methods[] = {
|
||||||
|
{"no", lcurl_err_no },
|
||||||
|
{"msg", lcurl_err_msg },
|
||||||
|
{"name", lcurl_err_mnemo },
|
||||||
|
{"mnemo", lcurl_err_mnemo },
|
||||||
|
{"__tostring", lcurl_err_tostring },
|
||||||
|
{"__eq", lcurl_err_equal },
|
||||||
|
|
||||||
|
{NULL,NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
void lcurl_error_initlib(lua_State *L, int nup){
|
||||||
|
if(!lutil_createmetap(L, LCURL_ERROR, lcurl_err_methods, nup))
|
||||||
|
lua_pop(L, nup);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
23
src/lcerror.h
Normal file
23
src/lcerror.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#ifndef _LCERROR_H_
|
||||||
|
#define _LCERROR_H_
|
||||||
|
|
||||||
|
#include "lcurl.h"
|
||||||
|
|
||||||
|
#define LCURL_ERROR_CURL 1
|
||||||
|
#define LCURL_ERROR_EASY 1
|
||||||
|
#define LCURL_ERROR_MULTI 2
|
||||||
|
#define LCURL_ERROR_SHARE 3
|
||||||
|
#define LCURL_ERROR_FORM 4
|
||||||
|
|
||||||
|
#define LCURL_ERROR_RETURN 1
|
||||||
|
#define LCURL_ERROR_RAISE 2
|
||||||
|
|
||||||
|
int lcurl_fail(lua_State *L, int error_type, int code);
|
||||||
|
|
||||||
|
int lcurl_fail_ex(lua_State *L, int mode, int error_type, int code);
|
||||||
|
|
||||||
|
int lcurl_error_new(lua_State *L);
|
||||||
|
|
||||||
|
void lcurl_error_initlib(lua_State *L, int nup);
|
||||||
|
|
||||||
|
#endif
|
393
src/lchttppost.c
Normal file
393
src/lchttppost.c
Normal file
@ -0,0 +1,393 @@
|
|||||||
|
#include "lcurl.h"
|
||||||
|
#include "lchttppost.h"
|
||||||
|
#include "lcerror.h"
|
||||||
|
#include "lcutils.h"
|
||||||
|
|
||||||
|
#define LCURL_HTTPPOST_NAME LCURL_PREFIX" HTTPPost"
|
||||||
|
static const char *LCURL_HTTPPOST = LCURL_HTTPPOST_NAME;
|
||||||
|
|
||||||
|
//{
|
||||||
|
|
||||||
|
int lcurl_hpost_create(lua_State *L, int error_mode){
|
||||||
|
lcurl_hpost_t *p = lutil_newudatap(L, lcurl_hpost_t, LCURL_HTTPPOST);
|
||||||
|
p->post = p->last = 0;
|
||||||
|
p->storage = lcurl_storage_init(L);
|
||||||
|
p->err_mode = error_mode;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lcurl_hpost_t *lcurl_gethpost_at(lua_State *L, int i){
|
||||||
|
lcurl_hpost_t *p = (lcurl_hpost_t *)lutil_checkudatap (L, i, LCURL_HTTPPOST);
|
||||||
|
luaL_argcheck (L, p != NULL, 1, LCURL_PREFIX"HTTPPost object expected");
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_hpost_add_content(lua_State *L){
|
||||||
|
// add_buffer(name, data, [type,] [headers])
|
||||||
|
lcurl_hpost_t *p = lcurl_gethpost(L);
|
||||||
|
size_t name_len; const char *name = luaL_checklstring(L, 2, &name_len);
|
||||||
|
size_t cont_len; const char *cont = luaL_checklstring(L, 3, &cont_len);
|
||||||
|
const char *type = lua_tostring(L, 4);
|
||||||
|
struct curl_slist *list = lcurl_util_to_slist(L, type?5:4);
|
||||||
|
struct curl_forms forms[3];
|
||||||
|
CURLFORMcode code;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
if(type){ forms[i].option = CURLFORM_CONTENTTYPE; forms[i++].value = type; }
|
||||||
|
if(list){ forms[i].option = CURLFORM_CONTENTHEADER; forms[i++].value = (char*)list; }
|
||||||
|
forms[i].option = CURLFORM_END;
|
||||||
|
|
||||||
|
code = curl_formadd(&p->post, &p->last,
|
||||||
|
CURLFORM_PTRNAME, name, CURLFORM_NAMELENGTH, name_len,
|
||||||
|
CURLFORM_PTRCONTENTS, cont, CURLFORM_CONTENTSLENGTH, cont_len,
|
||||||
|
CURLFORM_ARRAY, forms,
|
||||||
|
CURLFORM_END);
|
||||||
|
|
||||||
|
if(code != CURL_FORMADD_OK){
|
||||||
|
if(list) curl_slist_free_all(list);
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_FORM, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
lcurl_storage_preserve_value(L, p->storage, 2);
|
||||||
|
lcurl_storage_preserve_value(L, p->storage, 3);
|
||||||
|
if(list) lcurl_storage_preserve_slist (L, p->storage, list);
|
||||||
|
|
||||||
|
lua_settop(L, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_hpost_add_buffer(lua_State *L){
|
||||||
|
// add_buffer(name, filename, data, [type,] [headers])
|
||||||
|
lcurl_hpost_t *p = lcurl_gethpost(L);
|
||||||
|
size_t name_len; const char *name = luaL_checklstring(L, 2, &name_len);
|
||||||
|
const char *buff = luaL_checkstring(L, 3);
|
||||||
|
size_t cont_len; const char *cont = luaL_checklstring(L, 4, &cont_len);
|
||||||
|
const char *type = lua_tostring(L, 5);
|
||||||
|
struct curl_slist *list = lcurl_util_to_slist(L, type?6:5);
|
||||||
|
struct curl_forms forms[3];
|
||||||
|
CURLFORMcode code;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
if(type){ forms[i].option = CURLFORM_CONTENTTYPE; forms[i++].value = type; }
|
||||||
|
if(list){ forms[i].option = CURLFORM_CONTENTHEADER; forms[i++].value = (char*)list; }
|
||||||
|
forms[i].option = CURLFORM_END;
|
||||||
|
|
||||||
|
code = curl_formadd(&p->post, &p->last,
|
||||||
|
CURLFORM_PTRNAME, name, CURLFORM_NAMELENGTH, name_len,
|
||||||
|
CURLFORM_BUFFER, buff,
|
||||||
|
CURLFORM_BUFFERPTR, cont, CURLFORM_BUFFERLENGTH, cont_len,
|
||||||
|
CURLFORM_ARRAY, forms,
|
||||||
|
CURLFORM_END);
|
||||||
|
|
||||||
|
if(code != CURL_FORMADD_OK){
|
||||||
|
if(list) curl_slist_free_all(list);
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_FORM, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
lcurl_storage_preserve_value(L, p->storage, 2);
|
||||||
|
lcurl_storage_preserve_value(L, p->storage, 4);
|
||||||
|
if(list) lcurl_storage_preserve_slist (L, p->storage, list);
|
||||||
|
|
||||||
|
lua_settop(L, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_hpost_add_file(lua_State *L){
|
||||||
|
// add_file(name, path, [type, [fname,]] [headers])
|
||||||
|
// add_file("Picture", "c:\\image.jpg")
|
||||||
|
// add_file("Picture", "c:\\image.jpg", "image/jpeg")
|
||||||
|
// add_file("Picture", "c:\\image.jpg", "image/jpeg", {"XDescript: my image"})
|
||||||
|
// add_file("Picture", "c:\\image.jpg", "image/jpeg", "avatar.jpeg", {"XDescript: my image"})
|
||||||
|
// add_file("Picture", "c:\\image.jpg", nil, "avatar.jpeg", {"XDescript: my image"})
|
||||||
|
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
lcurl_hpost_t *p = lcurl_gethpost(L);
|
||||||
|
size_t name_len; const char *name = luaL_checklstring(L, 2, &name_len);
|
||||||
|
const char *path = luaL_checkstring(L, 3);
|
||||||
|
const char *type = 0, *fname = 0;
|
||||||
|
struct curl_slist *list;
|
||||||
|
struct curl_forms forms[3];
|
||||||
|
CURLFORMcode code;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
if(top == 4){ /* name, path, type | headers */
|
||||||
|
if(lua_istable(L, 4))
|
||||||
|
list = lcurl_util_to_slist(L, 4);
|
||||||
|
else
|
||||||
|
type = lua_tostring(L, 4);
|
||||||
|
}
|
||||||
|
else if(top > 4){ /* name, path, type, fname | [fname, headers] */
|
||||||
|
type = lua_tostring(L, 4);
|
||||||
|
if(top == 5){ /* name, path, type, fname | headers */
|
||||||
|
if(lua_istable(L, 5))
|
||||||
|
list = lcurl_util_to_slist(L, 5);
|
||||||
|
else
|
||||||
|
fname = lua_tostring(L, 5);
|
||||||
|
}
|
||||||
|
else{ /* name, path, type, fname, headers */
|
||||||
|
fname = lua_tostring(L, 5);
|
||||||
|
list = lcurl_util_to_slist(L, 6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(type){ forms[i].option = CURLFORM_CONTENTTYPE; forms[i++].value = type; }
|
||||||
|
if(list){ forms[i].option = CURLFORM_CONTENTHEADER; forms[i++].value = (char*)list; }
|
||||||
|
forms[i].option = CURLFORM_END;
|
||||||
|
|
||||||
|
code = curl_formadd(&p->post, &p->last,
|
||||||
|
CURLFORM_PTRNAME, name, CURLFORM_NAMELENGTH, name_len,
|
||||||
|
CURLFORM_FILE, path,
|
||||||
|
CURLFORM_ARRAY, forms,
|
||||||
|
CURLFORM_END);
|
||||||
|
|
||||||
|
if(code != CURL_FORMADD_OK){
|
||||||
|
if(list) curl_slist_free_all(list);
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_FORM, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
lcurl_storage_preserve_value(L, p->storage, 2);
|
||||||
|
if(list) lcurl_storage_preserve_slist (L, p->storage, list);
|
||||||
|
|
||||||
|
lua_settop(L, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_hpost_add_files(lua_State *L){
|
||||||
|
lcurl_hpost_t *p = lcurl_gethpost(L);
|
||||||
|
size_t name_len; const char *name = luaL_checklstring(L, 2, &name_len);
|
||||||
|
int i; int opt_count = 0;
|
||||||
|
int arr_count = lua_rawlen(L, 3);
|
||||||
|
struct curl_forms *forms;
|
||||||
|
CURLFORMcode code;
|
||||||
|
|
||||||
|
lua_settop(L, 3);
|
||||||
|
if(lua_type(L, -1) != LUA_TTABLE){
|
||||||
|
//! @fixme use library specific error codes
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_FORM, CURL_FORMADD_ILLEGAL_ARRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(i = 1; i <= arr_count; ++i){
|
||||||
|
int n;
|
||||||
|
lua_rawgeti(L, 3, i);
|
||||||
|
|
||||||
|
if((lua_type(L, -1) != LUA_TTABLE) && (lua_type(L, -1) != LUA_TSTRING)){
|
||||||
|
//! @fixme use library specific error codes
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_FORM, CURL_FORMADD_ILLEGAL_ARRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
n = (lua_type(L, -1) == LUA_TSTRING) ? 1: lua_rawlen(L, -1);
|
||||||
|
if(n == 1) opt_count += 1; // name
|
||||||
|
else if(n == 2) opt_count += 2; // name and type
|
||||||
|
else if(n == 3) opt_count += 3; // name, type and filename
|
||||||
|
else{
|
||||||
|
//! @fixme use library specific error codes
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_FORM, CURL_FORMADD_ILLEGAL_ARRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(opt_count == 0){
|
||||||
|
lua_settop(L, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
forms = calloc(opt_count + 1, sizeof(struct curl_forms));
|
||||||
|
if(!forms){
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_FORM, CURL_FORMADD_MEMORY);
|
||||||
|
}
|
||||||
|
forms[opt_count].option = CURLFORM_END;
|
||||||
|
|
||||||
|
opt_count = 0;
|
||||||
|
for(i = 1; i <= arr_count; ++i){
|
||||||
|
int n;
|
||||||
|
|
||||||
|
lua_rawgeti(L, 3, i);
|
||||||
|
if (lua_type(L, -1) == LUA_TSTRING){
|
||||||
|
forms[opt_count].option = CURLFORM_FILE; forms[opt_count++].value = luaL_checkstring(L, -1);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
n = lua_rawlen(L, -1);
|
||||||
|
lua_rawgeti(L, -1, 1);
|
||||||
|
forms[opt_count].option = CURLFORM_FILE; forms[opt_count++].value = luaL_checkstring(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
if(n > 1){
|
||||||
|
lua_rawgeti(L, -1, 2);
|
||||||
|
forms[opt_count].option = CURLFORM_CONTENTTYPE; forms[opt_count++].value = luaL_checkstring(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
if(n > 2){
|
||||||
|
lua_rawgeti(L, -1, 3);
|
||||||
|
forms[opt_count].option = CURLFORM_FILENAME; forms[opt_count++].value = luaL_checkstring(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
code = curl_formadd(&p->post, &p->last,
|
||||||
|
CURLFORM_PTRNAME, name, CURLFORM_NAMELENGTH, name_len,
|
||||||
|
CURLFORM_ARRAY, forms,
|
||||||
|
CURLFORM_END);
|
||||||
|
|
||||||
|
free(forms);
|
||||||
|
|
||||||
|
if(code != CURL_FORMADD_OK){
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_FORM, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_settop(L, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t lcurl_hpost_getter_by_buffer(void *arg, const char *buf, size_t len){
|
||||||
|
luaL_Buffer *b = arg;
|
||||||
|
luaL_addlstring(b, buf, len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t call_writer(lua_State *L, int fn, int ctx, const char *buf, size_t len){
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
int n = 1; // number of args
|
||||||
|
lua_Number ret = (lua_Number)len;
|
||||||
|
|
||||||
|
lua_pushvalue(L, fn);
|
||||||
|
if(ctx){
|
||||||
|
lua_pushvalue(L, ctx);
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
|
lua_pushlstring(L, buf, len);
|
||||||
|
|
||||||
|
if(lua_pcall(L, n, LUA_MULTRET, 0)) return 0;
|
||||||
|
|
||||||
|
if(lua_gettop(L) > top){
|
||||||
|
if(lua_isnil(L, top + 1)) return 0;
|
||||||
|
if(lua_isboolean(L, top + 1)){
|
||||||
|
if(!lua_toboolean(L, top + 1)) ret = 0;
|
||||||
|
}
|
||||||
|
else ret = lua_tonumber(L, top + 1);
|
||||||
|
}
|
||||||
|
lua_settop(L, top);
|
||||||
|
|
||||||
|
return (size_t)ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t lcurl_hpost_getter_by_callback1(void *arg, const char *buf, size_t len){
|
||||||
|
lua_State *L = arg;
|
||||||
|
assert(2 == lua_gettop(L));
|
||||||
|
return call_writer(L, 2, 0, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t lcurl_hpost_getter_by_callback2(void *arg, const char *buf, size_t len){
|
||||||
|
lua_State *L = arg;
|
||||||
|
assert(3 == lua_gettop(L));
|
||||||
|
return call_writer(L, 2, 3, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_hpost_get(lua_State *L){
|
||||||
|
// get()
|
||||||
|
// get(fn [, ctx])
|
||||||
|
// get(object)
|
||||||
|
lcurl_hpost_t *p = lcurl_gethpost(L);
|
||||||
|
CURLcode code;
|
||||||
|
int top;
|
||||||
|
|
||||||
|
if(lua_isnoneornil(L, 2)){
|
||||||
|
luaL_Buffer b;
|
||||||
|
luaL_buffinit(L, &b);
|
||||||
|
|
||||||
|
code = curl_formget(p->post, &b, lcurl_hpost_getter_by_buffer);
|
||||||
|
if(code != CURLE_OK){
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_CURL, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
luaL_pushresult(&b);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lua_isfunction(L, 2)){
|
||||||
|
if(lua_gettop(L) == 2){
|
||||||
|
top = 2;
|
||||||
|
code = curl_formget(p->post, L, lcurl_hpost_getter_by_callback1);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
top = 3;
|
||||||
|
lua_settop(L, 3);
|
||||||
|
code = curl_formget(p->post, L, lcurl_hpost_getter_by_callback2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(lua_isuserdata(L, 2) || lua_istable(L, 2)){
|
||||||
|
lua_settop(L, 2);
|
||||||
|
lua_getfield(L, 2, "write");
|
||||||
|
luaL_argcheck(L, lua_isfunction(L, -1), 2, "write method not found in object");
|
||||||
|
assert(3 == lua_gettop(L));
|
||||||
|
lua_insert(L, -2);
|
||||||
|
top = 3;
|
||||||
|
code = curl_formget(p->post, L, lcurl_hpost_getter_by_callback2);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
lua_pushliteral(L, "invalid writer type");
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((CURLcode)-1 == code){
|
||||||
|
if(((lua_gettop(L) == top+1))&&(lua_isstring(L, -1))){
|
||||||
|
return lua_error(L);
|
||||||
|
}
|
||||||
|
return lua_gettop(L) - top;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(code != CURLE_OK){
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_CURL, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_settop(L, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_hpost_storage(lua_State *L){
|
||||||
|
lcurl_hpost_t *p = lcurl_gethpost(L);
|
||||||
|
lua_rawgeti(L, LCURL_LUA_REGISTRY, p->storage);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_hpost_free(lua_State *L){
|
||||||
|
lcurl_hpost_t *p = lcurl_gethpost(L);
|
||||||
|
if(p->post){
|
||||||
|
curl_formfree(p->post);
|
||||||
|
p->post = p->last = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(p->storage != LUA_NOREF){
|
||||||
|
lcurl_storage_free(L, p->storage);
|
||||||
|
p->storage = LUA_NOREF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//}
|
||||||
|
|
||||||
|
static const struct luaL_Reg lcurl_hpost_methods[] = {
|
||||||
|
{"add_content", lcurl_hpost_add_content },
|
||||||
|
{"add_buffer", lcurl_hpost_add_buffer },
|
||||||
|
{"add_file", lcurl_hpost_add_file },
|
||||||
|
|
||||||
|
{"add_files", lcurl_hpost_add_files },
|
||||||
|
|
||||||
|
{"storage", lcurl_hpost_storage },
|
||||||
|
{"get", lcurl_hpost_get },
|
||||||
|
{"free", lcurl_hpost_free },
|
||||||
|
{"__gc", lcurl_hpost_free },
|
||||||
|
|
||||||
|
{NULL,NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
void lcurl_hpost_initlib(lua_State *L, int nup){
|
||||||
|
if(!lutil_createmetap(L, LCURL_HTTPPOST, lcurl_hpost_methods, nup))
|
||||||
|
lua_pop(L, nup);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
22
src/lchttppost.h
Normal file
22
src/lchttppost.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#ifndef _LCHTTPPOST_H_
|
||||||
|
#define _LCHTTPPOST_H_
|
||||||
|
|
||||||
|
#include "lcurl.h"
|
||||||
|
|
||||||
|
typedef struct lcurl_hpost_tag{
|
||||||
|
struct curl_httppost *post;
|
||||||
|
struct curl_httppost *last;
|
||||||
|
int storage;
|
||||||
|
int err_mode;
|
||||||
|
}lcurl_hpost_t;
|
||||||
|
|
||||||
|
int lcurl_hpost_create(lua_State *L, int error_mode);
|
||||||
|
|
||||||
|
void lcurl_hpost_initlib(lua_State *L, int nup);
|
||||||
|
|
||||||
|
lcurl_hpost_t *lcurl_gethpost_at(lua_State *L, int i);
|
||||||
|
|
||||||
|
#define lcurl_gethpost(L) lcurl_gethpost_at((L),1)
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
44
src/lcinfoeasy.h
Normal file
44
src/lcinfoeasy.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
OPT_ENTRY( effective_url, EFFECTIVE_URL, STR, 0)
|
||||||
|
OPT_ENTRY( response_code, RESPONSE_CODE, LNG, 0)
|
||||||
|
OPT_ENTRY( http_connectcode, HTTP_CONNECTCODE, LNG, 0)
|
||||||
|
OPT_ENTRY( filetime, FILETIME, LNG, 0)
|
||||||
|
OPT_ENTRY( total_time, TOTAL_TIME, DBL, 0)
|
||||||
|
OPT_ENTRY( namelookup_time, NAMELOOKUP_TIME, DBL, 0)
|
||||||
|
OPT_ENTRY( connect_time, CONNECT_TIME, DBL, 0)
|
||||||
|
OPT_ENTRY( appconnect_time, APPCONNECT_TIME, DBL, 0)
|
||||||
|
OPT_ENTRY( pretransfer_time, PRETRANSFER_TIME, DBL, 0)
|
||||||
|
OPT_ENTRY( starttransfer_time, STARTTRANSFER_TIME, DBL, 0)
|
||||||
|
OPT_ENTRY( redirect_time, REDIRECT_TIME, DBL, 0)
|
||||||
|
OPT_ENTRY( redirect_count, REDIRECT_COUNT, LNG, 0)
|
||||||
|
OPT_ENTRY( redirect_url, REDIRECT_URL, STR, 0)
|
||||||
|
OPT_ENTRY( size_upload, SIZE_UPLOAD, DBL, 0)
|
||||||
|
OPT_ENTRY( size_download, SIZE_DOWNLOAD, DBL, 0)
|
||||||
|
OPT_ENTRY( speed_download, SPEED_DOWNLOAD, DBL, 0)
|
||||||
|
OPT_ENTRY( speed_upload, SPEED_UPLOAD, DBL, 0)
|
||||||
|
OPT_ENTRY( header_size, HEADER_SIZE, LNG, 0)
|
||||||
|
OPT_ENTRY( request_size, REQUEST_SIZE, LNG, 0)
|
||||||
|
OPT_ENTRY( ssl_verifyresult, SSL_VERIFYRESULT, LNG, 0)
|
||||||
|
OPT_ENTRY( ssl_engines, SSL_ENGINES, LST, 0)
|
||||||
|
OPT_ENTRY( content_length_download, CONTENT_LENGTH_DOWNLOAD, DBL, 0)
|
||||||
|
OPT_ENTRY( content_length_upload, CONTENT_LENGTH_UPLOAD, DBL, 0)
|
||||||
|
OPT_ENTRY( content_type, CONTENT_TYPE, STR, 0)
|
||||||
|
OPT_ENTRY( httpauth_avail, HTTPAUTH_AVAIL, LNG, 0)
|
||||||
|
OPT_ENTRY( proxyauth_avail, PROXYAUTH_AVAIL, LNG, 0)
|
||||||
|
OPT_ENTRY( os_errno, OS_ERRNO, LNG, 0)
|
||||||
|
OPT_ENTRY( num_connects, NUM_CONNECTS, LNG, 0)
|
||||||
|
OPT_ENTRY( primary_ip, PRIMARY_IP, STR, 0)
|
||||||
|
OPT_ENTRY( primary_port, PRIMARY_PORT, LNG, 0)
|
||||||
|
OPT_ENTRY( local_ip, LOCAL_IP, STR, 0)
|
||||||
|
OPT_ENTRY( local_port, LOCAL_PORT, LNG, 0)
|
||||||
|
OPT_ENTRY( cookielist, COOKIELIST, LST, 0)
|
||||||
|
OPT_ENTRY( lastsocket, LASTSOCKET, LNG, 0)
|
||||||
|
OPT_ENTRY( ftp_entry_path, FTP_ENTRY_PATH, STR, 0)
|
||||||
|
OPT_ENTRY( condition_unmet, CONDITION_UNMET, LNG, 0)
|
||||||
|
OPT_ENTRY( rtsp_session_id, RTSP_SESSION_ID, STR, 0)
|
||||||
|
OPT_ENTRY( rtsp_client_cseq, RTSP_CLIENT_CSEQ, LNG, 0)
|
||||||
|
OPT_ENTRY( rtsp_server_cseq, RTSP_SERVER_CSEQ, LNG, 0)
|
||||||
|
OPT_ENTRY( rtsp_cseq_recv, RTSP_CSEQ_RECV, LNG, 0)
|
||||||
|
|
||||||
|
// OPT_ENTRY( PRIVATE, void )
|
||||||
|
// OPT_ENTRY( CERTINFO, struct curl_certinfo *
|
||||||
|
// OPT_ENTRY( TLS_SESSION, struct curl_tlssessioninfo *
|
159
src/lcopteasy.h
Normal file
159
src/lcopteasy.h
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
#undef INTERFACE
|
||||||
|
#undef BUFFERSIZE
|
||||||
|
#undef TCP_NODELAY
|
||||||
|
#undef TCP_KEEPALIVE
|
||||||
|
|
||||||
|
/* Before version 7.17.0, strings were not copied.
|
||||||
|
Instead the user was forced keep them available
|
||||||
|
until libcurl no longer needed them.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LCURL_STORE_STRING
|
||||||
|
# define LCURL_STORE_STRING 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
OPT_ENTRY( verbose, VERBOSE, LNG, 0 )
|
||||||
|
OPT_ENTRY( header, HEADER, LNG, 0 )
|
||||||
|
OPT_ENTRY( noprogress, NOPROGRESS, LNG, 0 )
|
||||||
|
OPT_ENTRY( nosignal, NOSIGNAL, LNG, 0 )
|
||||||
|
OPT_ENTRY( wildcardmatch, WILDCARDMATCH, LNG, 0 )
|
||||||
|
|
||||||
|
OPT_ENTRY( url, URL, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( failonerror, FAILONERROR, LNG, 0 )
|
||||||
|
|
||||||
|
OPT_ENTRY( protocols, PROTOCOLS, LNG, 0 )
|
||||||
|
OPT_ENTRY( redir_protocols, REDIR_PROTOCOLS, LNG, 0 )
|
||||||
|
OPT_ENTRY( proxy, PROXY, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( proxyport, PROXYPORT, LNG, 0 )
|
||||||
|
OPT_ENTRY( proxytype, PROXYTYPE, LNG, 0 )
|
||||||
|
OPT_ENTRY( noproxy, NOPROXY, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( httpproxytunnel, HTTPPROXYTUNNEL, LNG, 0 )
|
||||||
|
OPT_ENTRY( socks5_gssapi_service, SOCKS5_GSSAPI_SERVICE, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( socks5_gssapi_nec, SOCKS5_GSSAPI_NEC, LNG, 0 )
|
||||||
|
OPT_ENTRY( interface, INTERFACE, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( localport, LOCALPORT, LNG, 0 )
|
||||||
|
OPT_ENTRY( localportrange, LOCALPORTRANGE, LNG, 0 )
|
||||||
|
OPT_ENTRY( dns_cache_timeout, DNS_CACHE_TIMEOUT, LNG, 0 )
|
||||||
|
OPT_ENTRY( dns_use_global_cache, DNS_USE_GLOBAL_CACHE, LNG, 0 )
|
||||||
|
OPT_ENTRY( buffersize, BUFFERSIZE, LNG, 0 )
|
||||||
|
OPT_ENTRY( port, PORT, LNG, 0 )
|
||||||
|
OPT_ENTRY( tcp_nodelay, TCP_NODELAY, LNG, 0 )
|
||||||
|
OPT_ENTRY( address_scope, ADDRESS_SCOPE, LNG, 0 )
|
||||||
|
OPT_ENTRY( tcp_keepalive, TCP_KEEPALIVE, LNG, 0 )
|
||||||
|
OPT_ENTRY( tcp_keepidle, TCP_KEEPIDLE, LNG, 0 )
|
||||||
|
OPT_ENTRY( tcp_keepintvl, TCP_KEEPINTVL, LNG, 0 )
|
||||||
|
|
||||||
|
OPT_ENTRY( netrc, NETRC, LNG, 0 )
|
||||||
|
OPT_ENTRY( netrc_file, NETRC_FILE, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( userpwd, USERPWD, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( proxyuserpwd, PROXYUSERPWD, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( username, USERNAME, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( password, PASSWORD, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( login_options, LOGIN_OPTIONS, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( proxyusername, PROXYUSERNAME, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( proxypassword, PROXYPASSWORD, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( httpauth, HTTPAUTH, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( tlsauth_username, TLSAUTH_USERNAME, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( tlsauth_password, TLSAUTH_PASSWORD, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( proxyauth, PROXYAUTH, LNG, 0 )
|
||||||
|
OPT_ENTRY( sasl_ir, SASL_IR, LNG, 0 )
|
||||||
|
OPT_ENTRY( xoauth2_bearer, XOAUTH2_BEARER, STR, LCURL_STORE_STRING )
|
||||||
|
|
||||||
|
OPT_ENTRY( autoreferer, AUTOREFERER, LNG, 0 )
|
||||||
|
OPT_ENTRY( accept_encoding, ACCEPT_ENCODING, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( transfer_encoding, TRANSFER_ENCODING, LNG, 0 )
|
||||||
|
OPT_ENTRY( followlocation, FOLLOWLOCATION, LNG, 0 )
|
||||||
|
OPT_ENTRY( unrestricted_auth, UNRESTRICTED_AUTH, LNG, 0 )
|
||||||
|
OPT_ENTRY( maxredirs, MAXREDIRS, LNG, 0 )
|
||||||
|
OPT_ENTRY( postredir, POSTREDIR, LNG, 0 )
|
||||||
|
OPT_ENTRY( put, PUT, LNG, 0 )
|
||||||
|
OPT_ENTRY( post, POST, LNG, 0 )
|
||||||
|
OPT_ENTRY( referer, REFERER, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( useragent, USERAGENT, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( headeropt, HEADEROPT, LNG, 0 )
|
||||||
|
OPT_ENTRY( httpheader, HTTPHEADER, LST, 0 )
|
||||||
|
OPT_ENTRY( proxyheader, PROXYHEADER, LST, 0 )
|
||||||
|
OPT_ENTRY( http200aliases, HTTP200ALIASES, LST, 0 )
|
||||||
|
OPT_ENTRY( cookie, COOKIE, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( cookiefile, COOKIEFILE, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( cookiejar, COOKIEJAR, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( cookiesession, COOKIESESSION, LNG, 0 )
|
||||||
|
OPT_ENTRY( cookielist, COOKIELIST, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( httpget, HTTPGET, LNG, 0 )
|
||||||
|
OPT_ENTRY( http_version, HTTP_VERSION, LNG, 0 )
|
||||||
|
OPT_ENTRY( ignore_content_length, IGNORE_CONTENT_LENGTH, LNG, 0 )
|
||||||
|
OPT_ENTRY( http_content_decoding, HTTP_CONTENT_DECODING, LNG, 0 )
|
||||||
|
OPT_ENTRY( http_transfer_decoding, HTTP_TRANSFER_DECODING, LNG, 0 )
|
||||||
|
OPT_ENTRY( expect_100_timeout_ms, EXPECT_100_TIMEOUT_MS, LNG, 0 )
|
||||||
|
|
||||||
|
OPT_ENTRY( mail_from, MAIL_FROM, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( mail_rcpt, MAIL_RCPT, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( mail_auth, MAIL_AUTH, STR, LCURL_STORE_STRING )
|
||||||
|
|
||||||
|
OPT_ENTRY( tftp_blksize, TFTP_BLKSIZE, LNG, 0 )
|
||||||
|
|
||||||
|
OPT_ENTRY( ftpport, FTPPORT, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( quote, QUOTE, LST, 0 )
|
||||||
|
OPT_ENTRY( postquote, POSTQUOTE, LST, 0 )
|
||||||
|
OPT_ENTRY( prequote, PREQUOTE, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( dirlistonly, DIRLISTONLY, LNG, 0 )
|
||||||
|
OPT_ENTRY( append, APPEND, LNG, 0 )
|
||||||
|
OPT_ENTRY( ftp_use_eprt, FTP_USE_EPRT, LNG, 0 )
|
||||||
|
OPT_ENTRY( ftp_use_epsv, FTP_USE_EPSV, LNG, 0 )
|
||||||
|
OPT_ENTRY( ftp_use_pret, FTP_USE_PRET, LNG, 0 )
|
||||||
|
OPT_ENTRY( ftp_create_missing_dirs, FTP_CREATE_MISSING_DIRS, LNG, 0 )
|
||||||
|
OPT_ENTRY( ftp_response_timeout, FTP_RESPONSE_TIMEOUT, LNG, 0 )
|
||||||
|
OPT_ENTRY( ftp_alternative_to_user, FTP_ALTERNATIVE_TO_USER, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( ftp_skip_pasv_ip, FTP_SKIP_PASV_IP, LNG, 0 )
|
||||||
|
OPT_ENTRY( ftpsslauth, FTPSSLAUTH, LNG, 0 )
|
||||||
|
OPT_ENTRY( ftp_ssl_ccc, FTP_SSL_CCC, LNG, 0 )
|
||||||
|
OPT_ENTRY( ftp_account, FTP_ACCOUNT, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( ftp_filemethod, FTP_FILEMETHOD, LNG, 0 )
|
||||||
|
|
||||||
|
OPT_ENTRY( transfertext, TRANSFERTEXT, LNG, 0 )
|
||||||
|
OPT_ENTRY( proxy_transfer_mode, PROXY_TRANSFER_MODE, LNG, 0 )
|
||||||
|
OPT_ENTRY( crlf, CRLF, LNG, 0 )
|
||||||
|
OPT_ENTRY( range, RANGE, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( resume_from, RESUME_FROM, LNG, 0 )
|
||||||
|
OPT_ENTRY( resume_from_large, RESUME_FROM_LARGE, LNG, 0 )
|
||||||
|
OPT_ENTRY( customrequest, CUSTOMREQUEST, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( filetime, FILETIME, LNG, 0 )
|
||||||
|
OPT_ENTRY( nobody, NOBODY, LNG, 0 )
|
||||||
|
OPT_ENTRY( infilesize, INFILESIZE, LNG, 0 )
|
||||||
|
OPT_ENTRY( infilesize_large, INFILESIZE_LARGE, LNG, 0 )
|
||||||
|
OPT_ENTRY( upload, UPLOAD, LNG, 0 )
|
||||||
|
OPT_ENTRY( maxfilesize, MAXFILESIZE, LNG, 0 )
|
||||||
|
OPT_ENTRY( maxfilesize_large, MAXFILESIZE_LARGE, LNG, 0 )
|
||||||
|
OPT_ENTRY( timecondition, TIMECONDITION, LNG, 0 )
|
||||||
|
OPT_ENTRY( timevalue, TIMEVALUE, LNG, 0 )
|
||||||
|
|
||||||
|
OPT_ENTRY( timeout, TIMEOUT, LNG, 0 )
|
||||||
|
OPT_ENTRY( timeout_ms, TIMEOUT_MS, LNG, 0 )
|
||||||
|
OPT_ENTRY( low_speed_limit, LOW_SPEED_LIMIT, LNG, 0 )
|
||||||
|
OPT_ENTRY( low_speed_time, LOW_SPEED_TIME, LNG, 0 )
|
||||||
|
OPT_ENTRY( max_send_speed_large, MAX_SEND_SPEED_LARGE, LNG, 0 )
|
||||||
|
OPT_ENTRY( max_recv_speed_large, MAX_RECV_SPEED_LARGE, LNG, 0 )
|
||||||
|
OPT_ENTRY( maxconnects, MAXCONNECTS, LNG, 0 )
|
||||||
|
OPT_ENTRY( fresh_connect, FRESH_CONNECT, LNG, 0 )
|
||||||
|
OPT_ENTRY( forbid_reuse, FORBID_REUSE, LNG, 0 )
|
||||||
|
OPT_ENTRY( connecttimeout, CONNECTTIMEOUT, LNG, 0 )
|
||||||
|
OPT_ENTRY( connecttimeout_ms, CONNECTTIMEOUT_MS, LNG, 0 )
|
||||||
|
OPT_ENTRY( ipresolve, IPRESOLVE, LNG, 0 )
|
||||||
|
OPT_ENTRY( connect_only, CONNECT_ONLY, LNG, 0 )
|
||||||
|
OPT_ENTRY( use_ssl, USE_SSL, LNG, 0 )
|
||||||
|
OPT_ENTRY( resolve, RESOLVE, LST, 0 )
|
||||||
|
OPT_ENTRY( dns_interface, DNS_INTERFACE, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( dns_local_ip4, DNS_LOCAL_IP4, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( dns_local_ip6, DNS_LOCAL_IP6, STR, LCURL_STORE_STRING )
|
||||||
|
OPT_ENTRY( accepttimeout_ms, ACCEPTTIMEOUT_MS, LNG, 0 )
|
||||||
|
|
||||||
|
OPT_ENTRY( ssh_auth_types, SSH_AUTH_TYPES, LNG, 0)
|
||||||
|
OPT_ENTRY( ssh_host_public_key_md5, SSH_HOST_PUBLIC_KEY_MD5, STR, 0)
|
||||||
|
OPT_ENTRY( ssh_public_keyfile, SSH_PUBLIC_KEYFILE, STR, 0)
|
||||||
|
OPT_ENTRY( ssh_private_keyfile, SSH_PRIVATE_KEYFILE, STR, 0)
|
||||||
|
OPT_ENTRY( ssh_knownhosts, SSH_KNOWNHOSTS, STR, 0)
|
||||||
|
|
||||||
|
OPT_ENTRY( new_file_perms, NEW_FILE_PERMS, LNG, 0)
|
||||||
|
OPT_ENTRY( new_directory_perms, NEW_DIRECTORY_PERMS, LNG, 0)
|
||||||
|
|
||||||
|
OPT_ENTRY( telnetoptions, TELNETOPTIONS, LST, 0)
|
73
src/lcurl.c
Normal file
73
src/lcurl.c
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#include "lcurl.h"
|
||||||
|
#include "lceasy.h"
|
||||||
|
#include "lcerror.h"
|
||||||
|
#include "lchttppost.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int lcurl_easy_new_safe(lua_State *L){
|
||||||
|
return lcurl_easy_create(L, LCURL_ERROR_RETURN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_hpost_new_safe(lua_State *L){
|
||||||
|
return lcurl_hpost_create(L, LCURL_ERROR_RETURN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_easy_new(lua_State *L){
|
||||||
|
return lcurl_easy_create(L, LCURL_ERROR_RAISE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lcurl_hpost_new(lua_State *L){
|
||||||
|
return lcurl_hpost_create(L, LCURL_ERROR_RAISE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct luaL_Reg lcurl_functions[] = {
|
||||||
|
{"error", lcurl_error_new },
|
||||||
|
{"httppost", lcurl_hpost_new },
|
||||||
|
{"easy", lcurl_easy_new },
|
||||||
|
|
||||||
|
{NULL,NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct luaL_Reg lcurl_functions_safe[] = {
|
||||||
|
{"error", lcurl_error_new },
|
||||||
|
{"httppost", lcurl_hpost_new_safe },
|
||||||
|
{"easy", lcurl_easy_new_safe },
|
||||||
|
|
||||||
|
{NULL,NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static volatile int LCURL_INIT = 0;
|
||||||
|
|
||||||
|
static const char* LCURL_REGISTRY = "LCURL Registry";
|
||||||
|
|
||||||
|
static int luaopen_lcurl_(lua_State *L, const struct luaL_Reg *func){
|
||||||
|
if(!LCURL_INIT){
|
||||||
|
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||||
|
LCURL_INIT = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_rawgetp(L, LUA_REGISTRYINDEX, LCURL_REGISTRY);
|
||||||
|
if(!lua_istable(L, -1)){ /* registry */
|
||||||
|
lua_pop(L, 1);
|
||||||
|
lua_newtable(L);
|
||||||
|
}
|
||||||
|
lua_newtable(L); /* library */
|
||||||
|
|
||||||
|
lua_pushvalue(L, -2); luaL_setfuncs(L, func, 1);
|
||||||
|
lua_pushvalue(L, -2); lcurl_error_initlib(L, 1);
|
||||||
|
lua_pushvalue(L, -2); lcurl_hpost_initlib(L, 1);
|
||||||
|
lua_pushvalue(L, -2); lcurl_easy_initlib (L, 1);
|
||||||
|
|
||||||
|
lua_pushvalue(L, -2); lua_rawsetp(L, LUA_REGISTRYINDEX, LCURL_REGISTRY);
|
||||||
|
|
||||||
|
lua_remove(L, -2); /* registry */
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
__declspec(dllexport)
|
||||||
|
int luaopen_lcurl(lua_State *L){ return luaopen_lcurl_(L, lcurl_functions); }
|
||||||
|
|
||||||
|
__declspec(dllexport)
|
||||||
|
int luaopen_lcurl_safe(lua_State *L){ return luaopen_lcurl_(L, lcurl_functions_safe); }
|
||||||
|
|
16
src/lcurl.h
Normal file
16
src/lcurl.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef _LCURL_H_
|
||||||
|
#define _LCURL_H_
|
||||||
|
|
||||||
|
#include "l52util.h"
|
||||||
|
#include "curl/curl.h"
|
||||||
|
#include "curl/easy.h"
|
||||||
|
#include "curl/multi.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#define LCURL_PREFIX "LcURL"
|
||||||
|
|
||||||
|
#define LCURL_LUA_REGISTRY lua_upvalueindex(1)
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
101
src/lcutils.c
Normal file
101
src/lcutils.c
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#include "lcurl.h"
|
||||||
|
#include "lcutils.h"
|
||||||
|
#include "lcerror.h"
|
||||||
|
|
||||||
|
int lcurl_storage_init(lua_State *L){
|
||||||
|
lua_newtable(L);
|
||||||
|
return luaL_ref(L, LCURL_LUA_REGISTRY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcurl_storage_preserve_value(lua_State *L, int storage, int i){
|
||||||
|
assert(i > 0);
|
||||||
|
luaL_checkany(L, i);
|
||||||
|
lua_rawgeti(L, LCURL_LUA_REGISTRY, storage);
|
||||||
|
lua_pushvalue(L, i); lua_pushboolean(L, 1); lua_rawset(L, -3);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int lcurl_storage_preserve_slist(lua_State *L, int storage, struct curl_slist * list){
|
||||||
|
int r;
|
||||||
|
lua_rawgeti(L, LCURL_LUA_REGISTRY, storage);
|
||||||
|
lua_rawgeti(L, -1, 1); // list storage
|
||||||
|
if(!lua_istable(L, -1)){
|
||||||
|
lua_pop(L, 1);
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_pushvalue(L, -1);
|
||||||
|
lua_rawseti(L, -3, 1);
|
||||||
|
}
|
||||||
|
lua_pushlightuserdata(L, list);
|
||||||
|
r = luaL_ref(L, -2);
|
||||||
|
lua_pop(L, 2);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct curl_slist* lcurl_storage_remove_slist(lua_State *L, int storage, int idx){
|
||||||
|
struct curl_slist* list;
|
||||||
|
assert(idx != LUA_NOREF);
|
||||||
|
lua_rawgeti(L, LCURL_LUA_REGISTRY, storage);
|
||||||
|
lua_rawgeti(L, -1, 1); // list storage
|
||||||
|
lua_rawgeti(L, -1, idx);
|
||||||
|
list = lua_touserdata(L, -1);
|
||||||
|
assert(list);
|
||||||
|
luaL_unref(L, -2, idx);
|
||||||
|
lua_pop(L, 3);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void lcurl_storage_free(lua_State *L, int storage){
|
||||||
|
lua_rawgeti(L, LCURL_LUA_REGISTRY, storage);
|
||||||
|
lua_rawgeti(L, -1, 1); // list storage
|
||||||
|
if(lua_istable(L, -1)){
|
||||||
|
lua_pushnil(L);
|
||||||
|
while(lua_next(L, -2) != 0){
|
||||||
|
struct curl_slist * list = lua_touserdata(L, -1);
|
||||||
|
curl_slist_free_all(list);
|
||||||
|
lua_pushvalue(L, -2); lua_pushnil(L);
|
||||||
|
lua_rawset(L, -5);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
luaL_unref(L, LCURL_LUA_REGISTRY, storage);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct curl_slist* lcurl_util_array_to_slist(lua_State *L, int t){
|
||||||
|
struct curl_slist *list = NULL;
|
||||||
|
int i, n = lua_rawlen(L, t);
|
||||||
|
|
||||||
|
assert(lua_type(L, t) == LUA_TTABLE);
|
||||||
|
|
||||||
|
for(i = 1; i <= n; ++i){
|
||||||
|
lua_rawgeti(L, t, i);
|
||||||
|
list = curl_slist_append(list, lua_tostring(L, -1));
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct curl_slist* lcurl_util_to_slist(lua_State *L, int t){
|
||||||
|
if(lua_type(L, t) == LUA_TTABLE){
|
||||||
|
return lcurl_util_array_to_slist(L, t);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcurl_util_slist_set(lua_State *L, int t, struct curl_slist* list){
|
||||||
|
int i;
|
||||||
|
t = lua_absindex(L, t);
|
||||||
|
for(i = 0;list;list = list->next){
|
||||||
|
lua_pushstring(L, list->data);
|
||||||
|
lua_rawseti(L, t, ++i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void lcurl_util_slist_to_table(lua_State *L, struct curl_slist* list){
|
||||||
|
lua_newtable(L);
|
||||||
|
lcurl_util_slist_set(L, -1, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
24
src/lcutils.h
Normal file
24
src/lcutils.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#ifndef _LCUTILS_H_
|
||||||
|
#define _LCUTILS_H_
|
||||||
|
|
||||||
|
#include "lcurl.h"
|
||||||
|
|
||||||
|
int lcurl_storage_init(lua_State *L);
|
||||||
|
|
||||||
|
void lcurl_storage_preserve_value(lua_State *L, int storage, int i);
|
||||||
|
|
||||||
|
int lcurl_storage_preserve_slist(lua_State *L, int storage, struct curl_slist * list);
|
||||||
|
|
||||||
|
struct curl_slist* lcurl_storage_remove_slist(lua_State *L, int storage, int idx);
|
||||||
|
|
||||||
|
void lcurl_storage_free(lua_State *L, int storage);
|
||||||
|
|
||||||
|
struct curl_slist* lcurl_util_array_to_slist(lua_State *L, int t);
|
||||||
|
|
||||||
|
struct curl_slist* lcurl_util_to_slist(lua_State *L, int t);
|
||||||
|
|
||||||
|
void lcurl_util_slist_set(lua_State *L, int t, struct curl_slist* list);
|
||||||
|
|
||||||
|
void lcurl_util_slist_to_table(lua_State *L, struct curl_slist* list);
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user