Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local buffer = require("buffer")
- local component = require("component")
- local event = require("event")
- local internet = {}
- local ltn12 = require("ltn12")
- local javaserialize = require("javaserialization").javaserialize
- -------------------------------------------------------------------------------
- function internet.request2(url, postdata, headers)
- checkArg(1, url, "string")
- checkArg(2, data, "string", "table", "nil")
- checkArg(3, headers, "table", "nil")
- if not component.isAvailable("internet") then
- error("no primary internet card found", 2)
- end
- local inet = component.internet
- -- TODO: Check for too many connections
- url = string_trim(url)
- -- TODO: Use url.parse
- local protocol = url:match("(.-):")
- if protocol == "http" then
- elseif protocol == "https" then
- if not httpsok then
- return nil, "unsupported protocol"
- end
- elseif protocol == "ftp" or protocol == "mailto" then
- return nil, "unsupported protocol"
- else
- return nil, "invalid address"
- end
- if type(postData) ~= "string" then
- postData = nil
- end
- local cleanheaders = {}
- if type(headers) == "table" then
- for k, v in pairs(headers) do
- if type(k) == "string" then
- cleanheaders[k:lower()] = javaserialize(v)
- end
- end
- end
- local body = {}
- local reqt = {
- method = (postData and "POST" or "GET"),
- url = url,
- headers = cleanheaders,
- sink = ltn12.sink.table(body)
- }
- if postData then
- reqt.source = ltn12.source.string(postData)
- reqt.headers["content-length"] = #postData
- reqt.headers["content-type"] = "application/x-www-form-urlencoded"
- end
- -- TODO: This works ... but is slow.
- -- TODO: Infact so slow, it can trigger the machine's sethook, so we have to work around that.
- local starttime = gettime()
- local page, err, headers, status = inet.request(reqt)
- local offset = gettime() - starttime
- timeoffset = timeoffset + offset
- cprint("(request.hack) Going back in time: " .. offset .. "s")
- if not page then
- cprint("(request) request failed",err)
- else
- page = table.concat(body)
- end
- -- Experimental fix for headers
- if headers ~= nil then
- local oldheaders = headers
- headers = {}
- for k,v in pairs(oldheaders) do
- local name = k:gsub("^.",string.upper):gsub("%-.",string.upper)
- if type(v) == "table" then
- v.n = #v
- headers[name] = v
- else
- headers[name] = {v,n=1}
- end
- end
- end
- local procotol, code, message
- local bad = false
- if status then
- protocol, code, message = status:match("(.-) (.-) (.*)")
- code = tonumber(code)
- if code >= 400 then
- bad = true
- if code == 404 or code == 410 then
- page = url
- else
- page = "Server returned HTTP response code: " .. code .. " for URL: " .. url
- end
- end
- end
- local closed = false
- local fakesocket = {
- read = function(n)
- cprint("(socket) read",n)
- if n == nil then n = math.huge end
- checkArg(1,n,"number")
- if closed then
- return nil, "connection lost"
- elseif headers == nil then
- return nil, "Connection refused"
- elseif page == "" then
- return nil
- elseif bad then
- return nil, page
- else
- n = math.min(math.max(n, 0), settings.maxReadBuffer)
- local data
- if n == math.huge then
- data = page
- page = ""
- else
- data = page:sub(1,n)
- page = page:sub(n+1)
- end
- return data
- end
- end,
- response = function()
- cprint("(socket) response")
- if headers == nil or bad then
- return nil
- end
- return code, message, headers
- end,
- close = function()
- cprint("(request) close")
- closed = true
- page = nil
- end,
- finishConnect = function()
- cprint("(socket) finishConnect")
- if closed then
- return nil, "connection lost"
- elseif headers == nil then
- return nil, "Connection refused"
- elseif bad then
- return nil, page
- end
- return true
- end
- }
- return fakesocket
- end
- -------------------------------------------------------------------------------
- return internet2
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement