--:Minify:-- local http = {} local syscall = syscall local function parseUrl(url) local proto, host, path = url:match( "^(https?://)([^/]+)(/.*)$" ) if not proto then proto, host = url:match( "^(https?://)([^/]+)$" ) path = "/" end if not proto then return nil, "EINVAL" end return host, path end local function buildRequest(req) local host, path = parseUrl(req.url) if not host then return nil, path end local method = req.method or "GET" local body = req.body or "" local headers = table.deepcopy( req.headers or {} ) headers.Host = headers.Host or host headers.Connection = headers.Connection or "close" if body ~= "" then headers["Content-Length"] = tostring(#body) end local out = { method .. " " .. path .. " HTTP/1.1" } for k, v in pairs(headers) do out[#out + 1] = tostring(k) .. ": " .. tostring(v) end out[#out + 1] = "" out[#out + 1] = body return table.concat(out, "\r\n") end local function parseResponse(response) local headerBlock, body = response:match("^(.-)\r\n\r\n(.*)$") if not headerBlock then return nil, "invalid HTTP response" end local headers = {} -- Parse status line local statusLine, rest = headerBlock:match("^(.-)\r\n(.*)$") if not statusLine then statusLine = headerBlock rest = "" end local version, code, message = statusLine:match("^(HTTP/%d+%.%d+)%s+(%d+)%s+(.*)$") -- Parse headers for line in (rest .. "\r\n"):gmatch("(.-)\r\n") do local key, value = line:match("^([^:]+):%s*(.*)$") if key then headers[key:lower()] = value end end return { code=tonumber(code), message=message, headers=headers, body=body } end function http.request(req) local raw, err = buildRequest(req) if not raw then return nil, err end local fd = syscall.socket() if not fd then return nil, "ESOCKET" end local host, path = parseUrl(req.url) if not host then syscall.close(fd) return nil, path end local proto = req.url:match("^(https?://)") local base = proto .. host local ok, err = syscall.connect(fd, base) if not ok then syscall.close(fd) return nil, err end local ok2, err2 = syscall.write(fd, raw) if not ok2 then syscall.close(fd) return nil, err2 end local out = {} while true do local chunk = syscall.read(fd, 4096) if chunk == "" then break end out[#out+1] = chunk end syscall.close(fd) return parseResponse(table.concat(out)) end function http.get(url, headers) return http.request({ url = url, method = "GET", headers = headers }) end function http.post(url, body, headers) return http.request({ url = url, method = "POST", body = body, headers = headers }) end return http