Skip to content

Commit 0e1eaa5

Browse files
committed
Add. New cURL MIME API
1 parent 14a9246 commit 0e1eaa5

18 files changed

Lines changed: 1116 additions & 131 deletions

.travis.yml

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,17 @@ env:
99

1010
matrix:
1111
include:
12-
- compiler: ": Lua51-osx"
13-
env: LUA="lua 5.1"
12+
- env: LUA="lua 5.1"
1413
os: osx
15-
- compiler: ": Lua51"
16-
env: LUA="lua 5.1"
14+
- env: LUA="lua 5.1"
1715
os: linux
18-
- compiler: ": Lua52"
19-
env: LUA="lua 5.2"
16+
- env: LUA="lua 5.2"
2017
os: linux
21-
- compiler: ": Lua53"
22-
env: LUA="lua 5.3"
18+
- env: LUA="lua 5.3"
2319
os: linux
24-
- compiler: ": LuaJIT20"
25-
env: LUA="luajit 2.0"
20+
- env: LUA="luajit 2.0"
2621
os: linux
27-
- compiler: ": LuaJIT21"
28-
env: LUA="luajit 2.1"
22+
- env: LUA="luajit 2.1"
2923
os: linux
3024

3125
cache:
@@ -36,10 +30,9 @@ cache:
3630
branches:
3731
only:
3832
- master
33+
- curl_mime
3934

4035
before_install:
41-
- export CC=gcc
42-
- gcc --version
4336
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export PATH=$PATH:~/Library/Python/2.7/bin/; fi
4437
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then export LCURL_LD_FLAGS="-bundle -undefined dynamic_lookup -all_load --coverage"; fi
4538
- pip install --user cpp-coveralls
@@ -68,6 +61,13 @@ script:
6861
# - lunit.sh test_form.lua
6962
# - lunit.sh test_curl.lua
7063

64+
before_cache:
65+
# - cd $TRAVIS_BUILD_DIR/test
66+
# - coveralls -b .. -r .. --dump c.report.json
67+
# - luacov-coveralls -j c.report.json -v
68+
# - luarocks remove lluv-gsmmodem
69+
# - rm -f /home/travis/.cache/pip/log/debug.log
70+
7171
after_success:
7272
- coveralls -b .. -r .. --dump c.report.json
7373
- luacov-coveralls -j c.report.json -v

appveyor.yml

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

88
environment:
99
LR_EXTERNAL: c:\external
10-
CURL_VER: 7.55.1
10+
CURL_VER: 7.56.0
1111

1212
matrix:
1313
- LUA: "lua 5.1"

examples/lcurl/smtp-mime.lua

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
local curl = require "lcurl"
2+
3+
local SMTP = {
4+
url = "smtp://mail.example.com";
5+
}
6+
7+
local FROM = "<sender@example.org>"
8+
local TO = "<addressee@example.net>"
9+
local CC = "<info@example.org>"
10+
local FILE = "smtp-mime.lua" -- if you send this file do not forget it may have mail password
11+
local CT_FILE = "application/lua"
12+
13+
local DUMP_MIME = false
14+
15+
local headers = {
16+
"Date: Tue, 22 Aug 2017 14:08:43 +0100",
17+
"To: " .. TO,
18+
"From: " .. FROM .. " (Example User)",
19+
"Cc: " .. CC .. " (Another example User)",
20+
"Message-ID: <dcd7cb36-11db-487a-9f3a-e652a9458efd@rfcpedant.example.org>",
21+
"Subject: example sending a MIME-formatted message",
22+
}
23+
24+
local inline_text = ""
25+
.. "This is the inline text message of the e-mail.\r\n"
26+
.. "\r\n"
27+
.. " It could be a lot of lines that would be displayed in an e-mail\r\n"
28+
.. "viewer that is not able to handle HTML.\r\n"
29+
30+
local inline_html = ""
31+
.. "<html><body>\r\n"
32+
.. "<p>This is the inline <b>HTML</b> message of the e-mail.</p>"
33+
.. "<br />\r\n"
34+
.. "<p>It could be a lot of HTML data that would be displayed by "
35+
.. "e-mail viewers able to handle HTML.</p>"
36+
.. "</body></html>\r\n"
37+
38+
local function dump_mime(type, data)
39+
if type == curl.INFO_DATA_OUT then io.write(data) end
40+
end
41+
42+
local easy = curl.easy()
43+
44+
local mime = easy:mime() do
45+
local alt = easy:mime()
46+
alt
47+
:addpart()
48+
:data(inline_html, "text/html")
49+
alt
50+
:addpart()
51+
:data(inline_text)
52+
mime:addpart()
53+
:subparts(alt, "multipart/alternative", {
54+
"Content-Disposition: inline"
55+
})
56+
mime
57+
:addpart()
58+
:filedata(FILE, CT_FILE)
59+
end
60+
61+
easy:setopt{
62+
url = SMTP.url,
63+
mail_from = FROM,
64+
mail_rcpt = {TO, CC},
65+
httpheader = headers;
66+
mimepost = mime;
67+
ssl_verifyhost = false;
68+
ssl_verifypeer = false;
69+
username = SMTP.user;
70+
password = SMTP.password;
71+
upload = true;
72+
}
73+
74+
if DUMP_MIME then
75+
easy:setopt{
76+
verbose = true;
77+
debugfunction = dump_mime;
78+
}
79+
end
80+
81+
easy:perform()
82+
83+
easy:close()
84+
85+
mime:free()

rockspecs/lua-curl-scm-0.rockspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ build = {
6363
sources = {
6464
"src/l52util.c", "src/lceasy.c", "src/lcerror.c",
6565
"src/lchttppost.c", "src/lcurl.c", "src/lcutils.c",
66-
"src/lcmulti.c", "src/lcshare.c",
66+
"src/lcmulti.c", "src/lcshare.c","src/lcmime.c",
6767
},
6868
incdirs = { "$(CURL_INCDIR)" },
6969
libdirs = { "$(CURL_LIBDIR)" }

src/lceasy.c

Lines changed: 89 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/******************************************************************************
22
* Author: Alexey Melnichuk <mimir@newmail.ru>
33
*
4-
* Copyright (C) 2014 Alexey Melnichuk <mimir@newmail.ru>
4+
* Copyright (C) 2014-2017 Alexey Melnichuk <mimir@newmail.ru>
55
*
66
* Licensed according to the included 'LICENSE' document
77
*
@@ -15,6 +15,7 @@
1515
#include "lchttppost.h"
1616
#include "lcshare.h"
1717
#include "lcmulti.h"
18+
#include "lcmime.h"
1819
#include <memory.h>
1920

2021
static const char *LCURL_ERROR_TAG = "LCURL_ERROR_TAG";
@@ -29,7 +30,7 @@ static const char *LCURL_EASY = LCURL_EASY_NAME;
2930
#endif
3031

3132
/* Before call curl_XXX function which can call any callback
32-
* need set Curren Lua thread pointer in easy/multi contexts.
33+
* need set Current Lua thread pointer in easy/multi contexts.
3334
* But it also possible that we already in callback call.
3435
* E.g. `curl_easy_pause` function may be called from write callback.
3536
* and it even may be called in different thread.
@@ -41,7 +42,7 @@ static const char *LCURL_EASY = LCURL_EASY_NAME;
4142
* ```
4243
* So we have to restore previews Lua state in callback contexts.
4344
* But if previews Lua state is NULL then we can just do not set it back.
44-
* But set it to NULL make esier debug code.
45+
* But set it to NULL make easier to debug code.
4546
*/
4647
void lcurl__easy_assign_lua(lua_State *L, lcurl_easy_t *p, lua_State *value, int assign_multi){
4748
if(p->multi && assign_multi){
@@ -52,6 +53,11 @@ void lcurl__easy_assign_lua(lua_State *L, lcurl_easy_t *p, lua_State *value, int
5253
if(p->post){
5354
p->post->L = value;
5455
}
56+
#if LCURL_CURL_VER_GE(7,56,0)
57+
if(p->mime){
58+
lcurl_mime_set_lua(L, p->mime, value);
59+
}
60+
#endif
5561
}
5662
}
5763

@@ -74,6 +80,9 @@ int lcurl_easy_create(lua_State *L, int error_mode){
7480
p->L = NULL;
7581
p->post = NULL;
7682
p->multi = NULL;
83+
#if LCURL_CURL_VER_GE(7,56,0)
84+
p->mime = NULL;
85+
#endif
7786
p->storage = lcurl_storage_init(L);
7887
p->wr.cb_ref = p->wr.ud_ref = LUA_NOREF;
7988
p->rd.cb_ref = p->rd.ud_ref = LUA_NOREF;
@@ -125,6 +134,8 @@ static int lcurl_easy_cleanup(lua_State *L){
125134

126135
// In my tests when I cleanup some easy handle.
127136
// timerfunction called only for single multi handle.
137+
// Also may be this function may call `close` callback
138+
// for `curl_mimepart` structure.
128139
curL = p->L; lcurl__easy_assign_lua(L, p, L, 1);
129140
curl_easy_cleanup(p->curl);
130141
#ifndef LCURL_RESET_NULL_LUA
@@ -135,6 +146,11 @@ static int lcurl_easy_cleanup(lua_State *L){
135146
p->curl = NULL;
136147
}
137148

149+
p->post = NULL;
150+
#if LCURL_CURL_VER_GE(7,56,0)
151+
p->mime = NULL;
152+
#endif
153+
138154
if(p->storage != LUA_NOREF){
139155
p->storage = lcurl_storage_free(L, p->storage);
140156
}
@@ -266,6 +282,15 @@ static int lcurl_easy_reset(lua_State *L){
266282
return 1;
267283
}
268284

285+
#if LCURL_CURL_VER_GE(7,56,0)
286+
287+
static int lcurl_easy_mime(lua_State *L){
288+
lcurl_easy_t *p = lcurl_geteasy(L);
289+
return lcurl_mime_create(L, p->err_mode);
290+
}
291+
292+
#endif
293+
269294
//{ OPTIONS
270295

271296
//{ set
@@ -447,6 +472,26 @@ static int lcurl_easy_set_STREAM_DEPENDS_E(lua_State *L){
447472

448473
#endif
449474

475+
#if LCURL_CURL_VER_GE(7,56,0)
476+
477+
static int lcurl_easy_set_MIMEPOST(lua_State *L){
478+
lcurl_easy_t *p = lcurl_geteasy(L);
479+
lcurl_mime_t *mime = lcurl_getmime_at(L, 2);
480+
CURLcode code = curl_easy_setopt(p->curl, CURLOPT_MIMEPOST, mime->mime);
481+
if(code != CURLE_OK){
482+
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
483+
}
484+
485+
lcurl_storage_preserve_iv(L, p->storage, CURLOPT_MIMEPOST, 2);
486+
487+
p->mime = mime;
488+
489+
lua_settop(L, 1);
490+
return 1;
491+
}
492+
493+
#endif
494+
450495
//}
451496

452497
//{ unset
@@ -775,6 +820,25 @@ static int lcurl_easy_unset_STREAM_DEPENDS_E(lua_State *L){
775820

776821
#endif
777822

823+
#if LCURL_CURL_VER_GE(7,56,0)
824+
825+
static int lcurl_easy_unset_MIMEPOST(lua_State *L){
826+
lcurl_easy_t *p = lcurl_geteasy(L);
827+
CURLcode code = curl_easy_setopt(p->curl, CURLOPT_MIMEPOST, NULL);
828+
if(code != CURLE_OK){
829+
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_EASY, code);
830+
}
831+
832+
lcurl_storage_remove_i(L, p->storage, CURLOPT_MIMEPOST);
833+
834+
p->mime = NULL;
835+
836+
lua_settop(L, 1);
837+
return 1;
838+
}
839+
840+
#endif
841+
778842
//}
779843

780844
//}
@@ -1004,7 +1068,7 @@ static int lcurl_easy_set_WRITEFUNCTION(lua_State *L){
10041068

10051069
//{ Reader
10061070

1007-
static size_t lcurl_read_callback(lua_State *L,
1071+
size_t lcurl_read_callback(lua_State *L,
10081072
lcurl_callback_t *rd, lcurl_read_buffer_t *rbuffer,
10091073
char *buffer, size_t size, size_t nitems
10101074
){
@@ -1477,6 +1541,9 @@ static int lcurl_easy_setopt(lua_State *L){
14771541
#if LCURL_CURL_VER_GE(7,46,0)
14781542
OPT_ENTRY(stream_depends, STREAM_DEPENDS, TTT, 0, 0)
14791543
OPT_ENTRY(stream_depends_e, STREAM_DEPENDS_E, TTT, 0, 0)
1544+
#endif
1545+
#if LCURL_CURL_VER_GE(7,56,0)
1546+
OPT_ENTRY(mimepost, MIMEPOST, TTT, 0, 0)
14801547
#endif
14811548
}
14821549
#undef OPT_ENTRY
@@ -1511,6 +1578,9 @@ static int lcurl_easy_unsetopt(lua_State *L){
15111578
#if LCURL_CURL_VER_GE(7,46,0)
15121579
OPT_ENTRY(stream_depends, STREAM_DEPENDS, TTT, 0, 0)
15131580
OPT_ENTRY(stream_depends_e, STREAM_DEPENDS_E, TTT, 0, 0)
1581+
#endif
1582+
#if LCURL_CURL_VER_GE(7,56,0)
1583+
OPT_ENTRY(mimepost, MIMEPOST, TTT, 0, 0)
15141584
#endif
15151585
}
15161586
#undef OPT_ENTRY
@@ -1582,14 +1652,17 @@ static const struct luaL_Reg lcurl_easy_methods[] = {
15821652
OPT_ENTRY(seekfunction, SEEKFUNCTION, TTT, 0, 0)
15831653
OPT_ENTRY(debugfunction, DEBUGFUNCTION, TTT, 0, 0)
15841654
#if LCURL_CURL_VER_GE(7,21,0)
1585-
OPT_ENTRY(fnmatch_function, FNMATCH_FUNCTION, TTT, 0, 0)
1655+
OPT_ENTRY(fnmatch_function, FNMATCH_FUNCTION, TTT, 0, 0)
15861656
OPT_ENTRY(chunk_bgn_function, CHUNK_BGN_FUNCTION, TTT, 0, 0)
15871657
OPT_ENTRY(chunk_end_function, CHUNK_END_FUNCTION, TTT, 0, 0)
15881658
#endif
15891659
#if LCURL_CURL_VER_GE(7,46,0)
15901660
OPT_ENTRY(stream_depends, STREAM_DEPENDS, TTT, 0, 0)
15911661
OPT_ENTRY(stream_depends_e, STREAM_DEPENDS_E, TTT, 0, 0)
15921662
#endif
1663+
#if LCURL_CURL_VER_GE(7,56,0)
1664+
OPT_ENTRY(mimepost, MIMEPOST, TTT, 0, 0)
1665+
#endif
15931666
#undef OPT_ENTRY
15941667

15951668
#define OPT_ENTRY(L, N, T, S, D) { "unsetopt_"#L, lcurl_easy_unset_##N },
@@ -1604,20 +1677,27 @@ static const struct luaL_Reg lcurl_easy_methods[] = {
16041677
OPT_ENTRY(seekfunction, SEEKFUNCTION, TTT, 0, 0)
16051678
OPT_ENTRY(debugfunction, DEBUGFUNCTION, TTT, 0, 0)
16061679
#if LCURL_CURL_VER_GE(7,21,0)
1607-
OPT_ENTRY(fnmatch_function, FNMATCH_FUNCTION, TTT, 0, 0)
1680+
OPT_ENTRY(fnmatch_function, FNMATCH_FUNCTION, TTT, 0, 0)
16081681
OPT_ENTRY(chunk_bgn_function, CHUNK_BGN_FUNCTION, TTT, 0, 0)
16091682
OPT_ENTRY(chunk_end_function, CHUNK_END_FUNCTION, TTT, 0, 0)
16101683
#endif
16111684
#if LCURL_CURL_VER_GE(7,46,0)
16121685
OPT_ENTRY(stream_depends, STREAM_DEPENDS, TTT, 0, 0)
16131686
OPT_ENTRY(stream_depends_e, STREAM_DEPENDS_E, TTT, 0, 0)
16141687
#endif
1688+
#if LCURL_CURL_VER_GE(7,56,0)
1689+
OPT_ENTRY(mimepost, MIMEPOST, TTT, 0, 0)
1690+
#endif
16151691
#undef OPT_ENTRY
16161692

16171693
#define OPT_ENTRY(L, N, T, S) { "getinfo_"#L, lcurl_easy_get_##N },
16181694
#include "lcinfoeasy.h"
16191695
#undef OPT_ENTRY
16201696

1697+
#if LCURL_CURL_VER_GE(7,56,0)
1698+
{ "mime", lcurl_easy_mime },
1699+
#endif
1700+
16211701
{ "pause", lcurl_easy_pause },
16221702
{ "reset", lcurl_easy_reset },
16231703
{ "setopt", lcurl_easy_setopt },
@@ -1659,6 +1739,9 @@ static const lcurl_const_t lcurl_easy_opt[] = {
16591739
OPT_ENTRY(stream_depends, STREAM_DEPENDS, TTT, 0, 0)
16601740
OPT_ENTRY(stream_depends_e, STREAM_DEPENDS_E, TTT, 0, 0)
16611741
#endif
1742+
#if LCURL_CURL_VER_GE(7,56,0)
1743+
OPT_ENTRY(mimepost, MIMEPOST, TTT, 0, 0)
1744+
#endif
16621745
#undef OPT_ENTRY
16631746
#undef FLG_ENTRY
16641747

0 commit comments

Comments
 (0)