[Test]HTTPS support for Windows (NO libraries required)

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
bio1712
Citizen
Posts: 72
Joined: Wed Aug 19, 2015 4:13 pm
Location: Italy

[Test]HTTPS support for Windows (NO libraries required)

Post by bio1712 »

Hi, I've created a .love that makes https requests without additional libraries.
Basically, it uses a .js file and uses the MSXML2.ServerXMLHTTP class that is built-in in Windows.
It was made in 30 minutes, therefore it can be definitely improved.

Image

If you want to use this in your project, just add the file https.lua.

However, I would not recommend this, because you can't do 2 requests simultaneously and because it works only in Windows.
Any suggestion is appreciated.

P.S: I posted this thread in "General" because this is not a proper library.
https.love
(1.99 KiB) Downloaded 447 times
Attachments
https.lua
(2.6 KiB) Downloaded 472 times
Last edited by bio1712 on Wed Sep 26, 2018 7:28 am, edited 1 time in total.
bobbyjones
Party member
Posts: 730
Joined: Sat Apr 26, 2014 7:46 pm

Re: [Test]HTTPS support for Windows (NO libraries required)

Post by bobbyjones »

That is an interesting way to do an https request without binaries.

Edit: using the same method I'm sure it's also possible to do https on Linux using whatever Unix command for retrieving a web page. I think it's wget. And I'm sure Mac has it's own command for retrieving a web page as well.
bio1712
Citizen
Posts: 72
Joined: Wed Aug 19, 2015 4:13 pm
Location: Italy

Re: [Test]HTTPS support for Windows (NO libraries required)

Post by bio1712 »

If we can improve this and make this more reliable it will be awesome :ultrahappy:
Edit: I have added an example .love
User avatar
HDPLocust
Citizen
Posts: 65
Joined: Thu Feb 19, 2015 10:56 pm
Location: Swamp
Contact:

Re: [Test]HTTPS support for Windows (NO libraries required)

Post by HDPLocust »

Also we can just use luasec.
Science and violence
User avatar
zorg
Party member
Posts: 3436
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: [Test]HTTPS support for Windows (NO libraries required)

Post by zorg »

HDPLocust wrote: Tue Nov 06, 2018 9:40 am Also we can just use luasec.
So... what release of luasec does not require other libraries? and more importantly, non-lua ones?
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: [Test]HTTPS support for Windows (NO libraries required)

Post by ivan »

This is a very fragile and hacky script but I like it.
I could see myself using something like this as a crude scraper tool.
Here I have cleaned up the code a little bit:

Code: Select all

local https = {}

https.timeout = 0

https.js = [[
var script = %script%;
var url = %url%;
var method = %method%;
var data = %data%;
var username = %username%;
var password = %password%;
var timeout = %timeout%;
var headers = %headers%;

var status = 0;

try
{
  var xHttp = new ActiveXObject("MSXML2.ServerXMLHTTP");
  if (timeout)
    xHttp.setTimeouts(timeout, timeout, timeout, timeout);
  xHttp.open(method, url, false, username, password);
  for (var key in headers)
    xHttp.setRequestHeader(key, headers[key]);
  xHttp.send(data);

  var fsT = new ActiveXObject("ADODB.Stream");
  fsT.type = 2; 
  fsT.charset = headers['charset']; 
  fsT.open(); 
  fsT.writeText(xHttp.responseText);
  fsT.saveToFile(script + "0", 2);
  
  var response = xHttp.getAllResponseHeaders();
  var FSO = new ActiveXObject("Scripting.FileSystemObject");
  var file = FSO.CreateTextFile(script + "2", true);
  file.Write(response + "\n");
  file.Close();

  status = xHttp.status;
}
catch (err)
{
  status = 400;
}

var FSO = new ActiveXObject("Scripting.FileSystemObject");
var file = FSO.CreateTextFile(script + "1", true);
file.Write(status + "\n");
file.Close();
]]

function https.request(url, data)
  local p = {}
  if type(url) == "table" then
    for k, v in pairs(url) do
      p[k] = v
    end
  else
    p.url = url
    p.data = data
  end
  p.url = p.url or ""
  p.data = p.data or ""
  p.method = p.method or "GET"
  p.timeout = https.timeout
  local h = p.headers or {}
  h['charset'] = h['charset'] or "us-ascii"
  h['conent-type'] = h['content-type'] or "application/x-www-form-urlencoded"
  h['content-length'] = string.len(p.data)
  p.headers = h

  local script = os.tmpname()
  p.script = script
  local js = https.js
  for k, v in pairs(p) do
    if type(v) == "table" then
      local t = {}
      for j, w in pairs(v) do
        if type(w) == "string" then
          w = string.format("%q", w)
        else
          w = tostring(w)
        end
        local row = string.format("%q:%s", j, w)
        table.insert(t, row)
      end
      v = "{"..table.concat(t, ",\n").."}"
    elseif type(v) == "string" then
      v = string.format("%q", v)
    else
      v = tostring(v)
    end
    js = js:gsub("%%"..k.."%%", v)
  end
  js = js:gsub("%%(.-)%%", "null")

  local file = io.open(script..".js", "w")
  if not file then
    return
  end
  file:write(js)
  file:close()
  --os.execute(script..".js")
  
  local console = io.popen(script..".js", "r")
  console:read("*all")
  console:close()
  
  local response = {}
  for i = 0, 2 do
    local out = io.open(script..i, "r")
    if out then
      response[i + 1] = out:read("*a")
      out:close()
    end
    os.remove(script..i)
  end
  os.remove(script..".js")
  
  response[2] = tonumber(response[2])
  
  return unpack(response)
end

return https
+ Removed the Love2D dependency so it can work using pure Lua.
+ Added temporary filenames so this could be used in parallel.
+ Certificate validation is ON by default - seems like xHttp.setOption(2, 13056) is probably insecure
+ Username and Pass can be supplied optionally using the table syntax: https.request{url='https://example.com',user='me',pass='secret'}
+ Better way to pass data from Lua to JavaScript (the reverse is not as elegant)
+ Works similarly to LuaSocket's http.request (returning the headers and body)
- The JavaScript part will only work with Windows.
- The console windows will pop up when using https.request.
- All requests are blocking

Usage (for experimentation and fun):

Code: Select all

https = require("https")

function love.load()
  body, status, headers = https.request("https://love2d.org/")
  love.system.setClipboardText(body)
end

function love.draw()
  love.graphics.print(tostring(status), 0, 0)
  love.graphics.print(tostring(body), 0, 20)
end
davidkonsumer
Prole
Posts: 6
Joined: Thu Dec 28, 2017 12:34 am

Re: [Test]HTTPS support for Windows (NO libraries required)

Post by davidkonsumer »

Here is a quick hack that adds support for mac/linux via curl (cli tool.) It could use detection of wget/curl as well as better parsing of options and return value so they both match, but it has the rough idea.

Code: Select all

local https = {}

-- hacky OS detection
local ostype = package.config:sub(1,1) == "\\" and "windows" or "posix"

https.timeout = 0

local function handleArgs(url, data)
  local p = {}
  if type(url) == "table" then
    for k, v in pairs(url) do
      p[k] = v
    end
  else
    p.url = url
    p.data = data
  end
  p.url = p.url or ""
  p.data = p.data or ""
  p.method = p.method or "GET"
  p.timeout = https.timeout
  local h = p.headers or {}
  h['charset'] = h['charset'] or "us-ascii"
  h['conent-type'] = h['content-type'] or "application/x-www-form-urlencoded"
  h['content-length'] = string.len(p.data)
  p.headers = h
  return p
end

if ostype == "windows" then
  https.js = [[
  var script = %script%;
  var url = %url%;
  var method = %method%;
  var data = %data%;
  var username = %username%;
  var password = %password%;
  var timeout = %timeout%;
  var headers = %headers%;

  var status = 0;

  try
  {
    var xHttp = new ActiveXObject("MSXML2.ServerXMLHTTP");
    if (timeout)
      xHttp.setTimeouts(timeout, timeout, timeout, timeout);
    xHttp.open(method, url, false, username, password);
    for (var key in headers)
      xHttp.setRequestHeader(key, headers[key]);
    xHttp.send(data);

    var fsT = new ActiveXObject("ADODB.Stream");
    fsT.type = 2; 
    fsT.charset = headers['charset']; 
    fsT.open(); 
    fsT.writeText(xHttp.responseText);
    fsT.saveToFile(script + "0", 2);
    
    var response = xHttp.getAllResponseHeaders();
    var FSO = new ActiveXObject("Scripting.FileSystemObject");
    var file = FSO.CreateTextFile(script + "2", true);
    file.Write(response + "\n");
    file.Close();

    status = xHttp.status;
  }
  catch (err)
  {
    status = 400;
  }

  var FSO = new ActiveXObject("Scripting.FileSystemObject");
  var file = FSO.CreateTextFile(script + "1", true);
  file.Write(status + "\n");
  file.Close();
  ]]

  function https.request(url, data)
    local p = handleArgs(url, data)

    local script = os.tmpname()
    p.script = script
    local js = https.js
    for k, v in pairs(p) do
      if type(v) == "table" then
        local t = {}
        for j, w in pairs(v) do
          if type(w) == "string" then
            w = string.format("%q", w)
          else
            w = tostring(w)
          end
          local row = string.format("%q:%s", j, w)
          table.insert(t, row)
        end
        v = "{"..table.concat(t, ",\n").."}"
      elseif type(v) == "string" then
        v = string.format("%q", v)
      else
        v = tostring(v)
      end
      js = js:gsub("%%"..k.."%%", v)
    end
    js = js:gsub("%%(.-)%%", "null")

    local file = io.open(script..".js", "w")
    if not file then
      return
    end
    file:write(js)
    file:close()
    local console = io.popen(script..".js", "r")
    console:read("*all")
    console:close()
    
    local response = {}
    for i = 0, 2 do
      local out = io.open(script..i, "r")
      if out then
        response[i + 1] = out:read("*a")
        out:close()
      end
      os.remove(script..i)
    end
    os.remove(script..".js")
    
    response[2] = tonumber(response[2])
    
    return unpack(response)
  end
else
  function https.request(url, data)
    local p = handleArgs(url, data)
    -- TODO: did not dig into options of other thing, this just uses URL
    -- TODO: detect curl/wget
    local console = io.popen("curl -s '"..p.url.."'", "r")
    -- local console = io.popen("wget -qO- '"..p.url.."'", "r")
    local o = console:read("*all")
    console:close()
    return o
  end
end

return https
alejandroalzate
Citizen
Posts: 67
Joined: Sat May 08, 2021 9:45 pm

Re: [Test]HTTPS support for Windows (NO libraries required)

Post by alejandroalzate »

bio1712 wrote: Tue Sep 25, 2018 8:58 pm Hi, I've created a .love that makes https requests without additional libraries.
Basically, it uses a .js file and uses the MSXML2.ServerXMLHTTP class that is built-in in Windows.
It was made in 30 minutes, therefore it can be definitely improved.

Image

If you want to use this in your project, just add the file https.lua.

However, I would not recommend this, because you can't do 2 requests simultaneously and because it works only in Windows.
Any suggestion is appreciated.

P.S: I posted this thread in "General" because this is not a proper library.

https.love
but what version uses? in 11.4 throws an error:
"C:\Users\Alejandro" no se reconoce como un comando interno o externo,
programa o archivo por lotes ejecutable.
o)
nf
and i guess is just an folder mess of windows lol cuz the user folder has spaces (my user)

Code: Select all

target = boardIndex.getWhosPeekingThisLine()
target:setObey(true)
User avatar
togFox
Party member
Posts: 770
Joined: Sat Jan 30, 2021 9:46 am
Location: Brisbane, Oztralia

Re: [Test]HTTPS support for Windows (NO libraries required)

Post by togFox »

You know you bumped a 4 year old thread? It won't be 11.4.
Current project:
https://togfox.itch.io/backyard-gridiron-manager
American football manager/sim game - build and manage a roster and win season after season
Post Reply

Who is online

Users browsing this forum: No registered users and 60 guests