Software /
code /
prosody
Comparison
net/http.lua @ 6054:7a5ddbaf758d
Merge 0.9->0.10
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Wed, 02 Apr 2014 17:41:38 +0100 |
parent | 5950:bd1d1c29a7e7 |
child | 5964:ad04170d6533 |
child | 6382:57d23c26039b |
comparison
equal
deleted
inserted
replaced
6053:2f93a04564b2 | 6054:7a5ddbaf758d |
---|---|
1 -- Prosody IM | 1 -- Prosody IM |
2 -- Copyright (C) 2008-2010 Matthew Wild | 2 -- Copyright (C) 2008-2010 Matthew Wild |
3 -- Copyright (C) 2008-2010 Waqas Hussain | 3 -- Copyright (C) 2008-2010 Waqas Hussain |
4 -- | 4 -- |
5 -- This project is MIT/X11 licensed. Please see the | 5 -- This project is MIT/X11 licensed. Please see the |
6 -- COPYING file in the source package for more information. | 6 -- COPYING file in the source package for more information. |
7 -- | 7 -- |
8 | 8 |
9 local socket = require "socket" | 9 local socket = require "socket" |
35 -- Send the request | 35 -- Send the request |
36 local request_line = { req.method or "GET", " ", req.path, " HTTP/1.1\r\n" }; | 36 local request_line = { req.method or "GET", " ", req.path, " HTTP/1.1\r\n" }; |
37 if req.query then | 37 if req.query then |
38 t_insert(request_line, 4, "?"..req.query); | 38 t_insert(request_line, 4, "?"..req.query); |
39 end | 39 end |
40 | 40 |
41 conn:write(t_concat(request_line)); | 41 conn:write(t_concat(request_line)); |
42 local t = { [2] = ": ", [4] = "\r\n" }; | 42 local t = { [2] = ": ", [4] = "\r\n" }; |
43 for k, v in pairs(req.headers) do | 43 for k, v in pairs(req.headers) do |
44 t[1], t[3] = k, v; | 44 t[1], t[3] = k, v; |
45 conn:write(t_concat(t)); | 45 conn:write(t_concat(t)); |
46 end | 46 end |
47 conn:write("\r\n"); | 47 conn:write("\r\n"); |
48 | 48 |
49 if req.body then | 49 if req.body then |
50 conn:write(req.body); | 50 conn:write(req.body); |
51 end | 51 end |
52 end | 52 end |
53 | 53 |
79 request.callback(reason or "connection-closed", 0, request); | 79 request.callback(reason or "connection-closed", 0, request); |
80 request.callback = nil; | 80 request.callback = nil; |
81 end | 81 end |
82 destroy_request(request); | 82 destroy_request(request); |
83 end | 83 end |
84 | 84 |
85 if not data then | 85 if not data then |
86 error_cb(err); | 86 error_cb(err); |
87 return; | 87 return; |
88 end | 88 end |
89 | 89 |
90 local function success_cb(r) | 90 local function success_cb(r) |
91 if request.callback then | 91 if request.callback then |
92 request.callback(r.body, r.code, r, request); | 92 request.callback(r.body, r.code, r, request); |
93 request.callback = nil; | 93 request.callback = nil; |
94 end | 94 end |
103 end | 103 end |
104 | 104 |
105 local function handleerr(err) log("error", "Traceback[http]: %s", traceback(tostring(err), 2)); end | 105 local function handleerr(err) log("error", "Traceback[http]: %s", traceback(tostring(err), 2)); end |
106 function request(u, ex, callback) | 106 function request(u, ex, callback) |
107 local req = url.parse(u); | 107 local req = url.parse(u); |
108 | 108 |
109 if not (req and req.host) then | 109 if not (req and req.host) then |
110 callback(nil, 0, req); | 110 callback(nil, 0, req); |
111 return nil, "invalid-url"; | 111 return nil, "invalid-url"; |
112 end | 112 end |
113 | 113 |
114 if not req.path then | 114 if not req.path then |
115 req.path = "/"; | 115 req.path = "/"; |
116 end | 116 end |
117 | 117 |
118 local method, headers, body; | 118 local method, headers, body; |
119 | 119 |
120 local host, port = req.host, req.port; | 120 local host, port = req.host, req.port; |
121 local host_header = host; | 121 local host_header = host; |
122 if (port == "80" and req.scheme == "http") | 122 if (port == "80" and req.scheme == "http") |
123 or (port == "443" and req.scheme == "https") then | 123 or (port == "443" and req.scheme == "https") then |
124 port = nil; | 124 port = nil; |
128 | 128 |
129 headers = { | 129 headers = { |
130 ["Host"] = host_header; | 130 ["Host"] = host_header; |
131 ["User-Agent"] = "Prosody XMPP Server"; | 131 ["User-Agent"] = "Prosody XMPP Server"; |
132 }; | 132 }; |
133 | 133 |
134 if req.userinfo then | 134 if req.userinfo then |
135 headers["Authorization"] = "Basic "..b64(req.userinfo); | 135 headers["Authorization"] = "Basic "..b64(req.userinfo); |
136 end | 136 end |
137 | 137 |
138 if ex then | 138 if ex then |
148 for k, v in pairs(ex.headers) do | 148 for k, v in pairs(ex.headers) do |
149 headers[k] = v; | 149 headers[k] = v; |
150 end | 150 end |
151 end | 151 end |
152 end | 152 end |
153 | 153 |
154 -- Attach to request object | 154 -- Attach to request object |
155 req.method, req.headers, req.body = method, headers, body; | 155 req.method, req.headers, req.body = method, headers, body; |
156 | 156 |
157 local using_https = req.scheme == "https"; | 157 local using_https = req.scheme == "https"; |
158 if using_https and not ssl_available then | 158 if using_https and not ssl_available then |
159 error("SSL not available, unable to contact https URL"); | 159 error("SSL not available, unable to contact https URL"); |
160 end | 160 end |
161 local port_number = port and tonumber(port) or (using_https and 443 or 80); | 161 local port_number = port and tonumber(port) or (using_https and 443 or 80); |
162 | 162 |
163 -- Connect the socket, and wrap it with net.server | 163 -- Connect the socket, and wrap it with net.server |
164 local conn = socket.tcp(); | 164 local conn = socket.tcp(); |
165 conn:settimeout(10); | 165 conn:settimeout(10); |
166 local ok, err = conn:connect(host, port_number); | 166 local ok, err = conn:connect(host, port_number); |
167 if not ok and err ~= "timeout" then | 167 if not ok and err ~= "timeout" then |
168 callback(nil, 0, req); | 168 callback(nil, 0, req); |
169 return nil, err; | 169 return nil, err; |
170 end | 170 end |
171 | 171 |
172 local sslctx = false; | 172 local sslctx = false; |
173 if using_https then | 173 if using_https then |
174 sslctx = ex and ex.sslctx or { mode = "client", protocol = "sslv23", options = { "no_sslv2" } }; | 174 sslctx = ex and ex.sslctx or { mode = "client", protocol = "sslv23", options = { "no_sslv2" } }; |
175 end | 175 end |
176 | 176 |
177 req.handler, req.conn = assert(server.wrapclient(conn, host, port_number, listener, "*a", sslctx)); | 177 req.handler, req.conn = assert(server.wrapclient(conn, host, port_number, listener, "*a", sslctx)); |
178 req.write = function (...) return req.handler:write(...); end | 178 req.write = function (...) return req.handler:write(...); end |
179 | 179 |
180 req.callback = function (content, code, request, response) log("debug", "Calling callback, status %s", code or "---"); return select(2, xpcall(function () return callback(content, code, request, response) end, handleerr)); end | 180 req.callback = function (content, code, request, response) log("debug", "Calling callback, status %s", code or "---"); return select(2, xpcall(function () return callback(content, code, request, response) end, handleerr)); end |
181 req.reader = request_reader; | 181 req.reader = request_reader; |
182 req.state = "status"; | 182 req.state = "status"; |
183 | 183 |
184 requests[req.handler] = req; | 184 requests[req.handler] = req; |