14.03.2023, 07:57
(13.03.2023, 12:51)admin Wrote: Are you sure that this uses Basic auth but not digest?
I´ll try it with digest first. I wroute in the post "Email with attachement" but you tell me to try with basic auth. But this post is very old and I create a new more specific.
Trying with digest auth this is the result:
Code:
* arg: 1
* string: <!DOCTYPE html>
<html><head><title>Document Error: Unauthorized</title></head>
<body><h2>Access Error: 401 -- Unauthorized</h2>
<p>Authentication Error</p>
</body>
</html>
<!DOCTYPE html>
<html><head><title>Document Error: Unauthorized</title></head>
<body><h2>Access Error: 401 -- Unauthorized</h2>
<p>Authentication Error</p>
</body>
</html>
* arg: 2
* number: 401
* arg: 3
* table:
["server"]
* string: webserver
["content-type"]
* string: text/html
["connection"]
* string: close
["date"]
* string: Mon, 13 Mar 2023 10:37:01 GMT
["x-frame-options"]
* string: SAMEORIGIN
["www-authenticate"]
* string: Digest qop="auth", realm="IP Camera(F0849)", nonce="5a6d566c5a475a6d59324d365a474534596a67794d6d493d", stale="FALSE"
["content-length"]
* string: 178
And the code is:
Code:
local url = 'http://user:Pass@'..IP..'/ISAPI/Streaming/channels/101/picture'
function SnapshotCamaraIP (url)
--Meter url de la camara http://admin:pass@"IP"/snapshot.jpeg
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
--log(user,password)
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
local body, code, hdrs = skthttp.request(req)
--log(body, code, hdrs)
if code == 401 and hdrs['www-authenticate'] then
local ht = parse_header(hdrs['www-authenticate'])
log(ht)
if not ht.realm or not ht.nonce then
log("REALM")
return nil, 'missing realm/nonce from response'
end
if ht.qop ~= 'auth' then
log("QOP")
return nil, 'unsupported qop ' .. tostring(ht.qop)
end
if ht.algorithm and ht.algorithm:lower() ~= 'md5' then
log("MD5")
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
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
image, err, hdrs = request(url)
log(image, err, hdrs)
return image,err
end
Thanks