net/httpserver.lua
changeset 2877 1edeb8fe7d14
parent 2775 72b31799b0cb
parent 2837 a17e73ab5f4c
child 2923 b7049746bd29
equal deleted inserted replaced
2813:46dfcc33ea9e 2877:1edeb8fe7d14
    34 end
    34 end
    35 
    35 
    36 local function send_response(request, response)
    36 local function send_response(request, response)
    37 	-- Write status line
    37 	-- Write status line
    38 	local resp;
    38 	local resp;
    39 	if response.body then
    39 	if response.body or response.headers then
    40 		local body = tostring(response.body);
    40 		local body = response.body and tostring(response.body);
    41 		log("debug", "Sending response to %s", request.id);
    41 		log("debug", "Sending response to %s", request.id);
    42 		resp = { "HTTP/1.0 ", response.status or "200 OK", "\r\n"};
    42 		resp = { "HTTP/1.0 ", response.status or "200 OK", "\r\n"};
    43 		local h = response.headers;
    43 		local h = response.headers;
    44 		if h then
    44 		if h then
    45 			for k, v in pairs(h) do
    45 			for k, v in pairs(h) do
    47 				t_insert(resp, ": ");
    47 				t_insert(resp, ": ");
    48 				t_insert(resp, v);
    48 				t_insert(resp, v);
    49 				t_insert(resp, "\r\n");
    49 				t_insert(resp, "\r\n");
    50 			end
    50 			end
    51 		end
    51 		end
    52 		if not (h and h["Content-Length"]) then
    52 		if body and not (h and h["Content-Length"]) then
    53 			t_insert(resp, "Content-Length: ");
    53 			t_insert(resp, "Content-Length: ");
    54 			t_insert(resp, #body);
    54 			t_insert(resp, #body);
    55 			t_insert(resp, "\r\n");
    55 			t_insert(resp, "\r\n");
    56 		end
    56 		end
    57 		t_insert(resp, "\r\n");
    57 		t_insert(resp, "\r\n");
    58 		
    58 		
    59 		if request.method ~= "HEAD" then
    59 		if body and request.method ~= "HEAD" then
    60 			t_insert(resp, body);
    60 			t_insert(resp, body);
    61 		end
    61 		end
    62 	else
    62 	else
    63 		-- Response we have is just a string (the body)
    63 		-- Response we have is just a string (the body)
    64 		log("debug", "Sending 200 response to %s", request.id or "<none>");
    64 		log("debug", "Sending 200 response to %s", request.id or "<none>");
   145 			end
   145 			end
   146 		end
   146 		end
   147 	elseif request.state == "headers" then
   147 	elseif request.state == "headers" then
   148 		log("debug", "Reading headers...")
   148 		log("debug", "Reading headers...")
   149 		local pos = startpos;
   149 		local pos = startpos;
   150 		local headers = request.headers or {};
   150 		local headers, headers_complete = request.headers;
       
   151 		if not headers then
       
   152 			headers = {};
       
   153 			request.headers = headers;
       
   154 		end
       
   155 		
   151 		for line in data:gmatch("(.-)\r\n") do
   156 		for line in data:gmatch("(.-)\r\n") do
   152 			startpos = (startpos or 1) + #line + 2;
   157 			startpos = (startpos or 1) + #line + 2;
   153 			local k, v = line:match("(%S+): (.+)");
   158 			local k, v = line:match("(%S+): (.+)");
   154 			if k and v then
   159 			if k and v then
   155 				headers[k:lower()] = v;
   160 				headers[k:lower()] = v;
   156 --				log("debug", "Header: "..k:lower().." = "..v);
   161 				--log("debug", "Header: '"..k:lower().."' = '"..v.."'");
   157 			elseif #line == 0 then
   162 			elseif #line == 0 then
   158 				request.headers = headers;
   163 				headers_complete = true;
   159 				break;
   164 				break;
   160 			else
   165 			else
   161 				log("debug", "Unhandled header line: "..line);
   166 				log("debug", "Unhandled header line: "..line);
   162 			end
   167 			end
   163 		end
   168 		end
   164 		
   169 		
   165 		if not expectbody(request) then 
   170 		if not headers_complete then return; end
       
   171 		
       
   172 		if not expectbody(request) then
   166 			call_callback(request);
   173 			call_callback(request);
   167 			return;
   174 			return;
   168 		end
   175 		end
   169 		
   176 		
   170 		-- Reached the end of the headers
   177 		-- Reached the end of the headers
   174 		end
   181 		end
   175 	elseif request.state == "request" then
   182 	elseif request.state == "request" then
   176 		log("debug", "Reading request line...")
   183 		log("debug", "Reading request line...")
   177 		local method, path, http, linelen = data:match("^(%S+) (%S+) HTTP/(%S+)\r\n()", startpos);
   184 		local method, path, http, linelen = data:match("^(%S+) (%S+) HTTP/(%S+)\r\n()", startpos);
   178 		if not method then
   185 		if not method then
   179 			return call_callback(request, "invalid-status-line");
   186 			log("warn", "Invalid HTTP status line, telling callback then closing");
       
   187 			local ret = call_callback(request, "invalid-status-line");
       
   188 			request:destroy();
       
   189 			return ret;
   180 		end
   190 		end
   181 		
   191 		
   182 		request.method, request.path, request.httpversion = method, path, http;
   192 		request.method, request.path, request.httpversion = method, path, http;
   183 		
   193 		
   184 		request.url = url_parse(request.path);
   194 		request.url = url_parse(request.path);