Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local function httpRequest(url, verb, headers, data, timeout)
- if type(url) == 'table' then
- verb = url.verb
- headers = url.headers
- data = url.data
- timeout = url.timeout
- url = url.url
- end
- local socket = require('socket')
- ---------------------------------[REQUEST PART]---------------------------------
- -- Protocol host path
- local proto, host, path = url:match('(https?://)([^/]+)(/?.*)')
- -- proto: 'http(s)://', host: 'ru.wikipedia.org', path: '/wiki/HTTP'
- if not proto then return nil, 'Invalid request' end
- path = #path == 0 and '/' or path
- local port = proto:find('https') and 433 or 80
- do -- host -> (ru.wikipedia.org):(8080) <- port
- local _host, _port = host:match('(.-):(%d+)')
- if _host then
- host = _host
- port = tonumber(_port)
- end
- end
- verb = verb or 'GET'
- headers = headers or {}
- --[==[
- HTTP-request is string like this (without "[" and "]", is formatting boundaries):
- [POST /wiki/HTTP HTTP/1.1]
- [Host: ru.wikipedia.org]
- [User-Agent: Mozilla/5.0]
- [Content-Length: 6]
- [(empty string)]
- [qwerty] <- Content-Length, if defined
- Delmitter between lines is [\r\n] (line feed + newline)
- ]==]
- local Request = {} -- request table
- Request[1] = verb .. ' ' .. path .. ' HTTP/1.1'
- Request[2] = 'Host: ' .. host
- Request[3] = 'User-Agent: Mozilla/5.0 (X11; U; Linux i686; ru; rv:1.9b5)' ..
- 'Gecko/2008050509 Firefox/3.0b5'
- for k, v in pairs(headers) do
- Request[#Request + 1] = k .. ': ' .. v
- end
- if data then
- Request[#Request + 1] = 'Content-length: ' .. #data
- Request[#Request + 1] = ''
- Request[#Request + 1] = data
- else
- Request[#Request + 1] = ''
- end
- Request = table.concat(Request, '\r\n')
- -- if proto:find('https') then connect through luasec
- local connection, status = socket.connect(host, port)
- if not connection then return nil, status end
- connection:settimeout((timeout or 60) * 1000)
- local sended_bytes, status = connection:send(Request)
- if sended_bytes ~= #Request then
- return nil, 'Request error: ' .. tostring(status)
- end
- ---------------------------------[RESPONSE PART]--------------------------------
- --[==[
- HTTP-response is string like this (without "[" and "]", is formatting boundaries):
- [HTTP/1.1 200 OK]
- [Content-Length: 10]
- [(empty string)]
- [qwertyuiop] <- Content-Length, if defined
- Delmitter between lines is [\r\n] (line feed + newline)
- ]==]
- local data, status = connection:receive('*l')
- if not data then return nil, status end
- local responseStatus = data:match(' (%d+)') -- HTTP/1.1 (200) OK
- local headers = {}
- data, status = connection:receive('*l')
- while data and #data > 0 do
- local key, value = data:match('(.-): (.*)')
- if key then
- headers[key:lower()] = value
- end
- data, status = connection:receive('*l')
- end
- local responseData
- if headers['content-length'] then
- responseData = connection:receive(tonumber(headers['content-length']))
- end
- return responseData, responseStatus, headers
- end
- print(httpRequest('http://google.ru'))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement