aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDiego Nehab <diego@tecgraf.puc-rio.br>2001-08-07 19:50:04 +0000
committerDiego Nehab <diego@tecgraf.puc-rio.br>2001-08-07 19:50:04 +0000
commitcb61077f7a8c71536c3ad331f041bc4ab97c719c (patch)
treed520adce2f440362ba6a8fda7a4627c28b8b34ab /src
parent3143c58e0fe839e849aca3b29e0928bd9c1df6a5 (diff)
downloadluasocket-cb61077f7a8c71536c3ad331f041bc4ab97c719c.tar.gz
luasocket-cb61077f7a8c71536c3ad331f041bc4ab97c719c.tar.bz2
luasocket-cb61077f7a8c71536c3ad331f041bc4ab97c719c.zip
Minor documentation changes.
Constants were moved to Public table. Updated to use new fast concatenation module (concat.lua).
Diffstat (limited to 'src')
-rw-r--r--src/http.lua104
1 files changed, 52 insertions, 52 deletions
diff --git a/src/http.lua b/src/http.lua
index e68cf22..1e4c2cd 100644
--- a/src/http.lua
+++ b/src/http.lua
@@ -1,9 +1,10 @@
1----------------------------------------------------------------------------- 1-----------------------------------------------------------------------------
2-- Full HTTP/1.1 client support for the Lua language using the 2-- HTTP/1.1 client support for the Lua language.
3-- LuaSocket 1.4a toolkit. 3-- LuaSocket 1.4a toolkit.
4-- Author: Diego Nehab 4-- Author: Diego Nehab
5-- Date: 26/12/2000 5-- Date: 26/12/2000
6-- Conforming to: RFC 2068 6-- Conforming to: RFC 2616, LTN7
7-- RCS ID: $Id$
7----------------------------------------------------------------------------- 8-----------------------------------------------------------------------------
8 9
9local Public, Private = {}, {} 10local Public, Private = {}, {}
@@ -13,27 +14,27 @@ HTTP = Public
13-- Program constants 14-- Program constants
14----------------------------------------------------------------------------- 15-----------------------------------------------------------------------------
15-- connection timeout in seconds 16-- connection timeout in seconds
16Private.TIMEOUT = 60 17Public.TIMEOUT = 60
17-- default port for document retrieval 18-- default port for document retrieval
18Private.PORT = 80 19Public.PORT = 80
19-- user agent field sent in request 20-- user agent field sent in request
20Private.USERAGENT = "LuaSocket 1.4a" 21Public.USERAGENT = "LuaSocket 1.4a"
21-- block size used in transfers 22-- block size used in transfers
22Private.BLOCKSIZE = 8192 23Public.BLOCKSIZE = 8192
23 24
24----------------------------------------------------------------------------- 25-----------------------------------------------------------------------------
25-- Required libraries 26-- Required libraries
26----------------------------------------------------------------------------- 27-----------------------------------------------------------------------------
27dofile "buffer.lua" 28dofile "buffer.lua"
28dofile "url.lua" 29dofile "url.lua"
29dofile "encode.lua" 30dofile "code.lua"
30 31
31----------------------------------------------------------------------------- 32-----------------------------------------------------------------------------
32-- Tries to get a pattern from the server and closes socket on error 33-- Tries to get a pattern from the server and closes socket on error
33-- sock: socket connected to the server 34-- sock: socket connected to the server
34-- pattern: pattern to receive 35-- ...: patterns to receive
35-- Returns 36-- Returns
36-- data: line received or nil in case of error 37-- ...: received patterns
37-- err: error message if any 38-- err: error message if any
38----------------------------------------------------------------------------- 39-----------------------------------------------------------------------------
39function Private.try_receive(...) 40function Private.try_receive(...)
@@ -60,11 +61,11 @@ function Private.try_send(sock, data)
60end 61end
61 62
62----------------------------------------------------------------------------- 63-----------------------------------------------------------------------------
63-- Retrieves status code from http status line 64-- Computes status code from HTTP status line
64-- Input 65-- Input
65-- line: http status line 66-- line: HTTP status line
66-- Returns 67-- Returns
67-- code: integer with status code 68-- code: integer with status code, or nil if malformed line
68----------------------------------------------------------------------------- 69-----------------------------------------------------------------------------
69function Private.get_statuscode(line) 70function Private.get_statuscode(line)
70 local code, _ 71 local code, _
@@ -73,12 +74,12 @@ function Private.get_statuscode(line)
73end 74end
74 75
75----------------------------------------------------------------------------- 76-----------------------------------------------------------------------------
76-- Receive server reply messages, parsing status code 77-- Receive server reply messages, parsing for status code
77-- Input 78-- Input
78-- sock: socket connected to the server 79-- sock: socket connected to the server
79-- Returns 80-- Returns
80-- code: server status code or nil if error 81-- code: server status code or nil if error
81-- line: full http status line 82-- line: full HTTP status line
82-- err: error message if any 83-- err: error message if any
83----------------------------------------------------------------------------- 84-----------------------------------------------------------------------------
84function Private.receive_status(sock) 85function Private.receive_status(sock)
@@ -108,7 +109,7 @@ function Private.receive_headers(sock, headers)
108 -- headers go until a blank line is found 109 -- headers go until a blank line is found
109 while line ~= "" do 110 while line ~= "" do
110 -- get field-name and value 111 -- get field-name and value
111 _,_, name, value = strfind(line, "(.-):%s*(.*)") 112 _,_, name, value = strfind(line, "^(.-):%s*(.*)")
112 if not name or not value then 113 if not name or not value then
113 sock:close() 114 sock:close()
114 return nil, "malformed reponse headers" 115 return nil, "malformed reponse headers"
@@ -145,14 +146,14 @@ function Private.receivebody_bychunks(sock, headers, receive_cb)
145 -- get chunk size, skip extention 146 -- get chunk size, skip extention
146 line, err = %Private.try_receive(sock) 147 line, err = %Private.try_receive(sock)
147 if err then 148 if err then
148 local _, uerr = receive_cb(nil, err) 149 local go, uerr = receive_cb(nil, err)
149 return uerr or err 150 return uerr or err
150 end 151 end
151 size = tonumber(gsub(line, ";.*", ""), 16) 152 size = tonumber(gsub(line, ";.*", ""), 16)
152 if not size then 153 if not size then
153 err = "invalid chunk size" 154 err = "invalid chunk size"
154 sock:close() 155 sock:close()
155 _, uerr = receive_cb(nil, err) 156 go, uerr = receive_cb(nil, err)
156 return uerr or err 157 return uerr or err
157 end 158 end
158 -- was it the last chunk? 159 -- was it the last chunk?
@@ -160,7 +161,7 @@ function Private.receivebody_bychunks(sock, headers, receive_cb)
160 -- get chunk 161 -- get chunk
161 chunk, err = %Private.try_receive(sock, size) 162 chunk, err = %Private.try_receive(sock, size)
162 if err then 163 if err then
163 _, uerr = receive_cb(nil, err) 164 go, uerr = receive_cb(nil, err)
164 return uerr or err 165 return uerr or err
165 end 166 end
166 -- pass chunk to callback 167 -- pass chunk to callback
@@ -172,7 +173,7 @@ function Private.receivebody_bychunks(sock, headers, receive_cb)
172 -- skip CRLF on end of chunk 173 -- skip CRLF on end of chunk
173 _, err = %Private.try_receive(sock) 174 _, err = %Private.try_receive(sock)
174 if err then 175 if err then
175 _, uerr = receive_cb(nil, err) 176 go, uerr = receive_cb(nil, err)
176 return uerr or err 177 return uerr or err
177 end 178 end
178 end 179 end
@@ -181,11 +182,11 @@ function Private.receivebody_bychunks(sock, headers, receive_cb)
181 -- being caught unprepaired. 182 -- being caught unprepaired.
182 headers, err = %Private.receive_headers(sock, headers) 183 headers, err = %Private.receive_headers(sock, headers)
183 if err then 184 if err then
184 _, uerr = receive_cb(nil, err) 185 go, uerr = receive_cb(nil, err)
185 return uerr or err 186 return uerr or err
186 end 187 end
187 -- let callback know we are done 188 -- let callback know we are done
188 _, uerr = receive_cb("") 189 go, uerr = receive_cb("")
189 return uerr 190 return uerr
190end 191end
191 192
@@ -193,6 +194,7 @@ end
193-- Receives a message body by content-length 194-- Receives a message body by content-length
194-- Input 195-- Input
195-- sock: socket connected to the server 196-- sock: socket connected to the server
197-- length: message body length
196-- receive_cb: function to receive chunks 198-- receive_cb: function to receive chunks
197-- Returns 199-- Returns
198-- nil if successfull or an error message in case of error 200-- nil if successfull or an error message in case of error
@@ -200,7 +202,7 @@ end
200function Private.receivebody_bylength(sock, length, receive_cb) 202function Private.receivebody_bylength(sock, length, receive_cb)
201 local uerr, go 203 local uerr, go
202 while length > 0 do 204 while length > 0 do
203 local size = min(%Private.BLOCKSIZE, length) 205 local size = min(%Public.BLOCKSIZE, length)
204 local chunk, err = sock:receive(size) 206 local chunk, err = sock:receive(size)
205 if err then 207 if err then
206 go, uerr = receive_cb(nil, err) 208 go, uerr = receive_cb(nil, err)
@@ -228,14 +230,14 @@ end
228function Private.receivebody_untilclosed(sock, receive_cb) 230function Private.receivebody_untilclosed(sock, receive_cb)
229 local err, go, uerr 231 local err, go, uerr
230 while 1 do 232 while 1 do
231 local chunk, err = sock:receive(%Private.BLOCKSIZE) 233 local chunk, err = sock:receive(%Public.BLOCKSIZE)
232 if err == "closed" or not err then 234 if err == "closed" or not err then
233 go, uerr = receive_cb(chunk) 235 go, uerr = receive_cb(chunk)
234 if not go then 236 if not go then
235 sock:close() 237 sock:close()
236 return uerr or "aborted by callback" 238 return uerr or "aborted by callback"
237 end 239 end
238 if err then break end 240 if err == "closed" then break end
239 else 241 else
240 go, uerr = callback(nil, err) 242 go, uerr = callback(nil, err)
241 return uerr or err 243 return uerr or err
@@ -246,7 +248,7 @@ function Private.receivebody_untilclosed(sock, receive_cb)
246end 248end
247 249
248----------------------------------------------------------------------------- 250-----------------------------------------------------------------------------
249-- Receives http response body 251-- Receives HTTP response body
250-- Input 252-- Input
251-- sock: socket connected to the server 253-- sock: socket connected to the server
252-- headers: response header fields 254-- headers: response header fields
@@ -270,7 +272,7 @@ function Private.receive_body(sock, headers, receive_cb)
270end 272end
271 273
272----------------------------------------------------------------------------- 274-----------------------------------------------------------------------------
273-- Drop http response body 275-- Drop HTTP response body
274-- Input 276-- Input
275-- sock: socket connected to the server 277-- sock: socket connected to the server
276-- headers: response header fields 278-- headers: response header fields
@@ -286,7 +288,7 @@ end
286-- Input 288-- Input
287-- data: data connection 289-- data: data connection
288-- send_cb: callback to produce file contents 290-- send_cb: callback to produce file contents
289-- chunk, size: first callback results 291-- chunk, size: first callback return values
290-- Returns 292-- Returns
291-- nil if successfull, or an error message in case of error 293-- nil if successfull, or an error message in case of error
292----------------------------------------------------------------------------- 294-----------------------------------------------------------------------------
@@ -311,20 +313,20 @@ function Private.send_indirect(data, send_cb, chunk, size)
311end 313end
312 314
313----------------------------------------------------------------------------- 315-----------------------------------------------------------------------------
314-- Sends a http request message through socket 316-- Sends a HTTP request message through socket
315-- Input 317-- Input
316-- sock: socket connected to the server 318-- sock: socket connected to the server
317-- method: request method to be used 319-- method: request method to be used
318-- path: url path 320-- uri: request uri
319-- headers: request headers to be sent 321-- headers: request headers to be sent
320-- body_cb: callback to send request message body 322-- body_cb: callback to send request message body
321-- Returns 323-- Returns
322-- err: nil in case of success, error message otherwise 324-- err: nil in case of success, error message otherwise
323----------------------------------------------------------------------------- 325-----------------------------------------------------------------------------
324function Private.send_request(sock, method, path, headers, body_cb) 326function Private.send_request(sock, method, uri, headers, body_cb)
325 local chunk, size, done, err 327 local chunk, size, done, err
326 -- send request line 328 -- send request line
327 err = %Private.try_send(sock, method .. " " .. path .. " HTTP/1.1\r\n") 329 err = %Private.try_send(sock, method .. " " .. uri .. " HTTP/1.1\r\n")
328 if err then return err end 330 if err then return err end
329 -- if there is a request message body, add content-length header 331 -- if there is a request message body, add content-length header
330 if body_cb then 332 if body_cb then
@@ -370,7 +372,7 @@ end
370-- Converts field names to lowercase and adds a few needed headers 372-- Converts field names to lowercase and adds a few needed headers
371-- Input 373-- Input
372-- headers: request header fields 374-- headers: request header fields
373-- parsed: parsed url components 375-- parsed: parsed request URL
374-- Returns 376-- Returns
375-- lower: a table with the same headers, but with lowercase field names 377-- lower: a table with the same headers, but with lowercase field names
376----------------------------------------------------------------------------- 378-----------------------------------------------------------------------------
@@ -378,7 +380,7 @@ function Private.fill_headers(headers, parsed)
378 local lower = {} 380 local lower = {}
379 headers = headers or {} 381 headers = headers or {}
380 -- set default headers 382 -- set default headers
381 lower["user-agent"] = %Private.USERAGENT 383 lower["user-agent"] = %Public.USERAGENT
382 lower["host"] = parsed.host 384 lower["host"] = parsed.host
383 -- override with user values 385 -- override with user values
384 for i,v in headers do 386 for i,v in headers do
@@ -393,7 +395,7 @@ end
393-- Decides wether we should follow retry with authorization formation 395-- Decides wether we should follow retry with authorization formation
394-- Input 396-- Input
395-- request: a table with the original request information 397-- request: a table with the original request information
396-- parsed: parsed request url 398-- parsed: parsed request URL
397-- response: a table with the server response information 399-- response: a table with the server response information
398-- Returns 400-- Returns
399-- 1 if we should retry, nil otherwise 401-- 1 if we should retry, nil otherwise
@@ -410,14 +412,14 @@ end
410-- Returns the result of retrying a request with authorization information 412-- Returns the result of retrying a request with authorization information
411-- Input 413-- Input
412-- request: a table with the original request information 414-- request: a table with the original request information
413-- parsed: parsed request url 415-- parsed: parsed request URL
414-- response: a table with the server response information 416-- response: a table with the server response information
415-- Returns 417-- Returns
416-- response: result of target redirection 418-- response: result of target redirection
417----------------------------------------------------------------------------- 419-----------------------------------------------------------------------------
418function Private.authorize(request, parsed, response) 420function Private.authorize(request, parsed, response)
419 request.headers["authorization"] = "Basic " .. 421 request.headers["authorization"] = "Basic " ..
420 base64(parsed.user .. ":" .. parsed.password) 422 Code.base64(parsed.user .. ":" .. parsed.password)
421 local authorize = { 423 local authorize = {
422 redirects = request.redirects, 424 redirects = request.redirects,
423 method = request.method, 425 method = request.method,
@@ -459,9 +461,9 @@ function Private.redirect(request, response)
459 local redirect = { 461 local redirect = {
460 redirects = redirects, 462 redirects = redirects,
461 method = request.method, 463 method = request.method,
462 -- the RFC says the redirect url has to be absolute, but some 464 -- the RFC says the redirect URL has to be absolute, but some
463 -- servers do not respect that 465 -- servers do not respect that
464 url = URL.build_absolute(request.url,response.headers["location"]), 466 url = URL.absolute_url(request.url, response.headers["location"]),
465 body_cb = request.body_cb, 467 body_cb = request.body_cb,
466 headers = request.headers 468 headers = request.headers
467 } 469 }
@@ -469,9 +471,9 @@ function Private.redirect(request, response)
469end 471end
470 472
471----------------------------------------------------------------------------- 473-----------------------------------------------------------------------------
472-- Computes the request URI from the given URL 474-- Computes the request URI from the parsed request URL
473-- Input 475-- Input
474-- parsed: parsed url 476-- parsed: parsed URL
475-- Returns 477-- Returns
476-- uri: request URI for parsed URL 478-- uri: request URI for parsed URL
477----------------------------------------------------------------------------- 479-----------------------------------------------------------------------------
@@ -505,9 +507,8 @@ end
505-- error: error message, or nil if successfull 507-- error: error message, or nil if successfull
506----------------------------------------------------------------------------- 508-----------------------------------------------------------------------------
507function Public.request_indirect(request, response) 509function Public.request_indirect(request, response)
508 -- get url components 510 local parsed = URL.parse_url(request.url, {port = %Public.PORT, path ="/"})
509 local parsed = URL.parse(request.url, {port = %Private.PORT, path ="/"}) 511 -- explicit authentication info overrides that given by the URL
510 -- explicit authentication info overrides that given by the url
511 parsed.user = request.user or parsed.user 512 parsed.user = request.user or parsed.user
512 parsed.password = request.password or parsed.password 513 parsed.password = request.password or parsed.password
513 -- default method 514 -- default method
@@ -519,7 +520,7 @@ function Public.request_indirect(request, response)
519 sock, response.error = connect(parsed.host, parsed.port) 520 sock, response.error = connect(parsed.host, parsed.port)
520 if not sock then return response end 521 if not sock then return response end
521 -- set connection timeout so that we do not hang forever 522 -- set connection timeout so that we do not hang forever
522 sock:timeout(%Private.TIMEOUT) 523 sock:timeout(%Public.TIMEOUT)
523 -- send request message 524 -- send request message
524 response.error = %Private.send_request(sock, request.method, 525 response.error = %Private.send_request(sock, request.method,
525 %Private.request_uri(parsed), request.headers, request.body_cb) 526 %Private.request_uri(parsed), request.headers, request.body_cb)
@@ -555,7 +556,7 @@ end
555-- Input 556-- Input
556-- request: a table with the following fields 557-- request: a table with the following fields
557-- method: "GET", "PUT", "POST" etc (defaults to "GET") 558-- method: "GET", "PUT", "POST" etc (defaults to "GET")
558-- url: target url, i.e. the document to be retrieved 559-- url: request URL, i.e. the document to be retrieved
559-- user, password: authentication information 560-- user, password: authentication information
560-- headers: request header fields, or nil if none 561-- headers: request header fields, or nil if none
561-- body: request message body as a string, or nil if none 562-- body: request message body as a string, or nil if none
@@ -572,17 +573,16 @@ function Public.request(request)
572 local response = {} 573 local response = {}
573 if request.body then 574 if request.body then
574 request.body_cb = function() 575 request.body_cb = function()
575 return %request.body, strlen(%request.body) 576 return %request.body, strlen(%request.body)
576 end 577 end
577 end 578 end
578 local auxiliar = { buf = buf_create() } 579 local cat = Concat.create()
579 response.body_cb = function(chunk, err) 580 response.body_cb = function(chunk, err)
580 if not chunk then %auxiliar.buf = nil end 581 %cat:addstring(chunk)
581 buf_addstring(%auxiliar.buf, chunk)
582 return 1 582 return 1
583 end 583 end
584 %Public.request_indirect(request, response) 584 %Public.request_indirect(request, response)
585 response.body = buf_getresult(auxiliar.buf) 585 response.body = cat:getresult()
586 response.body_cb = nil 586 response.body_cb = nil
587 return response 587 return response
588end 588end
@@ -590,7 +590,7 @@ end
590----------------------------------------------------------------------------- 590-----------------------------------------------------------------------------
591-- Retrieves a URL by the method "GET" 591-- Retrieves a URL by the method "GET"
592-- Input 592-- Input
593-- url: target url, i.e. the document to be retrieved 593-- url: request URL, i.e. the document to be retrieved
594-- Returns 594-- Returns
595-- body: response message body, or nil if failed 595-- body: response message body, or nil if failed
596-- headers: response header fields received, or nil if failed 596-- headers: response header fields received, or nil if failed
@@ -609,7 +609,7 @@ end
609----------------------------------------------------------------------------- 609-----------------------------------------------------------------------------
610-- Retrieves a URL by the method "POST" 610-- Retrieves a URL by the method "POST"
611-- Input 611-- Input
612-- url: target url, i.e. the document to be retrieved 612-- url: request URL, i.e. the document to be retrieved
613-- body: request message body, or nil if none 613-- body: request message body, or nil if none
614-- Returns 614-- Returns
615-- body: response message body, or nil if failed 615-- body: response message body, or nil if failed