09.02.2023, 22:13 
		
	
	
		Thank you so much!
Finally got it working with digest, it could problably be done prettier, but this works for me 
 
	
	
	
	
Finally got it working with digest, it could problably be done prettier, but this works for me
 
 Code:
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 
 

