src/https.lua

changeset 0
f7d2d78eb424
equal deleted inserted replaced
-1:000000000000 0:f7d2d78eb424
1 ----------------------------------------------------------------------------
2 -- LuaSec 0.4
3 -- Copyright (C) 2009 PUC-Rio
4 --
5 -- Author: Pablo Musa
6 -- Author: Tomas Guisasola
7 ---------------------------------------------------------------------------
8
9 local socket = require("socket")
10 local ssl = require("ssl")
11 local ltn12 = require("ltn12")
12 local http = require("socket.http")
13 local url = require("socket.url")
14
15 local table = require("table")
16 local string = require("string")
17
18 local try = socket.try
19 local type = type
20 local pairs = pairs
21 local getmetatable = getmetatable
22
23 module("ssl.https")
24
25 _VERSION = "0.4"
26 _COPYRIGHT = "LuaSec 0.4 - Copyright (C) 2009 PUC-Rio"
27
28 -- Default settings
29 PORT = 443
30
31 local cfg = {
32 protocol = "tlsv1",
33 options = "all",
34 verify = "none",
35 }
36
37 --------------------------------------------------------------------
38 -- Auxiliar Functions
39 --------------------------------------------------------------------
40
41 -- Insert default HTTPS port.
42 local function default_https_port(u)
43 return url.build(url.parse(u, {port = PORT}))
44 end
45
46 -- Convert an URL to a table according to Luasocket needs.
47 local function urlstring_totable(url, body, result_table)
48 url = {
49 url = default_https_port(url),
50 method = body and "POST" or "GET",
51 sink = ltn12.sink.table(result_table)
52 }
53 if body then
54 url.source = ltn12.source.string(body)
55 url.headers = {
56 ["content-length"] = #body,
57 ["content-type"] = "application/x-www-form-urlencoded",
58 }
59 end
60 return url
61 end
62
63 -- Forward calls to the real connection object.
64 local function reg(conn)
65 local mt = getmetatable(conn.sock).__index
66 for name, method in pairs(mt) do
67 if type(method) == "function" then
68 conn[name] = function (self, ...)
69 return method(self.sock, ...)
70 end
71 end
72 end
73 end
74
75 -- Return a function which performs the SSL/TLS connection.
76 local function tcp(params)
77 params = params or {}
78 -- Default settings
79 for k, v in pairs(cfg) do
80 params[k] = params[k] or v
81 end
82 -- Force client mode
83 params.mode = "client"
84 -- 'create' function for LuaSocket
85 return function ()
86 local conn = {}
87 conn.sock = try(socket.tcp())
88 local st = getmetatable(conn.sock).__index.settimeout
89 function conn:settimeout(...)
90 return st(self.sock, ...)
91 end
92 -- Replace TCP's connection function
93 function conn:connect(host, port)
94 try(self.sock:connect(host, port))
95 self.sock = try(ssl.wrap(self.sock, params))
96 try(self.sock:dohandshake())
97 reg(self, getmetatable(self.sock))
98 return 1
99 end
100 return conn
101 end
102 end
103
104 --------------------------------------------------------------------
105 -- Main Function
106 --------------------------------------------------------------------
107
108 -- Make a HTTP request over secure connection. This function receives
109 -- the same parameters of LuaSocket's HTTP module (except 'proxy' and
110 -- 'redirect') plus LuaSec parameters.
111 --
112 -- @param url mandatory (string or table)
113 -- @param body optional (string)
114 -- @return (string if url == string or 1), code, headers, status
115 --
116 function request(url, body)
117 local result_table = {}
118 local stringrequest = type(url) == "string"
119 if stringrequest then
120 url = urlstring_totable(url, body, result_table)
121 else
122 url.url = default_https_port(url.url)
123 end
124 if http.PROXY or url.proxy then
125 return nil, "proxy not supported"
126 elseif url.redirect then
127 return nil, "redirect not supported"
128 elseif url.create then
129 return nil, "create function not permitted"
130 end
131 -- New 'create' function to establish a secure connection
132 url.create = tcp(url)
133 local res, code, headers, status = http.request(url)
134 if res and stringrequest then
135 return table.concat(result_table), code, headers, status
136 end
137 return res, code, headers, status
138 end

mercurial