diff options
Diffstat (limited to 'src/http.lua')
| -rw-r--r-- | src/http.lua | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/src/http.lua b/src/http.lua index a10cf50..ab166e3 100644 --- a/src/http.lua +++ b/src/http.lua | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | -- HTTP/1.1 client support for the Lua language. | 2 | -- HTTP/1.1 client support for the Lua language. |
| 3 | -- LuaSocket toolkit. | 3 | -- LuaSocket toolkit. |
| 4 | -- Author: Diego Nehab | 4 | -- Author: Diego Nehab |
| 5 | -- Conforming to: RFC 2616, LTN7 | 5 | -- Conforming to RFC 2616 |
| 6 | -- RCS ID: $Id$ | 6 | -- RCS ID: $Id$ |
| 7 | ----------------------------------------------------------------------------- | 7 | ----------------------------------------------------------------------------- |
| 8 | -- make sure LuaSocket is loaded | 8 | -- make sure LuaSocket is loaded |
| @@ -39,21 +39,18 @@ local function third(a, b, c) | |||
| 39 | return c | 39 | return c |
| 40 | end | 40 | end |
| 41 | 41 | ||
| 42 | local function shift(a, b, c, d) | 42 | local function receive_headers(reqt, respt) |
| 43 | return c, d | 43 | local headers = {} |
| 44 | end | 44 | local sock = respt.tmp.sock |
| 45 | 45 | local line, name, value, _ | |
| 46 | -- resquest_p forward declaration | 46 | -- store results |
| 47 | local request_p | 47 | respt.headers = headers |
| 48 | |||
| 49 | local function receive_headers(sock, headers) | ||
| 50 | local line, name, value | ||
| 51 | -- get first line | 48 | -- get first line |
| 52 | line = socket.try(sock:receive()) | 49 | line = socket.try(sock:receive()) |
| 53 | -- headers go until a blank line is found | 50 | -- headers go until a blank line is found |
| 54 | while line ~= "" do | 51 | while line ~= "" do |
| 55 | -- get field-name and value | 52 | -- get field-name and value |
| 56 | name, value = shift(string.find(line, "^(.-):%s*(.*)")) | 53 | _, _, name, value = string.find(line, "^(.-):%s*(.*)") |
| 57 | assert(name and value, "malformed reponse headers") | 54 | assert(name and value, "malformed reponse headers") |
| 58 | name = string.lower(name) | 55 | name = string.lower(name) |
| 59 | -- get next line (value might be folded) | 56 | -- get next line (value might be folded) |
| @@ -100,7 +97,10 @@ local function receive_body_bychunks(sock, sink) | |||
| 100 | -- let callback know we are done | 97 | -- let callback know we are done |
| 101 | hand(sink, nil) | 98 | hand(sink, nil) |
| 102 | -- servers shouldn't send trailer headers, but who trusts them? | 99 | -- servers shouldn't send trailer headers, but who trusts them? |
| 103 | receive_headers(sock, {}) | 100 | local line = socket.try(sock:receive()) |
| 101 | while line ~= "" do | ||
| 102 | line = socket.try(sock:receive()) | ||
| 103 | end | ||
| 104 | end | 104 | end |
| 105 | 105 | ||
| 106 | local function receive_body_bylength(sock, length, sink) | 106 | local function receive_body_bylength(sock, length, sink) |
| @@ -245,7 +245,7 @@ local function open(reqt, respt) | |||
| 245 | socket.try(sock:connect(host, port)) | 245 | socket.try(sock:connect(host, port)) |
| 246 | end | 246 | end |
| 247 | 247 | ||
| 248 | function adjust_headers(reqt, respt) | 248 | local function adjust_headers(reqt, respt) |
| 249 | local lower = {} | 249 | local lower = {} |
| 250 | local headers = reqt.headers or {} | 250 | local headers = reqt.headers or {} |
| 251 | -- set default headers | 251 | -- set default headers |
| @@ -261,7 +261,7 @@ function adjust_headers(reqt, respt) | |||
| 261 | respt.tmp.headers = lower | 261 | respt.tmp.headers = lower |
| 262 | end | 262 | end |
| 263 | 263 | ||
| 264 | function parse_url(reqt, respt) | 264 | local function parse_url(reqt, respt) |
| 265 | -- parse url with default fields | 265 | -- parse url with default fields |
| 266 | local parsed = socket.url.parse(reqt.url, { | 266 | local parsed = socket.url.parse(reqt.url, { |
| 267 | host = "", | 267 | host = "", |
| @@ -280,11 +280,16 @@ function parse_url(reqt, respt) | |||
| 280 | respt.tmp.parsed = parsed | 280 | respt.tmp.parsed = parsed |
| 281 | end | 281 | end |
| 282 | 282 | ||
| 283 | -- forward declaration | ||
| 284 | local request_p | ||
| 285 | |||
| 283 | local function should_authorize(reqt, respt) | 286 | local function should_authorize(reqt, respt) |
| 284 | -- if there has been an authorization attempt, it must have failed | 287 | -- if there has been an authorization attempt, it must have failed |
| 285 | if reqt.headers and reqt.headers["authorization"] then return nil end | 288 | if reqt.headers and reqt.headers["authorization"] then return nil end |
| 286 | -- if we don't have authorization information, we can't retry | 289 | -- if last attempt didn't fail due to lack of authentication, |
| 287 | return respt.tmp.parsed.user and respt.tmp.parsed.password | 290 | -- or we don't have authorization information, we can't retry |
| 291 | return respt.code == 401 and | ||
| 292 | respt.tmp.parsed.user and respt.tmp.parsed.password | ||
| 288 | end | 293 | end |
| 289 | 294 | ||
| 290 | local function clone(headers) | 295 | local function clone(headers) |
| @@ -338,14 +343,14 @@ local function redirect(reqt, respt) | |||
| 338 | if respt.headers then respt.headers.location = redirt.url end | 343 | if respt.headers then respt.headers.location = redirt.url end |
| 339 | end | 344 | end |
| 340 | 345 | ||
| 346 | -- execute a request of through an exception | ||
| 341 | function request_p(reqt, respt) | 347 | function request_p(reqt, respt) |
| 342 | parse_url(reqt, respt) | 348 | parse_url(reqt, respt) |
| 343 | adjust_headers(reqt, respt) | 349 | adjust_headers(reqt, respt) |
| 344 | open(reqt, respt) | 350 | open(reqt, respt) |
| 345 | send_request(reqt, respt) | 351 | send_request(reqt, respt) |
| 346 | receive_status(reqt, respt) | 352 | receive_status(reqt, respt) |
| 347 | respt.headers = {} | 353 | receive_headers(reqt, respt) |
| 348 | receive_headers(respt.tmp.sock, respt.headers) | ||
| 349 | if should_redirect(reqt, respt) then | 354 | if should_redirect(reqt, respt) then |
| 350 | respt.tmp.sock:close() | 355 | respt.tmp.sock:close() |
| 351 | redirect(reqt, respt) | 356 | redirect(reqt, respt) |
