----------------------------------------------------------------------------- -- HTTP/1.1 client support for the Lua language. -- LuaSocket toolkit. -- Author: Diego Nehab ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- -- Declare module and import dependencies ------------------------------------------------------------------------------- socket.http = {} local _M = socket.http ----------------------------------------------------------------------------- -- Program constants ----------------------------------------------------------------------------- -- connection timeout in seconds _M.TIMEOUT = 60 -- user agent field sent in request _M.USERAGENT = socket._VERSION -- supported schemes and their particulars local SCHEMES = { http = { port = 80 , create = function(t) return socket.tcp end } , https = { port = 443 , create = function(t) return https.tcp(t) end }} -- default scheme and port for document retrieval local SCHEME = 'http' local PORT = SCHEMES[SCHEME].port ----------------------------------------------------------------------------- -- Reads MIME headers from a connection, unfolding where needed ----------------------------------------------------------------------------- local function receiveheaders(sock, headers) local line, name, value, err headers = headers or {} -- get first line line, err = sock:receive() if err then return nil, err end -- headers go until a blank line is found while line ~= "" do -- get field-name and value name, value = socket.skip(2, string.find(line, "^(.-):%s*(.*)")) if not (name and value) then return nil, "malformed reponse headers" end name = string.lower(name) -- get next line (value might be folded) line, err = sock:receive() if err then return nil, err end -- unfold any folded values while string.find(line, "^%s") do value = value .. line line = sock:receive() if err then return nil, err end end -- save pair in table if headers[name] then headers[name] = headers[name] .. ", " .. value else headers[name] = value end end return headers end ----------------------------------------------------------------------------- -- Extra sources and sinks ----------------------------------------------------------------------------- socket.sourcet["http-chunked"] = function(sock, headers) return setmetatable({ getfd = function() return sock:getfd() end, dirty = function() return sock:dirty() end }, { __call = function() -- get chunk size, skip extention local line, err = sock:receive() if err then return nil, err end local size = tonumber(string.gsub(line, ";.*", ""), 16) if not size then return nil, "invalid chunk size" end -- was it the last chunk? if size > 0 then -- if not, get chunk and skip terminating CRLF local chunk, err, part = sock:receive(size) if chunk then sock:receive() end return chunk, err else -- if it was, read trailers into headers table headers, err = receiveheaders(sock, headers) if not headers then return nil, err end end end }) end socket.sinkt["http-chunked"] = function(sock) return setmetatable({ getfd = function() return sock:getfd() end, dirty = function() return sock:dirty() end }, { __call = function(self, chunk, err) if not chunk then return sock:send("0\r\n\r\n") end local size = string.format("%X\r\n", string.len(chunk)) return sock:send(size .. chunk .. "\r\n") end }) end ----------------------------------------------------------------------------- -- Low level HTTP API
#!/usr/bin/python
"""
You can use this tool to find out values of keypresses
"""

from curses import *

sep = '; '

@wrapper
def main(w):
	while True:
		w.addstr(str(w.getch()) + sep)
d code < 200 then return nil end return 1 end -- forward declarations local trequest, tredirect --[[local]] function tredirect(reqt, location) -- the RFC says the redirect URL has to be absolute, but some -- servers do not respect that local newurl = url.absolute(reqt.url, location) -- if switching schemes, reset port and create function if url.parse(newurl).scheme ~= reqt.scheme then reqt.port = nil reqt.create = nil end -- make new request local result, code, headers, status = trequest { url = newurl, source = reqt.source, sink = reqt.sink, headers = reqt.headers, proxy = reqt.proxy, maxredirects = reqt.maxredirects, nredirects = (reqt.nredirects or 0) + 1, create = reqt.create } -- pass location header back as a hint we redirected headers = headers or {} headers.location = headers.location or location return result, code, headers, status end --[[local]] function trequest(reqt) -- we loop until we get what we want, or -- until we are sure there is no way to get it local nreqt = adjustrequest(reqt) local h = _M.open(nreqt.host, nreqt.port, nreqt.create) -- send request line and headers h:sendrequestline(nreqt.method, nreqt.uri) h:sendheaders(nreqt.headers) -- if there is a body, send it if nreqt.source then h:sendbody(nreqt.headers, nreqt.source, nreqt.step) end local code, status = h:receivestatusline() -- if it is an HTTP/0.9 server, simply get the body and we are done if not code then h:receive09body(status, nreqt.sink, nreqt.step) return 1, 200 elseif code == 408 then return 1, code end local headers -- ignore any 100-continue messages while code == 100 do headers = h:receiveheaders() code, status = h:receivestatusline() end headers = h:receiveheaders() -- at this point we should have a honest reply from the server -- we can't redirect if we already used the source, so we report the error if shouldredirect(nreqt, code, headers) and not nreqt.source then h:close() return tredirect(reqt, headers.location) end -- here we are finally done if shouldreceivebody(nreqt, code) then h:receivebody(headers, nreqt.sink, nreqt.step) end h:close() return 1, code, headers, status end -- turns an url and a body into a generic request local function genericform(u, b) local t = {} local reqt = { url = u, sink = ltn12.sink.table(t), target = t } if b then reqt.source = ltn12.source.string(b) reqt.headers = { ["content-length"] = string.len(b), ["content-type"] = "application/x-www-form-urlencoded" } reqt.method = "POST" end return reqt end _M.genericform = genericform local function srequest(u, b) local reqt = genericform(u, b) local _, code, headers, status = trequest(reqt) return table.concat(reqt.target), code, headers, status end _M.request = socket.protect(function(reqt, body) if type(reqt) == "string" then return srequest(reqt, body) else return trequest(reqt) end end) _M.schemes = SCHEMES return _M