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;