This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

HTTP PUT image to 2N intercom
#8
Thank you so much!
Finally got it working with digest, it could problably be done prettier, but this works for me  Big Grin

Code:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
fire = grp.getvalue("32/1/1") if fire == true then -- Uploads image to intercom     log("FIREALARM ACTIVE")     local skthttp = require("socket.http")     local skturl = require("socket.url")     local ltn12 = require("ltn12")     local md5sum = require("encdec").md5     boundary = os.date("%d%m%Y%H%M%S")     filedata = io.readfile("/www/scada/resources/img/STOP_DNE_214x320.jpeg") -- image data as a binary string     body =         table.concat(         {             "--" .. boundary,             'Content-Disposition: form-data; name="blob-image"; filename="picture.jpeg"',             "Content-Type: image/jpeg",             "",             filedata,             "--" .. boundary .. "--",             ""         },         "\r\n"     )     resp = {}     local hash = function(...)         return md5sum(table.concat({...}, ":"))     end     local parse_header = function(header)         local result = {}         for key, value in (header .. ","):gmatch("(%w+)=(.-),") do             if value:sub(1, 1) == '"' then -- strip quotes                 result[key:lower()] = value:sub(2, -2)             else                 result[key:lower()] = value             end         end         return result     end     local make_digest_header = function(headers)         local digest = {}         for _, header in ipairs(headers) do             if not header.unquote then                 header[2] = '"' .. header[2] .. '"'             end             digest[#digest + 1] = header[1] .. "=" .. header[2]         end         return "Digest " .. table.concat(digest, ", ")     end     local _request = function(req)         if not req.url then             return nil, "missing url"         end         local url = skturl.parse(req.url)         local user, password = url.user, url.password         local sink = req.sink         if not user or not password then             return nil, "missing credentials in url"         end         url.user, url.password, url.authority, url.userinfo = nil, nil, nil, nil         req.url = skturl.build(url)         local source         if req.source then             local chunks = {}             local capture = function(chunk)                 if chunk then                     chunks[#chunks + 1] = chunk                 end                 return chunk             end             local chunk_id = 0             source = function()                 chunk_id = chunk_id + 1                 return chunks[chunk_id]             end             req.source = ltn12.source.chain(req.source, capture)         end         req.sink = nil         local body, code, hdrs = skthttp.request(req)         if code == 401 and hdrs["www-authenticate"] then             local ht = parse_header(hdrs["www-authenticate"])             if not ht.realm or not ht.nonce then                 return nil, "missing realm/nonce from response"             end             local qop = ht.qop             if qop and qop ~= "auth" then                 return nil, "unsupported qop " .. tostring(qop)             end             if ht.algorithm and ht.algorithm:lower() ~= "md5" then                 return nil, "unsupported algo " .. tostring(ht.algorithm)             end             local nc = "00000001"             local cnonce = string.format("%08x", os.time())             local uri = skturl.build({path = url.path, query = url.query})             local method = req.method or "GET"             local response = hash(hash(user, ht.realm, password), ht.nonce, nc, cnonce, "auth", hash(method, uri))             req.headers = req.headers or {}             local auth = {                 {"username", user},                 {"realm", ht.realm},                 {"nonce", ht.nonce},                 {"uri", uri},                 {"cnonce", cnonce},                 {"nc", nc, unquote = true},                 {"qop", "auth"},                 {"algorithm", "MD5"},                 {"response", response}             }             if ht.opaque then                 table.insert(auth, {"opaque", ht.opaque})             end             req.headers.authorization = make_digest_header(auth)             if not req.headers.cookie and hdrs["set-cookie"] then                 -- not really correct but enough for httpbin                 local cookie = (hdrs["set-cookie"] .. ";"):match("(.-=.-)[;,]")                 if cookie then                     req.headers.cookie = "$Version: 0; " .. cookie .. ";"                 end             end             if req.source then                 req.source = source             end             req.sink = sink             body, code, hdrs = skthttp.request(req)         end         return body, code, hdrs     end     local request = function(url)         local t = type(url)         if t == "table" then             return _request(table.clone(url))         elseif t == "string" then             local req = {}             local _, code, headers = _request({url = url, sink = ltn12.sink.table(req)})             return table.concat(req), code, headers         end     end     res, code, response_headers, status =         request(         {             url = "https://test:test@10.0.0.230/api/display/image?display=ext1",             sink = ltn12.sink.table(resp),             method = "PUT",             source = ltn12.source.string(body),             headers = {                 ["content-length"] = #body,                 ["content-type"] = "multipart/form-data; boundary=" .. boundary             }         }     )     log(res, code, table.concat(resp)) elseif fire == false then -- Removes image from intercom     log("Firealarm reset")     local skthttp = require("socket.http")     local skturl = require("socket.url")     local ltn12 = require("ltn12")     local md5sum = require("encdec").md5     local hash = function(...)         return md5sum(table.concat({...}, ":"))     end     local parse_header = function(header)         local result = {}         for key, value in (header .. ","):gmatch("(%w+)=(.-),") do             if value:sub(1, 1) == '"' then -- strip quotes                 result[key:lower()] = value:sub(2, -2)             else                 result[key:lower()] = value             end         end         return result     end     local make_digest_header = function(headers)         local digest = {}         for _, header in ipairs(headers) do             if not header.unquote then                 header[2] = '"' .. header[2] .. '"'             end             digest[#digest + 1] = header[1] .. "=" .. header[2]         end         return "Digest " .. table.concat(digest, ", ")     end     local _request = function(req)         if not req.url then             return nil, "missing url"         end         local url = skturl.parse(req.url)         local user, password = url.user, url.password         local sink = req.sink         if not user or not password then             return nil, "missing credentials in url"         end         url.user, url.password, url.authority, url.userinfo = nil, nil, nil, nil         req.url = skturl.build(url)         local source         if req.source then             local chunks = {}             local capture = function(chunk)                 if chunk then                     chunks[#chunks + 1] = chunk                 end                 return chunk             end             local chunk_id = 0             source = function()                 chunk_id = chunk_id + 1                 return chunks[chunk_id]             end             req.source = ltn12.source.chain(req.source, capture)         end         req.sink = nil         local body, code, hdrs = skthttp.request(req)         if code == 401 and hdrs["www-authenticate"] then             local ht = parse_header(hdrs["www-authenticate"])             if not ht.realm or not ht.nonce then                 return nil, "missing realm/nonce from response"             end             local qop = ht.qop             if qop and qop ~= "auth" then                 return nil, "unsupported qop " .. tostring(qop)             end             if ht.algorithm and ht.algorithm:lower() ~= "md5" then                 return nil, "unsupported algo " .. tostring(ht.algorithm)             end             local nc = "00000001"             local cnonce = string.format("%08x", os.time())             local uri = skturl.build({path = url.path, query = url.query})             local method = req.method or "GET"             local response = hash(hash(user, ht.realm, password), ht.nonce, nc, cnonce, "auth", hash(method, uri))             req.headers = req.headers or {}             local auth = {                 {"username", user},                 {"realm", ht.realm},                 {"nonce", ht.nonce},                 {"uri", uri},                 {"cnonce", cnonce},                 {"nc", nc, unquote = true},                 {"qop", "auth"},                 {"algorithm", "MD5"},                 {"response", response}             }             if ht.opaque then                 table.insert(auth, {"opaque", ht.opaque})             end             req.headers.authorization = make_digest_header(auth)             if not req.headers.cookie and hdrs["set-cookie"] then                 -- not really correct but enough for httpbin                 local cookie = (hdrs["set-cookie"] .. ";"):match("(.-=.-)[;,]")                 if cookie then                     req.headers.cookie = "$Version: 0; " .. cookie .. ";"                 end             end             if req.source then                 req.source = source             end             req.sink = sink             body, code, hdrs = skthttp.request(req)         end         return body, code, hdrs     end     local request = function(url)         local t = type(url)         if t == "table" then             return _request(table.clone(url))         elseif t == "string" then             local req = {}             local _, code, headers = _request({url = url, sink = ltn12.sink.table(req)})             return table.concat(req), code, headers         end     end     local response_body = {}     local request_body = ""     local res, code, response_headers, status =         request {         url = "https://test:test@10.0.0.230/api/display/image?display=ext1",         method = "DELETE",         source = ltn12.source.string(request_body),         sink = ltn12.sink.table(response_body),         protocol = "tlsv1_2"     }     if code == 200 then         log("Image deleted successfully!")     else         log("Error deleting image: " .. code)     end else     log("ERROR") end
Reply


Messages In This Thread
HTTP PUT image to 2N intercom - by coolaew - 07.02.2023, 23:57
RE: HTTP PUT image to 2N intercom - by admin - 08.02.2023, 11:21
RE: HTTP PUT image to 2N intercom - by admin - 09.02.2023, 07:58
RE: HTTP PUT image to 2N intercom - by coolaew - 09.02.2023, 22:13

Forum Jump: