diff options
author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-01-21 01:09:50 +0000 |
---|---|---|
committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2004-01-21 01:09:50 +0000 |
commit | 3a7ac1e04361e12ddfcbf344e9e1db82fb88157b (patch) | |
tree | 166d452836a474541e1054f77b0b586bbe68dd6e | |
parent | 0b61b577f5d65a9c8bd5e690c4010c1e28b70e66 (diff) | |
download | luasocket-3a7ac1e04361e12ddfcbf344e9e1db82fb88157b.tar.gz luasocket-3a7ac1e04361e12ddfcbf344e9e1db82fb88157b.tar.bz2 luasocket-3a7ac1e04361e12ddfcbf344e9e1db82fb88157b.zip |
Changed the naming convention of the mime module.
Looks beautiful.
-rw-r--r-- | TODO | 3 | ||||
-rw-r--r-- | etc/get.lua | 20 | ||||
-rw-r--r-- | luasocket.vcproj | 2 | ||||
-rw-r--r-- | src/mime.c | 80 | ||||
-rw-r--r-- | src/mime.lua | 92 | ||||
-rw-r--r-- | test/httptest.lua | 124 | ||||
-rw-r--r-- | test/mimetest.lua | 30 |
7 files changed, 234 insertions, 117 deletions
@@ -19,6 +19,9 @@ tests | |||
19 | checar garbage collection | 19 | checar garbage collection |
20 | check for interrupts | 20 | check for interrupts |
21 | 21 | ||
22 | trust character constants in mime.c? noooooo. | ||
23 | smtp.lua needs stuff filter | ||
24 | |||
22 | new option.c module to put all options (TCP and UDP share...)? | 25 | new option.c module to put all options (TCP and UDP share...)? |
23 | testar os options! | 26 | testar os options! |
24 | add _tostring methods! | 27 | add _tostring methods! |
diff --git a/etc/get.lua b/etc/get.lua index 9f29a51..d6760b8 100644 --- a/etc/get.lua +++ b/etc/get.lua | |||
@@ -19,7 +19,7 @@ function nicetime(s) | |||
19 | end | 19 | end |
20 | end | 20 | end |
21 | end | 21 | end |
22 | if l == "s" then return string.format("%2.0f%s", s, l) | 22 | if l == "s" then return string.format("%5.0f%s", s, l) |
23 | else return string.format("%5.2f%s", s, l) end | 23 | else return string.format("%5.2f%s", s, l) end |
24 | end | 24 | end |
25 | 25 | ||
@@ -42,20 +42,16 @@ function nicesize(b) | |||
42 | end | 42 | end |
43 | 43 | ||
44 | -- returns a string with the current state of the download | 44 | -- returns a string with the current state of the download |
45 | local remaining_s = "%s received, %s/s throughput, %2.0f%% done, %s remaining" | ||
46 | local elapsed_s = "%s received, %s/s throughput, %s elapsed " | ||
45 | function gauge(got, delta, size) | 47 | function gauge(got, delta, size) |
46 | local rate = got / delta | 48 | local rate = got / delta |
47 | if size and size >= 1 then | 49 | if size and size >= 1 then |
48 | return string.format("%s received, %s/s throughput, " .. | 50 | return string.format(remaining_s, nicesize(got), nicesize(rate), |
49 | "%.0f%% done, %s remaining", | 51 | 100*got/size, nicetime((size-got)/rate)) |
50 | nicesize(got), | ||
51 | nicesize(rate), | ||
52 | 100*got/size, | ||
53 | nicetime((size-got)/rate)) | ||
54 | else | 52 | else |
55 | return string.format("%s received, %s/s throughput, %s elapsed", | 53 | return string.format(elapsed_s, nicesize(got), |
56 | nicesize(got), | 54 | nicesize(rate), nicetime(delta)) |
57 | nicesize(rate), | ||
58 | nicetime(delta)) | ||
59 | end | 55 | end |
60 | end | 56 | end |
61 | 57 | ||
@@ -78,7 +74,7 @@ function stats(size) | |||
78 | return chunk | 74 | return chunk |
79 | else | 75 | else |
80 | -- close up | 76 | -- close up |
81 | io.stderr:write("\n") | 77 | io.stderr:write("\r", gauge(got, delta), "\n") |
82 | return "" | 78 | return "" |
83 | end | 79 | end |
84 | end | 80 | end |
diff --git a/luasocket.vcproj b/luasocket.vcproj index 5a74880..f6ae497 100644 --- a/luasocket.vcproj +++ b/luasocket.vcproj | |||
@@ -70,7 +70,7 @@ | |||
70 | <Tool | 70 | <Tool |
71 | Name="VCCLCompilerTool" | 71 | Name="VCCLCompilerTool" |
72 | AdditionalIncludeDirectories="net/include" | 72 | AdditionalIncludeDirectories="net/include" |
73 | PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE, LUASOCKET_DEBUG" | 73 | PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE, LUASOCKET_DEBUG, LUASOCKET_COMPILED" |
74 | RuntimeLibrary="4" | 74 | RuntimeLibrary="4" |
75 | UsePrecompiledHeader="0" | 75 | UsePrecompiledHeader="0" |
76 | WarningLevel="3" | 76 | WarningLevel="3" |
@@ -35,17 +35,20 @@ static int mime_global_unqp(lua_State *L); | |||
35 | static int mime_global_qpfmt(lua_State *L); | 35 | static int mime_global_qpfmt(lua_State *L); |
36 | static int mime_global_eol(lua_State *L); | 36 | static int mime_global_eol(lua_State *L); |
37 | 37 | ||
38 | static void b64fill(UC *b64unbase); | 38 | static void b64setup(UC *b64unbase); |
39 | static size_t b64encode(UC c, UC *input, size_t size, luaL_Buffer *buffer); | 39 | static size_t b64encode(UC c, UC *input, size_t size, luaL_Buffer *buffer); |
40 | static size_t b64pad(const UC *input, size_t size, luaL_Buffer *buffer); | 40 | static size_t b64pad(const UC *input, size_t size, luaL_Buffer *buffer); |
41 | static size_t b64decode(UC c, UC *input, size_t size, luaL_Buffer *buffer); | 41 | static size_t b64decode(UC c, UC *input, size_t size, luaL_Buffer *buffer); |
42 | 42 | ||
43 | static void qpfill(UC *qpclass, UC *qpunbase); | 43 | static void qpsetup(UC *qpclass, UC *qpunbase); |
44 | static void qpquote(UC c, luaL_Buffer *buffer); | 44 | static void qpquote(UC c, luaL_Buffer *buffer); |
45 | static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer); | 45 | static size_t qpdecode(UC c, UC *input, size_t size, luaL_Buffer *buffer); |
46 | static size_t qpencode(UC c, UC *input, size_t size, | 46 | static size_t qpencode(UC c, UC *input, size_t size, |
47 | const char *marker, luaL_Buffer *buffer); | 47 | const char *marker, luaL_Buffer *buffer); |
48 | 48 | ||
49 | static const char *checklstring(lua_State *L, int n, size_t *l); | ||
50 | static const char *optlstring(lua_State *L, int n, const char *v, size_t *l); | ||
51 | |||
49 | /* code support functions */ | 52 | /* code support functions */ |
50 | static luaL_reg func[] = { | 53 | static luaL_reg func[] = { |
51 | { "eol", mime_global_eol }, | 54 | { "eol", mime_global_eol }, |
@@ -96,8 +99,27 @@ void mime_open(lua_State *L) | |||
96 | lua_settable(L, -3); | 99 | lua_settable(L, -3); |
97 | lua_pop(L, 1); | 100 | lua_pop(L, 1); |
98 | /* initialize lookup tables */ | 101 | /* initialize lookup tables */ |
99 | qpfill(qpclass, qpunbase); | 102 | qpsetup(qpclass, qpunbase); |
100 | b64fill(b64unbase); | 103 | b64setup(b64unbase); |
104 | } | ||
105 | |||
106 | /*-------------------------------------------------------------------------*\ | ||
107 | * Check if a string was provided. We accept false also. | ||
108 | \*-------------------------------------------------------------------------*/ | ||
109 | static const char *checklstring(lua_State *L, int n, size_t *l) | ||
110 | { | ||
111 | if (lua_isnil(L, n) || (lua_isboolean(L, n) && !lua_toboolean(L, n))) { | ||
112 | *l = 0; | ||
113 | return NULL; | ||
114 | } else return luaL_checklstring(L, n, l); | ||
115 | } | ||
116 | |||
117 | static const char *optlstring(lua_State *L, int n, const char *v, size_t *l) | ||
118 | { | ||
119 | if (lua_isnil(L, n) || (lua_isboolean(L, n) && !lua_toboolean(L, n))) { | ||
120 | *l = 0; | ||
121 | return NULL; | ||
122 | } else return luaL_optlstring(L, n, v, l); | ||
101 | } | 123 | } |
102 | 124 | ||
103 | /*=========================================================================*\ | 125 | /*=========================================================================*\ |
@@ -105,19 +127,19 @@ void mime_open(lua_State *L) | |||
105 | \*=========================================================================*/ | 127 | \*=========================================================================*/ |
106 | /*-------------------------------------------------------------------------*\ | 128 | /*-------------------------------------------------------------------------*\ |
107 | * Incrementaly breaks a string into lines | 129 | * Incrementaly breaks a string into lines |
108 | * A, n = fmt(B, length, left) | 130 | * A, n = fmt(l, B, length, marker) |
109 | * A is a copy of B, broken into lines of at most 'length' bytes. | 131 | * A is a copy of B, broken into lines of at most 'length' bytes. |
110 | * Left is how many bytes are left in the first line of B. 'n' is the number | 132 | * 'l' is how many bytes are left for the first line of B. |
111 | * of bytes left in the last line of A. | 133 | * 'n' is the number of bytes left in the last line of A. |
134 | * Marker is the end-of-line marker. | ||
112 | \*-------------------------------------------------------------------------*/ | 135 | \*-------------------------------------------------------------------------*/ |
113 | static int mime_global_fmt(lua_State *L) | 136 | static int mime_global_fmt(lua_State *L) |
114 | { | 137 | { |
115 | size_t size = 0; | 138 | size_t size = 0; |
116 | const UC *input = (UC *) (lua_isnil(L, 1)? NULL: | 139 | int left = (int) luaL_checknumber(L, 1); |
117 | luaL_checklstring(L, 1, &size)); | 140 | const UC *input = (UC *) checklstring(L, 2, &size); |
118 | const UC *last = input + size; | 141 | const UC *last = input + size; |
119 | int length = (int) luaL_checknumber(L, 2); | 142 | int length = (int) luaL_optnumber(L, 3, 76); |
120 | int left = (int) luaL_optnumber(L, 3, length); | ||
121 | const char *marker = luaL_optstring(L, 4, CRLF); | 143 | const char *marker = luaL_optstring(L, 4, CRLF); |
122 | luaL_Buffer buffer; | 144 | luaL_Buffer buffer; |
123 | luaL_buffinit(L, &buffer); | 145 | luaL_buffinit(L, &buffer); |
@@ -140,7 +162,7 @@ static int mime_global_fmt(lua_State *L) | |||
140 | /*-------------------------------------------------------------------------*\ | 162 | /*-------------------------------------------------------------------------*\ |
141 | * Fill base64 decode map. | 163 | * Fill base64 decode map. |
142 | \*-------------------------------------------------------------------------*/ | 164 | \*-------------------------------------------------------------------------*/ |
143 | static void b64fill(UC *b64unbase) | 165 | static void b64setup(UC *b64unbase) |
144 | { | 166 | { |
145 | int i; | 167 | int i; |
146 | for (i = 0; i < 255; i++) b64unbase[i] = 255; | 168 | for (i = 0; i < 255; i++) b64unbase[i] = 255; |
@@ -255,7 +277,7 @@ static int mime_global_b64(lua_State *L) | |||
255 | luaL_buffinit(L, &buffer); | 277 | luaL_buffinit(L, &buffer); |
256 | while (input < last) | 278 | while (input < last) |
257 | asize = b64encode(*input++, atom, asize, &buffer); | 279 | asize = b64encode(*input++, atom, asize, &buffer); |
258 | input = (UC *) luaL_optlstring(L, 2, NULL, &isize); | 280 | input = (UC *) optlstring(L, 2, NULL, &isize); |
259 | if (input) { | 281 | if (input) { |
260 | last = input + isize; | 282 | last = input + isize; |
261 | while (input < last) | 283 | while (input < last) |
@@ -283,7 +305,7 @@ static int mime_global_unb64(lua_State *L) | |||
283 | luaL_buffinit(L, &buffer); | 305 | luaL_buffinit(L, &buffer); |
284 | while (input < last) | 306 | while (input < last) |
285 | asize = b64decode(*input++, atom, asize, &buffer); | 307 | asize = b64decode(*input++, atom, asize, &buffer); |
286 | input = (UC *) luaL_optlstring(L, 2, NULL, &isize); | 308 | input = (UC *) optlstring(L, 2, NULL, &isize); |
287 | if (input) { | 309 | if (input) { |
288 | last = input + isize; | 310 | last = input + isize; |
289 | while (input < last) | 311 | while (input < last) |
@@ -311,7 +333,7 @@ static int mime_global_unb64(lua_State *L) | |||
311 | * Split quoted-printable characters into classes | 333 | * Split quoted-printable characters into classes |
312 | * Precompute reverse map for encoding | 334 | * Precompute reverse map for encoding |
313 | \*-------------------------------------------------------------------------*/ | 335 | \*-------------------------------------------------------------------------*/ |
314 | static void qpfill(UC *qpclass, UC *qpunbase) | 336 | static void qpsetup(UC *qpclass, UC *qpunbase) |
315 | { | 337 | { |
316 | int i; | 338 | int i; |
317 | for (i = 0; i < 256; i++) qpclass[i] = QP_QUOTED; | 339 | for (i = 0; i < 256; i++) qpclass[i] = QP_QUOTED; |
@@ -417,15 +439,14 @@ static int mime_global_qp(lua_State *L) | |||
417 | 439 | ||
418 | size_t asize = 0, isize = 0; | 440 | size_t asize = 0, isize = 0; |
419 | UC atom[3]; | 441 | UC atom[3]; |
420 | const UC *input = (UC *) (lua_isnil(L, 1) ? NULL: | 442 | const UC *input = (UC *) checklstring(L, 1, &isize); |
421 | luaL_checklstring(L, 1, &isize)); | ||
422 | const UC *last = input + isize; | 443 | const UC *last = input + isize; |
423 | const char *marker = luaL_optstring(L, 3, CRLF); | 444 | const char *marker = luaL_optstring(L, 3, CRLF); |
424 | luaL_Buffer buffer; | 445 | luaL_Buffer buffer; |
425 | luaL_buffinit(L, &buffer); | 446 | luaL_buffinit(L, &buffer); |
426 | while (input < last) | 447 | while (input < last) |
427 | asize = qpencode(*input++, atom, asize, marker, &buffer); | 448 | asize = qpencode(*input++, atom, asize, marker, &buffer); |
428 | input = (UC *) luaL_optlstring(L, 2, NULL, &isize); | 449 | input = (UC *) optlstring(L, 2, NULL, &isize); |
429 | if (input) { | 450 | if (input) { |
430 | last = input + isize; | 451 | last = input + isize; |
431 | while (input < last) | 452 | while (input < last) |
@@ -486,14 +507,13 @@ static int mime_global_unqp(lua_State *L) | |||
486 | 507 | ||
487 | size_t asize = 0, isize = 0; | 508 | size_t asize = 0, isize = 0; |
488 | UC atom[3]; | 509 | UC atom[3]; |
489 | const UC *input = (UC *) (lua_isnil(L, 1) ? NULL: | 510 | const UC *input = (UC *) checklstring(L, 1, &isize); |
490 | luaL_checklstring(L, 1, &isize)); | ||
491 | const UC *last = input + isize; | 511 | const UC *last = input + isize; |
492 | luaL_Buffer buffer; | 512 | luaL_Buffer buffer; |
493 | luaL_buffinit(L, &buffer); | 513 | luaL_buffinit(L, &buffer); |
494 | while (input < last) | 514 | while (input < last) |
495 | asize = qpdecode(*input++, atom, asize, &buffer); | 515 | asize = qpdecode(*input++, atom, asize, &buffer); |
496 | input = (UC *) luaL_optlstring(L, 2, NULL, &isize); | 516 | input = (UC *) optlstring(L, 2, NULL, &isize); |
497 | if (input) { | 517 | if (input) { |
498 | last = input + isize; | 518 | last = input + isize; |
499 | while (input < last) | 519 | while (input < last) |
@@ -506,21 +526,20 @@ static int mime_global_unqp(lua_State *L) | |||
506 | 526 | ||
507 | /*-------------------------------------------------------------------------*\ | 527 | /*-------------------------------------------------------------------------*\ |
508 | * Incrementally breaks a quoted-printed string into lines | 528 | * Incrementally breaks a quoted-printed string into lines |
509 | * A, n = qpfmt(B, length, left) | 529 | * A, n = qpfmt(l, B, length) |
510 | * A is a copy of B, broken into lines of at most 'length' bytes. | 530 | * A is a copy of B, broken into lines of at most 'length' bytes. |
511 | * Left is how many bytes are left in the first line of B. 'n' is the number | 531 | * 'l' is how many bytes are left for the first line of B. |
512 | * of bytes left in the last line of A. | 532 | * 'n' is the number of bytes left in the last line of A. |
513 | * There are two complications: lines can't be broken in the middle | 533 | * There are two complications: lines can't be broken in the middle |
514 | * of an encoded =XX, and there might be line breaks already | 534 | * of an encoded =XX, and there might be line breaks already |
515 | \*-------------------------------------------------------------------------*/ | 535 | \*-------------------------------------------------------------------------*/ |
516 | static int mime_global_qpfmt(lua_State *L) | 536 | static int mime_global_qpfmt(lua_State *L) |
517 | { | 537 | { |
518 | size_t size = 0; | 538 | size_t size = 0; |
519 | const UC *input = (UC *) (lua_isnil(L, 1)? NULL: | 539 | int left = (int) luaL_checknumber(L, 1); |
520 | luaL_checklstring(L, 1, &size)); | 540 | const UC *input = (UC *) checklstring(L, 2, &size); |
521 | const UC *last = input + size; | 541 | const UC *last = input + size; |
522 | int length = (int) luaL_checknumber(L, 2); | 542 | int length = (int) luaL_optnumber(L, 3, 76); |
523 | int left = (int) luaL_optnumber(L, 3, length); | ||
524 | luaL_Buffer buffer; | 543 | luaL_Buffer buffer; |
525 | luaL_buffinit(L, &buffer); | 544 | luaL_buffinit(L, &buffer); |
526 | while (input < last) { | 545 | while (input < last) { |
@@ -597,15 +616,14 @@ static int mime_global_eol(lua_State *L) | |||
597 | { | 616 | { |
598 | size_t asize = 0, isize = 0; | 617 | size_t asize = 0, isize = 0; |
599 | UC atom[2]; | 618 | UC atom[2]; |
600 | const UC *input = (UC *) (lua_isnil(L, 1)? NULL: | 619 | const UC *input = (UC *) checklstring(L, 1, &isize); |
601 | luaL_checklstring(L, 1, &isize)); | ||
602 | const UC *last = input + isize; | 620 | const UC *last = input + isize; |
603 | const char *marker = luaL_optstring(L, 3, CRLF); | 621 | const char *marker = luaL_optstring(L, 3, CRLF); |
604 | luaL_Buffer buffer; | 622 | luaL_Buffer buffer; |
605 | luaL_buffinit(L, &buffer); | 623 | luaL_buffinit(L, &buffer); |
606 | while (input < last) | 624 | while (input < last) |
607 | asize = eolconvert(*input++, atom, asize, marker, &buffer); | 625 | asize = eolconvert(*input++, atom, asize, marker, &buffer); |
608 | input = (UC *) luaL_optlstring(L, 2, NULL, &isize); | 626 | input = (UC *) optlstring(L, 2, NULL, &isize); |
609 | if (input) { | 627 | if (input) { |
610 | last = input + isize; | 628 | last = input + isize; |
611 | while (input < last) | 629 | while (input < last) |
diff --git a/src/mime.lua b/src/mime.lua index 86b3af2..0251f6e 100644 --- a/src/mime.lua +++ b/src/mime.lua | |||
@@ -10,75 +10,71 @@ socket.mime = mime | |||
10 | setmetatable(mime, { __index = _G }) | 10 | setmetatable(mime, { __index = _G }) |
11 | setfenv(1, mime) | 11 | setfenv(1, mime) |
12 | 12 | ||
13 | base64 = {} | 13 | -- encode, decode and wrap algorithm tables |
14 | qprint = {} | 14 | local et = {} |
15 | local dt = {} | ||
16 | local wt = {} | ||
15 | 17 | ||
16 | function base64.encode() | 18 | -- creates a function that chooses an algorithm from a given table |
17 | local unfinished = "" | 19 | local function choose(table) |
18 | return function(chunk) | 20 | return function(method, ...) |
19 | local done | 21 | local f = table[method or "nil"] |
20 | done, unfinished = b64(unfinished, chunk) | 22 | if not f then return nil, "unknown method (" .. tostring(method) .. ")" |
21 | return done | 23 | else return f(unpack(arg)) end |
22 | end | 24 | end |
23 | end | 25 | end |
24 | 26 | ||
25 | function base64.decode() | 27 | -- creates a function that cicles a filter with a given initial |
26 | local unfinished = "" | 28 | -- context and extra arguments |
29 | local function cicle(f, ctx, ...) | ||
27 | return function(chunk) | 30 | return function(chunk) |
28 | local done | 31 | local ret |
29 | done, unfinished = unb64(unfinished, chunk) | 32 | ret, ctx = f(ctx, chunk, unpack(arg)) |
30 | return done | 33 | return ret |
31 | end | 34 | end |
32 | end | 35 | end |
33 | 36 | ||
34 | function qprint.encode(mode) | 37 | -- function that choose the encoding, decoding or wrap algorithm |
35 | mode = (mode == "binary") and "=0D=0A" or "\13\10" | 38 | encode = choose(et) |
36 | local unfinished = "" | 39 | decode = choose(dt) |
37 | return function(chunk) | 40 | wrap = choose(wt) |
38 | local done | 41 | |
39 | done, unfinished = qp(unfinished, chunk, mode) | 42 | -- define the encoding algorithms |
40 | return done | 43 | et['base64'] = function() |
41 | end | 44 | return cicle(b64, "") |
42 | end | 45 | end |
43 | 46 | ||
44 | function qprint.decode() | 47 | et['quoted-printable'] = function(mode) |
45 | local unfinished = "" | 48 | return cicle(qp, "", (mode == "binary") and "=0D=0A" or "\13\10") |
46 | return function(chunk) | 49 | end |
47 | local done | 50 | |
48 | done, unfinished = unqp(unfinished, chunk) | 51 | -- define the decoding algorithms |
49 | return done | 52 | dt['base64'] = function() |
50 | end | 53 | return cicle(unb64, "") |
51 | end | 54 | end |
52 | 55 | ||
53 | function split(length, marker) | 56 | dt['quoted-printable'] = function() |
57 | return cicle(unqp, "") | ||
58 | end | ||
59 | |||
60 | -- define the wrap algorithms | ||
61 | wt['character'] = function(length) | ||
54 | length = length or 76 | 62 | length = length or 76 |
55 | local left = length | 63 | return cicle(fmt, length, length) |
56 | return function(chunk) | ||
57 | local done | ||
58 | done, left = fmt(chunk, length, left, marker) | ||
59 | return done | ||
60 | end | ||
61 | end | 64 | end |
65 | wt['base64'] = wt['character'] | ||
62 | 66 | ||
63 | function qprint.split(length) | 67 | wt['quoted-printable'] = function(length) |
64 | length = length or 76 | 68 | length = length or 76 |
65 | local left = length | 69 | return cicle(qpfmt, length, length) |
66 | return function(chunk) | ||
67 | local done | ||
68 | done, left = qpfmt(chunk, length, left) | ||
69 | return done | ||
70 | end | ||
71 | end | 70 | end |
72 | 71 | ||
72 | -- define the end-of-line translation function | ||
73 | function canonic(marker) | 73 | function canonic(marker) |
74 | local unfinished = "" | 74 | return cicle(eol, "", marker) |
75 | return function(chunk) | ||
76 | local done | ||
77 | done, unfinished = eol(unfinished, chunk, marker) | ||
78 | return done | ||
79 | end | ||
80 | end | 75 | end |
81 | 76 | ||
77 | -- chains several filters together | ||
82 | function chain(...) | 78 | function chain(...) |
83 | local layers = table.getn(arg) | 79 | local layers = table.getn(arg) |
84 | return function (chunk) | 80 | return function (chunk) |
diff --git a/test/httptest.lua b/test/httptest.lua index 44266d5..4667605 100644 --- a/test/httptest.lua +++ b/test/httptest.lua | |||
@@ -5,8 +5,8 @@ | |||
5 | -- needs "AllowOverride AuthConfig" on /home/c/diego/tec/luasocket/test/auth | 5 | -- needs "AllowOverride AuthConfig" on /home/c/diego/tec/luasocket/test/auth |
6 | dofile("noglobals.lua") | 6 | dofile("noglobals.lua") |
7 | 7 | ||
8 | local host, proxy, request, response | 8 | local host, proxy, request, response, index_file |
9 | local ignore, expect, index, prefix, cgiprefix | 9 | local ignore, expect, index, prefix, cgiprefix, index_crlf |
10 | 10 | ||
11 | socket.http.TIMEOUT = 5 | 11 | socket.http.TIMEOUT = 5 |
12 | 12 | ||
@@ -16,6 +16,7 @@ host = host or "diego.student.dyn.cs.princeton.edu" | |||
16 | proxy = proxy or "http://localhost:3128" | 16 | proxy = proxy or "http://localhost:3128" |
17 | prefix = prefix or "/luasocket-test" | 17 | prefix = prefix or "/luasocket-test" |
18 | cgiprefix = cgiprefix or "/luasocket-test-cgi" | 18 | cgiprefix = cgiprefix or "/luasocket-test-cgi" |
19 | index_file = "test/index.html" | ||
19 | 20 | ||
20 | local readfile = function(name) | 21 | local readfile = function(name) |
21 | local f = io.open(name, "r") | 22 | local f = io.open(name, "r") |
@@ -25,7 +26,8 @@ local readfile = function(name) | |||
25 | return s | 26 | return s |
26 | end | 27 | end |
27 | 28 | ||
28 | index = readfile("test/index.html") | 29 | -- read index with CRLF convention |
30 | index = readfile(index_file) | ||
29 | 31 | ||
30 | local similar = function(s1, s2) | 32 | local similar = function(s1, s2) |
31 | return string.lower(string.gsub(s1 or "", "%s", "")) == | 33 | return string.lower(string.gsub(s1 or "", "%s", "")) == |
@@ -42,13 +44,13 @@ local check = function (v, e) | |||
42 | if v then print("ok") | 44 | if v then print("ok") |
43 | else fail(e) end | 45 | else fail(e) end |
44 | end | 46 | end |
45 | 47 | ||
46 | local check_request = function(request, expect, ignore) | 48 | local check_result = function(response, expect, ignore) |
47 | local response = socket.http.request(request) | ||
48 | for i,v in response do | 49 | for i,v in response do |
49 | if not ignore[i] then | 50 | if not ignore[i] then |
50 | if v ~= expect[i] then | 51 | if v ~= expect[i] then |
51 | if string.len(v) < 80 then print(v) end | 52 | v = string.sub(type(v) == "string" and v or "", 1, 70) |
53 | print(v) | ||
52 | fail(i .. " differs!") | 54 | fail(i .. " differs!") |
53 | end | 55 | end |
54 | end | 56 | end |
@@ -56,7 +58,8 @@ local check_request = function(request, expect, ignore) | |||
56 | for i,v in expect do | 58 | for i,v in expect do |
57 | if not ignore[i] then | 59 | if not ignore[i] then |
58 | if v ~= response[i] then | 60 | if v ~= response[i] then |
59 | if string.len(v) < 80 then print(v) end | 61 | v = string.sub(type(v) == "string" and v or "", 1, 70) |
62 | print(v) | ||
60 | fail(i .. " differs!") | 63 | fail(i .. " differs!") |
61 | end | 64 | end |
62 | end | 65 | end |
@@ -64,6 +67,17 @@ local check_request = function(request, expect, ignore) | |||
64 | print("ok") | 67 | print("ok") |
65 | end | 68 | end |
66 | 69 | ||
70 | local check_request = function(request, expect, ignore) | ||
71 | local response = socket.http.request(request) | ||
72 | check_result(response, expect, ignore) | ||
73 | end | ||
74 | |||
75 | local check_request_cb = function(request, response, expect, ignore) | ||
76 | local response = socket.http.request_cb(request, response) | ||
77 | check_result(response, expect, ignore) | ||
78 | end | ||
79 | |||
80 | ------------------------------------------------------------------------ | ||
67 | io.write("testing request uri correctness: ") | 81 | io.write("testing request uri correctness: ") |
68 | local forth = cgiprefix .. "/request-uri?" .. "this+is+the+query+string" | 82 | local forth = cgiprefix .. "/request-uri?" .. "this+is+the+query+string" |
69 | local back, h, c, e = socket.http.get("http://" .. host .. forth) | 83 | local back, h, c, e = socket.http.get("http://" .. host .. forth) |
@@ -72,12 +86,15 @@ back = socket.url.parse(back) | |||
72 | if similar(back.query, "this+is+the+query+string") then print("ok") | 86 | if similar(back.query, "this+is+the+query+string") then print("ok") |
73 | else fail() end | 87 | else fail() end |
74 | 88 | ||
89 | ------------------------------------------------------------------------ | ||
75 | io.write("testing query string correctness: ") | 90 | io.write("testing query string correctness: ") |
76 | forth = "this+is+the+query+string" | 91 | forth = "this+is+the+query+string" |
77 | back = socket.http.get("http://" .. host .. cgiprefix .. "/query-string?" .. forth) | 92 | back = socket.http.get("http://" .. host .. cgiprefix .. |
93 | "/query-string?" .. forth) | ||
78 | if similar(back, forth) then print("ok") | 94 | if similar(back, forth) then print("ok") |
79 | else fail("failed!") end | 95 | else fail("failed!") end |
80 | 96 | ||
97 | ------------------------------------------------------------------------ | ||
81 | io.write("testing document retrieval: ") | 98 | io.write("testing document retrieval: ") |
82 | request = { | 99 | request = { |
83 | url = "http://" .. host .. prefix .. "/index.html" | 100 | url = "http://" .. host .. prefix .. "/index.html" |
@@ -92,6 +109,7 @@ ignore = { | |||
92 | } | 109 | } |
93 | check_request(request, expect, ignore) | 110 | check_request(request, expect, ignore) |
94 | 111 | ||
112 | ------------------------------------------------------------------------ | ||
95 | io.write("testing redirect loop: ") | 113 | io.write("testing redirect loop: ") |
96 | request = { | 114 | request = { |
97 | url = "http://" .. host .. cgiprefix .. "/redirect-loop" | 115 | url = "http://" .. host .. cgiprefix .. "/redirect-loop" |
@@ -106,6 +124,7 @@ ignore = { | |||
106 | } | 124 | } |
107 | check_request(request, expect, ignore) | 125 | check_request(request, expect, ignore) |
108 | 126 | ||
127 | ------------------------------------------------------------------------ | ||
109 | io.write("testing post method: ") | 128 | io.write("testing post method: ") |
110 | -- wanted to test chunked post, but apache doesn't support it... | 129 | -- wanted to test chunked post, but apache doesn't support it... |
111 | request = { | 130 | request = { |
@@ -125,6 +144,7 @@ ignore = { | |||
125 | } | 144 | } |
126 | check_request(request, expect, ignore) | 145 | check_request(request, expect, ignore) |
127 | 146 | ||
147 | ------------------------------------------------------------------------ | ||
128 | io.write("testing proxy with post method: ") | 148 | io.write("testing proxy with post method: ") |
129 | request = { | 149 | request = { |
130 | url = "http://" .. host .. cgiprefix .. "/cat", | 150 | url = "http://" .. host .. cgiprefix .. "/cat", |
@@ -143,10 +163,78 @@ ignore = { | |||
143 | } | 163 | } |
144 | check_request(request, expect, ignore) | 164 | check_request(request, expect, ignore) |
145 | 165 | ||
166 | ------------------------------------------------------------------------ | ||
146 | io.write("testing simple post function: ") | 167 | io.write("testing simple post function: ") |
147 | back = socket.http.post("http://" .. host .. cgiprefix .. "/cat", index) | 168 | back = socket.http.post("http://" .. host .. cgiprefix .. "/cat", index) |
148 | check(back == index) | 169 | check(back == index) |
149 | 170 | ||
171 | ------------------------------------------------------------------------ | ||
172 | io.write("testing send.file and receive.file callbacks: ") | ||
173 | request = { | ||
174 | url = "http://" .. host .. cgiprefix .. "/cat", | ||
175 | method = "POST", | ||
176 | body_cb = socket.callback.send.file(io.open(index_file, "r")), | ||
177 | headers = { ["content-length"] = string.len(index) } | ||
178 | } | ||
179 | response = { | ||
180 | body_cb = socket.callback.receive.file(io.open(index_file .. "-back", "w")) | ||
181 | } | ||
182 | expect = { | ||
183 | code = 200 | ||
184 | } | ||
185 | ignore = { | ||
186 | body_cb = 1, | ||
187 | status = 1, | ||
188 | headers = 1 | ||
189 | } | ||
190 | check_request_cb(request, response, expect, ignore) | ||
191 | back = readfile(index_file .. "-back") | ||
192 | check(back == index) | ||
193 | os.remove(index_file .. "-back") | ||
194 | |||
195 | ------------------------------------------------------------------------ | ||
196 | io.write("testing send.chain and receive.chain callbacks: ") | ||
197 | |||
198 | local function b64length(len) | ||
199 | local a = math.ceil(len/3)*4 | ||
200 | local l = math.ceil(a/76) | ||
201 | return a + l*2 | ||
202 | end | ||
203 | |||
204 | local req_cb = socket.callback.send.chain( | ||
205 | socket.callback.send.file(io.open(index_file, "r")), | ||
206 | socket.mime.chain( | ||
207 | socket.mime.encode("base64"), | ||
208 | socket.mime.wrap("base64") | ||
209 | ) | ||
210 | ) | ||
211 | |||
212 | local resp_cb = socket.callback.receive.chain( | ||
213 | socket.mime.decode("base64"), | ||
214 | socket.callback.receive.file(io.open(index_file .. "-back", "w")) | ||
215 | ) | ||
216 | |||
217 | request = { | ||
218 | url = "http://" .. host .. cgiprefix .. "/cat", | ||
219 | method = "POST", | ||
220 | body_cb = req_cb, | ||
221 | headers = { ["content-length"] = b64length(string.len(index)) } | ||
222 | } | ||
223 | response = { body_cb = resp_cb } | ||
224 | expect = { | ||
225 | code = 200 | ||
226 | } | ||
227 | ignore = { | ||
228 | body_cb = 1, | ||
229 | status = 1, | ||
230 | headers = 1 | ||
231 | } | ||
232 | check_request_cb(request, response, expect, ignore) | ||
233 | back = readfile(index_file .. "-back") | ||
234 | check(back == index) | ||
235 | os.remove(index_file .. "-back") | ||
236 | |||
237 | ------------------------------------------------------------------------ | ||
150 | io.write("testing simple post function with table args: ") | 238 | io.write("testing simple post function with table args: ") |
151 | back = socket.http.post { | 239 | back = socket.http.post { |
152 | url = "http://" .. host .. cgiprefix .. "/cat", | 240 | url = "http://" .. host .. cgiprefix .. "/cat", |
@@ -154,6 +242,7 @@ back = socket.http.post { | |||
154 | } | 242 | } |
155 | check(back == index) | 243 | check(back == index) |
156 | 244 | ||
245 | ------------------------------------------------------------------------ | ||
157 | io.write("testing http redirection: ") | 246 | io.write("testing http redirection: ") |
158 | request = { | 247 | request = { |
159 | url = "http://" .. host .. prefix | 248 | url = "http://" .. host .. prefix |
@@ -168,6 +257,7 @@ ignore = { | |||
168 | } | 257 | } |
169 | check_request(request, expect, ignore) | 258 | check_request(request, expect, ignore) |
170 | 259 | ||
260 | ------------------------------------------------------------------------ | ||
171 | io.write("testing proxy with redirection: ") | 261 | io.write("testing proxy with redirection: ") |
172 | request = { | 262 | request = { |
173 | url = "http://" .. host .. prefix, | 263 | url = "http://" .. host .. prefix, |
@@ -183,7 +273,7 @@ ignore = { | |||
183 | } | 273 | } |
184 | check_request(request, expect, ignore) | 274 | check_request(request, expect, ignore) |
185 | 275 | ||
186 | 276 | ------------------------------------------------------------------------ | |
187 | io.write("testing automatic auth failure: ") | 277 | io.write("testing automatic auth failure: ") |
188 | request = { | 278 | request = { |
189 | url = "http://really:wrong@" .. host .. prefix .. "/auth/index.html" | 279 | url = "http://really:wrong@" .. host .. prefix .. "/auth/index.html" |
@@ -198,6 +288,7 @@ ignore = { | |||
198 | } | 288 | } |
199 | check_request(request, expect, ignore) | 289 | check_request(request, expect, ignore) |
200 | 290 | ||
291 | ------------------------------------------------------------------------ | ||
201 | io.write("testing http redirection failure: ") | 292 | io.write("testing http redirection failure: ") |
202 | request = { | 293 | request = { |
203 | url = "http://" .. host .. prefix, | 294 | url = "http://" .. host .. prefix, |
@@ -213,6 +304,7 @@ ignore = { | |||
213 | } | 304 | } |
214 | check_request(request, expect, ignore) | 305 | check_request(request, expect, ignore) |
215 | 306 | ||
307 | ------------------------------------------------------------------------ | ||
216 | io.write("testing host not found: ") | 308 | io.write("testing host not found: ") |
217 | request = { | 309 | request = { |
218 | url = "http://wronghost/does/not/exist" | 310 | url = "http://wronghost/does/not/exist" |
@@ -224,6 +316,7 @@ expect = { | |||
224 | ignore = {} | 316 | ignore = {} |
225 | check_request(request, expect, ignore) | 317 | check_request(request, expect, ignore) |
226 | 318 | ||
319 | ------------------------------------------------------------------------ | ||
227 | io.write("testing invalid url: ") | 320 | io.write("testing invalid url: ") |
228 | request = { | 321 | request = { |
229 | url = host .. prefix | 322 | url = host .. prefix |
@@ -235,6 +328,7 @@ expect = { | |||
235 | ignore = {} | 328 | ignore = {} |
236 | check_request(request, expect, ignore) | 329 | check_request(request, expect, ignore) |
237 | 330 | ||
331 | ------------------------------------------------------------------------ | ||
238 | io.write("testing document not found: ") | 332 | io.write("testing document not found: ") |
239 | request = { | 333 | request = { |
240 | url = "http://" .. host .. "/wrongdocument.html" | 334 | url = "http://" .. host .. "/wrongdocument.html" |
@@ -249,6 +343,7 @@ ignore = { | |||
249 | } | 343 | } |
250 | check_request(request, expect, ignore) | 344 | check_request(request, expect, ignore) |
251 | 345 | ||
346 | ------------------------------------------------------------------------ | ||
252 | io.write("testing auth failure: ") | 347 | io.write("testing auth failure: ") |
253 | request = { | 348 | request = { |
254 | url = "http://" .. host .. prefix .. "/auth/index.html" | 349 | url = "http://" .. host .. prefix .. "/auth/index.html" |
@@ -263,6 +358,7 @@ ignore = { | |||
263 | } | 358 | } |
264 | check_request(request, expect, ignore) | 359 | check_request(request, expect, ignore) |
265 | 360 | ||
361 | ------------------------------------------------------------------------ | ||
266 | io.write("testing manual basic auth: ") | 362 | io.write("testing manual basic auth: ") |
267 | request = { | 363 | request = { |
268 | url = "http://" .. host .. prefix .. "/auth/index.html", | 364 | url = "http://" .. host .. prefix .. "/auth/index.html", |
@@ -280,6 +376,7 @@ ignore = { | |||
280 | } | 376 | } |
281 | check_request(request, expect, ignore) | 377 | check_request(request, expect, ignore) |
282 | 378 | ||
379 | ------------------------------------------------------------------------ | ||
283 | io.write("testing automatic basic auth: ") | 380 | io.write("testing automatic basic auth: ") |
284 | request = { | 381 | request = { |
285 | url = "http://luasocket:password@" .. host .. prefix .. "/auth/index.html" | 382 | url = "http://luasocket:password@" .. host .. prefix .. "/auth/index.html" |
@@ -294,6 +391,7 @@ ignore = { | |||
294 | } | 391 | } |
295 | check_request(request, expect, ignore) | 392 | check_request(request, expect, ignore) |
296 | 393 | ||
394 | ------------------------------------------------------------------------ | ||
297 | io.write("testing auth info overriding: ") | 395 | io.write("testing auth info overriding: ") |
298 | request = { | 396 | request = { |
299 | url = "http://really:wrong@" .. host .. prefix .. "/auth/index.html", | 397 | url = "http://really:wrong@" .. host .. prefix .. "/auth/index.html", |
@@ -310,6 +408,7 @@ ignore = { | |||
310 | } | 408 | } |
311 | check_request(request, expect, ignore) | 409 | check_request(request, expect, ignore) |
312 | 410 | ||
411 | ------------------------------------------------------------------------ | ||
313 | io.write("testing cgi output retrieval (probably chunked...): ") | 412 | io.write("testing cgi output retrieval (probably chunked...): ") |
314 | request = { | 413 | request = { |
315 | url = "http://" .. host .. cgiprefix .. "/cat-index-html" | 414 | url = "http://" .. host .. cgiprefix .. "/cat-index-html" |
@@ -324,6 +423,7 @@ ignore = { | |||
324 | } | 423 | } |
325 | check_request(request, expect, ignore) | 424 | check_request(request, expect, ignore) |
326 | 425 | ||
426 | ------------------------------------------------------------------------ | ||
327 | io.write("testing wrong scheme: ") | 427 | io.write("testing wrong scheme: ") |
328 | request = { | 428 | request = { |
329 | url = "wrong://" .. host .. cgiprefix .. "/cat", | 429 | url = "wrong://" .. host .. cgiprefix .. "/cat", |
@@ -336,11 +436,13 @@ ignore = { | |||
336 | } | 436 | } |
337 | check_request(request, expect, ignore) | 437 | check_request(request, expect, ignore) |
338 | 438 | ||
439 | ------------------------------------------------------------------------ | ||
339 | local body | 440 | local body |
340 | io.write("testing simple get function: ") | 441 | io.write("testing simple get function: ") |
341 | body = socket.http.get("http://" .. host .. prefix .. "/index.html") | 442 | body = socket.http.get("http://" .. host .. prefix .. "/index.html") |
342 | check(body == index) | 443 | check(body == index) |
343 | 444 | ||
445 | ------------------------------------------------------------------------ | ||
344 | io.write("testing simple get function with table args: ") | 446 | io.write("testing simple get function with table args: ") |
345 | body = socket.http.get { | 447 | body = socket.http.get { |
346 | url = "http://really:wrong@" .. host .. prefix .. "/auth/index.html", | 448 | url = "http://really:wrong@" .. host .. prefix .. "/auth/index.html", |
@@ -349,6 +451,7 @@ body = socket.http.get { | |||
349 | } | 451 | } |
350 | check(body == index) | 452 | check(body == index) |
351 | 453 | ||
454 | ------------------------------------------------------------------------ | ||
352 | io.write("testing HEAD method: ") | 455 | io.write("testing HEAD method: ") |
353 | socket.http.TIMEOUT = 1 | 456 | socket.http.TIMEOUT = 1 |
354 | response = socket.http.request { | 457 | response = socket.http.request { |
@@ -357,6 +460,7 @@ response = socket.http.request { | |||
357 | } | 460 | } |
358 | check(response and response.headers) | 461 | check(response and response.headers) |
359 | 462 | ||
463 | ------------------------------------------------------------------------ | ||
360 | print("passed all tests") | 464 | print("passed all tests") |
361 | 465 | ||
362 | print(string.format("done in %.2fs", socket.time() - t)) | 466 | print(string.format("done in %.2fs", socket.time() - t)) |
diff --git a/test/mimetest.lua b/test/mimetest.lua index 5485db1..0adcb18 100644 --- a/test/mimetest.lua +++ b/test/mimetest.lua | |||
@@ -66,8 +66,8 @@ local function compare(input, output) | |||
66 | end | 66 | end |
67 | 67 | ||
68 | local function encode_qptest(mode) | 68 | local function encode_qptest(mode) |
69 | local encode = socket.mime.qprint.encode(mode) | 69 | local encode = socket.mime.encode("quoted-printable", mode) |
70 | local split = socket.mime.qprint.split() | 70 | local split = socket.mime.wrap("quoted-printable") |
71 | local chain = socket.mime.chain(encode, split) | 71 | local chain = socket.mime.chain(encode, split) |
72 | transform(qptest, eqptest, chain) | 72 | transform(qptest, eqptest, chain) |
73 | end | 73 | end |
@@ -77,7 +77,7 @@ local function compare_qptest() | |||
77 | end | 77 | end |
78 | 78 | ||
79 | local function decode_qptest() | 79 | local function decode_qptest() |
80 | local decode = socket.mime.qprint.decode() | 80 | local decode = socket.mime.decode("quoted-printable") |
81 | transform(eqptest, dqptest, decode) | 81 | transform(eqptest, dqptest, decode) |
82 | end | 82 | end |
83 | 83 | ||
@@ -151,23 +151,23 @@ local function cleanup_qptest() | |||
151 | end | 151 | end |
152 | 152 | ||
153 | local function encode_b64test() | 153 | local function encode_b64test() |
154 | local e1 = socket.mime.base64.encode() | 154 | local e1 = socket.mime.encode("base64") |
155 | local e2 = socket.mime.base64.encode() | 155 | local e2 = socket.mime.encode("base64") |
156 | local e3 = socket.mime.base64.encode() | 156 | local e3 = socket.mime.encode("base64") |
157 | local e4 = socket.mime.base64.encode() | 157 | local e4 = socket.mime.encode("base64") |
158 | local sp4 = socket.mime.split() | 158 | local sp4 = socket.mime.wrap("character") |
159 | local sp3 = socket.mime.split(59) | 159 | local sp3 = socket.mime.wrap("character", 59) |
160 | local sp2 = socket.mime.split(30) | 160 | local sp2 = socket.mime.wrap("character", 30) |
161 | local sp1 = socket.mime.split(27) | 161 | local sp1 = socket.mime.wrap("character", 27) |
162 | local chain = socket.mime.chain(e1, sp1, e2, sp2, e3, sp3, e4, sp4) | 162 | local chain = socket.mime.chain(e1, sp1, e2, sp2, e3, sp3, e4, sp4) |
163 | transform(b64test, eb64test, chain) | 163 | transform(b64test, eb64test, chain) |
164 | end | 164 | end |
165 | 165 | ||
166 | local function decode_b64test() | 166 | local function decode_b64test() |
167 | local d1 = socket.mime.base64.decode() | 167 | local d1 = socket.mime.decode("base64") |
168 | local d2 = socket.mime.base64.decode() | 168 | local d2 = socket.mime.decode("base64") |
169 | local d3 = socket.mime.base64.decode() | 169 | local d3 = socket.mime.decode("base64") |
170 | local d4 = socket.mime.base64.decode() | 170 | local d4 = socket.mime.decode("base64") |
171 | local chain = socket.mime.chain(d1, d2, d3, d4) | 171 | local chain = socket.mime.chain(d1, d2, d3, d4) |
172 | transform(eb64test, db64test, chain) | 172 | transform(eb64test, db64test, chain) |
173 | end | 173 | end |