diff options
| author | Diego Nehab <diego@tecgraf.puc-rio.br> | 2006-03-13 07:16:39 +0000 |
|---|---|---|
| committer | Diego Nehab <diego@tecgraf.puc-rio.br> | 2006-03-13 07:16:39 +0000 |
| commit | 6248b915cba040a3d04fedd100637e1465a43cc7 (patch) | |
| tree | d87bde69c65934524b2102f47ac48cf28897bf80 /src/http.lua | |
| parent | 00e74c304c7aa917fffd1e5b7adedfa05727333c (diff) | |
| download | luasocket-6248b915cba040a3d04fedd100637e1465a43cc7.tar.gz luasocket-6248b915cba040a3d04fedd100637e1465a43cc7.tar.bz2 luasocket-6248b915cba040a3d04fedd100637e1465a43cc7.zip | |
Fixing bugs...
Diffstat (limited to 'src/http.lua')
| -rw-r--r-- | src/http.lua | 69 |
1 files changed, 51 insertions, 18 deletions
diff --git a/src/http.lua b/src/http.lua index 1834061..91600e7 100644 --- a/src/http.lua +++ b/src/http.lua | |||
| @@ -15,6 +15,7 @@ local mime = require("mime") | |||
| 15 | local string = require("string") | 15 | local string = require("string") |
| 16 | local base = _G | 16 | local base = _G |
| 17 | local table = require("table") | 17 | local table = require("table") |
| 18 | local print = print | ||
| 18 | module("socket.http") | 19 | module("socket.http") |
| 19 | 20 | ||
| 20 | ----------------------------------------------------------------------------- | 21 | ----------------------------------------------------------------------------- |
| @@ -194,16 +195,19 @@ local function adjustproxy(reqt) | |||
| 194 | end | 195 | end |
| 195 | end | 196 | end |
| 196 | 197 | ||
| 197 | local function adjustheaders(headers, host) | 198 | local function adjustheaders(reqt) |
| 198 | -- default headers | 199 | -- default headers |
| 199 | local lower = { | 200 | local lower = { |
| 200 | ["user-agent"] = USERAGENT, | 201 | ["user-agent"] = USERAGENT, |
| 201 | ["host"] = host, | 202 | ["host"] = reqt.host, |
| 202 | ["connection"] = "close, TE", | 203 | ["connection"] = "close, TE", |
| 203 | ["te"] = "trailers" | 204 | ["te"] = "trailers" |
| 204 | } | 205 | } |
| 206 | -- if we are sending a body, tell server to let us know | ||
| 207 | -- if it this is a waste of time | ||
| 208 | if reqt.source then lower["expect"] = "100-continue" end | ||
| 205 | -- override with user headers | 209 | -- override with user headers |
| 206 | for i,v in base.pairs(headers or lower) do | 210 | for i,v in base.pairs(reqt.headers or lower) do |
| 207 | lower[string.lower(i)] = v | 211 | lower[string.lower(i)] = v |
| 208 | end | 212 | end |
| 209 | return lower | 213 | return lower |
| @@ -229,7 +233,7 @@ local function adjustrequest(reqt) | |||
| 229 | -- ajust host and port if there is a proxy | 233 | -- ajust host and port if there is a proxy |
| 230 | nreqt.host, nreqt.port = adjustproxy(nreqt) | 234 | nreqt.host, nreqt.port = adjustproxy(nreqt) |
| 231 | -- adjust headers in request | 235 | -- adjust headers in request |
| 232 | nreqt.headers = adjustheaders(nreqt.headers, nreqt.host) | 236 | nreqt.headers = adjustheaders(nreqt) |
| 233 | return nreqt | 237 | return nreqt |
| 234 | end | 238 | end |
| 235 | 239 | ||
| @@ -257,6 +261,7 @@ local function shouldreceivebody(reqt, code) | |||
| 257 | return 1 | 261 | return 1 |
| 258 | end | 262 | end |
| 259 | 263 | ||
| 264 | |||
| 260 | -- forward declarations | 265 | -- forward declarations |
| 261 | local trequest, tauthorize, tredirect | 266 | local trequest, tauthorize, tredirect |
| 262 | 267 | ||
| @@ -274,46 +279,74 @@ function tredirect(reqt, location) | |||
| 274 | source = reqt.source, | 279 | source = reqt.source, |
| 275 | sink = reqt.sink, | 280 | sink = reqt.sink, |
| 276 | headers = reqt.headers, | 281 | headers = reqt.headers, |
| 277 | proxy = reqt.proxy, | 282 | proxy = reqt.proxy, |
| 278 | nredirects = (reqt.nredirects or 0) + 1, | 283 | nredirects = (reqt.nredirects or 0) + 1, |
| 279 | connect = reqt.connect | 284 | connect = reqt.connect |
| 280 | } | 285 | } |
| 281 | -- pass location header back as a hint we redirected | 286 | -- pass location header back as a hint we redirected |
| 282 | headers.location = headers.location or location | 287 | headers.location = headers.location or location |
| 283 | return result, code, headers, status | 288 | return result, code, headers, status |
| 284 | end | 289 | end |
| 285 | 290 | ||
| 286 | function trequest(reqt) | 291 | function trequest(reqt) |
| 292 | -- we loop until we get what we want, or | ||
| 293 | -- until we are sure there is no way to get it | ||
| 287 | reqt = adjustrequest(reqt) | 294 | reqt = adjustrequest(reqt) |
| 288 | local h = open(reqt.host, reqt.port, reqt.create) | 295 | local h = open(reqt.host, reqt.port, reqt.create) |
| 296 | -- send request line and headers | ||
| 289 | h:sendrequestline(reqt.method, reqt.uri) | 297 | h:sendrequestline(reqt.method, reqt.uri) |
| 290 | h:sendheaders(reqt.headers) | 298 | h:sendheaders(reqt.headers) |
| 291 | if reqt.source then h:sendbody(reqt.headers, reqt.source, reqt.step) end | 299 | local code = 100 |
| 292 | local code, headers, status | 300 | local headers, status |
| 293 | code, status = h:receivestatusline() | 301 | -- if there is a body, check for server status |
| 294 | headers = h:receiveheaders() | 302 | if reqt.source then |
| 303 | local ready = socket.select({h.c}, nil, TIMEOUT) | ||
| 304 | if ready[h.c] then | ||
| 305 | -- here the server sent us something | ||
| 306 | code, status = h:receivestatusline() | ||
| 307 | headers = h:receiveheaders() | ||
| 308 | end | ||
| 309 | -- if server is happy, send body | ||
| 310 | if code == 100 then | ||
| 311 | h:sendbody(reqt.headers, reqt.source, reqt.step) | ||
| 312 | -- can't send body again! | ||
| 313 | reqt.source = nil | ||
| 314 | end | ||
| 315 | end | ||
| 316 | -- ignore all further 100-continue messages | ||
| 317 | while code == 100 do | ||
| 318 | code, status = h:receivestatusline() | ||
| 319 | headers = h:receiveheaders() | ||
| 320 | end | ||
| 321 | -- at this point we should have a honest reply from the server | ||
| 295 | if shouldredirect(reqt, code, headers) then | 322 | if shouldredirect(reqt, code, headers) then |
| 296 | h:close() | 323 | h:close() |
| 297 | return tredirect(reqt, headers.location) | 324 | return tredirect(reqt, headers.location) |
| 298 | elseif shouldauthorize(reqt, code) then | 325 | elseif shouldauthorize(reqt, code) then |
| 299 | h:close() | 326 | h:close() |
| 300 | return tauthorize(reqt) | 327 | return tauthorize(reqt) |
| 301 | elseif shouldreceivebody(reqt, code) then | 328 | else |
| 302 | h:receivebody(headers, reqt.sink, reqt.step) | 329 | -- here we are finally done |
| 330 | if shouldreceivebody(reqt, code) then | ||
| 331 | h:receivebody(headers, reqt.sink, reqt.step) | ||
| 332 | end | ||
| 333 | h:close() | ||
| 334 | return 1, code, headers, status | ||
| 303 | end | 335 | end |
| 304 | h:close() | ||
| 305 | return 1, code, headers, status | ||
| 306 | end | 336 | end |
| 307 | 337 | ||
| 308 | local function srequest(u, body) | 338 | local function srequest(u, b, h) |
| 309 | local t = {} | 339 | local t = {} |
| 310 | local reqt = { | 340 | local reqt = { |
| 311 | url = u, | 341 | url = u, |
| 312 | sink = ltn12.sink.table(t) | 342 | sink = ltn12.sink.table(t) |
| 313 | } | 343 | } |
| 314 | if body then | 344 | if b then |
| 315 | reqt.source = ltn12.source.string(body) | 345 | reqt.source = ltn12.source.string(b) |
| 316 | reqt.headers = { ["content-length"] = string.len(body) } | 346 | reqt.headers = h or {} |
| 347 | reqt.headers["content-length"] = string.len(b) | ||
| 348 | reqt.headers["content-type"] = reqt.headers["content-type"] or | ||
| 349 | "application/x-www-form-urlencoded" | ||
| 317 | reqt.method = "POST" | 350 | reqt.method = "POST" |
| 318 | end | 351 | end |
| 319 | local code, headers, status = socket.skip(1, trequest(reqt)) | 352 | local code, headers, status = socket.skip(1, trequest(reqt)) |
