aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiego Nehab <diego.nehab@gmail.com>2016-03-04 16:16:41 -0300
committerDiego Nehab <diego.nehab@gmail.com>2016-03-04 16:16:41 -0300
commit5b4b9158799293eeaf8439d40a7845b5b0a5e125 (patch)
tree1742149e3d2eced135ec23e16f73cd288c975190
parent944305dc21350fd2ec32a9552d893da86894fd62 (diff)
downloadluasocket-5b4b9158799293eeaf8439d40a7845b5b0a5e125.tar.gz
luasocket-5b4b9158799293eeaf8439d40a7845b5b0a5e125.tar.bz2
luasocket-5b4b9158799293eeaf8439d40a7845b5b0a5e125.zip
Remove global PORT. Fix https redirect.
-rw-r--r--doc/http.html7
-rw-r--r--src/http.lua42
2 files changed, 30 insertions, 19 deletions
diff --git a/doc/http.html b/doc/http.html
index cd41c0d..3b7a8b1 100644
--- a/doc/http.html
+++ b/doc/http.html
@@ -112,12 +112,15 @@ the HTTP module:
112</p> 112</p>
113 113
114<ul> 114<ul>
115<li> <tt>PORT</tt>: default port used for connections; 115<li> <tt>PROXY</tt>: default proxy used for connections;
116<li> <tt>PROXY</tt>: default proxy used for connections;
117<li> <tt>TIMEOUT</tt>: sets the timeout for all I/O operations; 116<li> <tt>TIMEOUT</tt>: sets the timeout for all I/O operations;
118<li> <tt>USERAGENT</tt>: default user agent reported to server. 117<li> <tt>USERAGENT</tt>: default user agent reported to server.
119</ul> 118</ul>
120 119
120<p class=note id="post">
121Note: These constants are global. Changing them will also
122change the behavior other code that might be using LuaSocket.
123</p>
121 124
122<!-- http.request ++++++++++++++++++++++++++++++++++++++++++++++++++++++ --> 125<!-- http.request ++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
123 126
diff --git a/src/http.lua b/src/http.lua
index 45ffa15..d6bcc91 100644
--- a/src/http.lua
+++ b/src/http.lua
@@ -23,11 +23,14 @@ local _M = socket.http
23----------------------------------------------------------------------------- 23-----------------------------------------------------------------------------
24-- connection timeout in seconds 24-- connection timeout in seconds
25_M.TIMEOUT = 60 25_M.TIMEOUT = 60
26-- default port for document retrieval
27_M.PORT = 80
28-- user agent field sent in request 26-- user agent field sent in request
29_M.USERAGENT = socket._VERSION 27_M.USERAGENT = socket._VERSION
30 28
29-- supported schemes
30local SCHEMES = { ["http"] = true }
31-- default port for document retrieval
32local PORT = 80
33
31----------------------------------------------------------------------------- 34-----------------------------------------------------------------------------
32-- Reads MIME headers from a connection, unfolding where needed 35-- Reads MIME headers from a connection, unfolding where needed
33----------------------------------------------------------------------------- 36-----------------------------------------------------------------------------
@@ -114,7 +117,7 @@ function _M.open(host, port, create)
114 h.try = socket.newtry(function() h:close() end) 117 h.try = socket.newtry(function() h:close() end)
115 -- set timeout before connecting 118 -- set timeout before connecting
116 h.try(c:settimeout(_M.TIMEOUT)) 119 h.try(c:settimeout(_M.TIMEOUT))
117 h.try(c:connect(host, port or _M.PORT)) 120 h.try(c:connect(host, port or PORT))
118 -- here everything worked 121 -- here everything worked
119 return h 122 return h
120end 123end
@@ -218,7 +221,7 @@ local function adjustheaders(reqt)
218 } 221 }
219 -- if we have authentication information, pass it along 222 -- if we have authentication information, pass it along
220 if reqt.user and reqt.password then 223 if reqt.user and reqt.password then
221 lower["authorization"] = 224 lower["authorization"] =
222 "Basic " .. (mime.b64(reqt.user .. ":" .. reqt.password)) 225 "Basic " .. (mime.b64(reqt.user .. ":" .. reqt.password))
223 end 226 end
224 -- if we have proxy authentication information, pass it along 227 -- if we have proxy authentication information, pass it along
@@ -226,7 +229,7 @@ local function adjustheaders(reqt)
226 if proxy then 229 if proxy then
227 proxy = url.parse(proxy) 230 proxy = url.parse(proxy)
228 if proxy.user and proxy.password then 231 if proxy.user and proxy.password then
229 lower["proxy-authorization"] = 232 lower["proxy-authorization"] =
230 "Basic " .. (mime.b64(proxy.user .. ":" .. proxy.password)) 233 "Basic " .. (mime.b64(proxy.user .. ":" .. proxy.password))
231 end 234 end
232 end 235 end
@@ -240,7 +243,7 @@ end
240-- default url parts 243-- default url parts
241local default = { 244local default = {
242 host = "", 245 host = "",
243 port = _M.PORT, 246 port = PORT,
244 path ="/", 247 path ="/",
245 scheme = "http" 248 scheme = "http"
246} 249}
@@ -250,9 +253,10 @@ local function adjustrequest(reqt)
250 local nreqt = reqt.url and url.parse(reqt.url, default) or {} 253 local nreqt = reqt.url and url.parse(reqt.url, default) or {}
251 -- explicit components override url 254 -- explicit components override url
252 for i,v in base.pairs(reqt) do nreqt[i] = v end 255 for i,v in base.pairs(reqt) do nreqt[i] = v end
253 if nreqt.port == "" then nreqt.port = 80 end 256 if nreqt.port == "" then nreqt.port = PORT end
254 socket.try(nreqt.host and nreqt.host ~= "", 257 if not (nreqt.host and nreqt.host ~= "") then
255 "invalid host '" .. base.tostring(nreqt.host) .. "'") 258 socket.try(nil, "invalid host '" .. base.tostring(nreqt.host) .. "'")
259 end
256 -- compute uri if user hasn't overriden 260 -- compute uri if user hasn't overriden
257 nreqt.uri = reqt.uri or adjusturi(nreqt) 261 nreqt.uri = reqt.uri or adjusturi(nreqt)
258 -- adjust headers in request 262 -- adjust headers in request
@@ -263,9 +267,13 @@ local function adjustrequest(reqt)
263end 267end
264 268
265local function shouldredirect(reqt, code, headers) 269local function shouldredirect(reqt, code, headers)
266 return headers.location and 270 local location = headers.location
267 string.gsub(headers.location, "%s", "") ~= "" and 271 if not location then return false end
268 (reqt.redirect ~= false) and 272 location = string.gsub(location, "%s", "")
273 if location == "" then return false end
274 local scheme = string.match(location, "^([%w][%w%+%-%.]*)%:")
275 if scheme and not SCHEMES[scheme] then return false end
276 return (reqt.redirect ~= false) and
269 (code == 301 or code == 302 or code == 303 or code == 307) and 277 (code == 301 or code == 302 or code == 303 or code == 307) and
270 (not reqt.method or reqt.method == "GET" or reqt.method == "HEAD") 278 (not reqt.method or reqt.method == "GET" or reqt.method == "HEAD")
271 and (not reqt.nredirects or reqt.nredirects < 5) 279 and (not reqt.nredirects or reqt.nredirects < 5)
@@ -289,10 +297,10 @@ local trequest, tredirect
289 source = reqt.source, 297 source = reqt.source,
290 sink = reqt.sink, 298 sink = reqt.sink,
291 headers = reqt.headers, 299 headers = reqt.headers,
292 proxy = reqt.proxy, 300 proxy = reqt.proxy,
293 nredirects = (reqt.nredirects or 0) + 1, 301 nredirects = (reqt.nredirects or 0) + 1,
294 create = reqt.create 302 create = reqt.create
295 } 303 }
296 -- pass location header back as a hint we redirected 304 -- pass location header back as a hint we redirected
297 headers = headers or {} 305 headers = headers or {}
298 headers.location = headers.location or location 306 headers.location = headers.location or location
@@ -309,7 +317,7 @@ end
309 h:sendheaders(nreqt.headers) 317 h:sendheaders(nreqt.headers)
310 -- if there is a body, send it 318 -- if there is a body, send it
311 if nreqt.source then 319 if nreqt.source then
312 h:sendbody(nreqt.headers, nreqt.source, nreqt.step) 320 h:sendbody(nreqt.headers, nreqt.source, nreqt.step)
313 end 321 end
314 local code, status = h:receivestatusline() 322 local code, status = h:receivestatusline()
315 -- if it is an HTTP/0.9 server, simply get the body and we are done 323 -- if it is an HTTP/0.9 server, simply get the body and we are done
@@ -319,13 +327,13 @@ end
319 end 327 end
320 local headers 328 local headers
321 -- ignore any 100-continue messages 329 -- ignore any 100-continue messages
322 while code == 100 do 330 while code == 100 do
323 headers = h:receiveheaders() 331 headers = h:receiveheaders()
324 code, status = h:receivestatusline() 332 code, status = h:receivestatusline()
325 end 333 end
326 headers = h:receiveheaders() 334 headers = h:receiveheaders()
327 -- at this point we should have a honest reply from the server 335 -- at this point we should have a honest reply from the server
328 -- we can't redirect if we already used the source, so we report the error 336 -- we can't redirect if we already used the source, so we report the error
329 if shouldredirect(nreqt, code, headers) and not nreqt.source then 337 if shouldredirect(nreqt, code, headers) and not nreqt.source then
330 h:close() 338 h:close()
331 return tredirect(reqt, headers.location) 339 return tredirect(reqt, headers.location)