function buildDigestHeader(user, pass, method, path, authHeader) {
        var challenge = {}
        var re = /([a-z0-9_-]+)=(?:"([^"]+)"|([a-z0-9_-]+))/gi
        for (;;) {
            var match = re.exec(authHeader)
            if (!match) {
                break
            }
            challenge[match[1]] = match[2] || match[3]
        }
        var qop = /(^|,)\s*auth\s*($|,)/.test(challenge.qop) && 'auth'
        var nc = qop && '00000001'
        var cnonce = qop && uuid().replace(/-/g, '')
        var ha1 = ha1Compute(challenge.algorithm, user, challenge.realm, pass, challenge.nonce, cnonce)
        var ha2 = digestCompute(challenge.algorithm, method + ':' + path)
        var digestResponse = qop
        ? digestCompute(challenge.algorithm, ha1 + ':' + challenge.nonce + ':' + nc + ':' + cnonce + ':' + qop + ':' + ha2)
        : digestCompute(challenge.algorithm, ha1 + ':' + challenge.nonce + ':' + ha2)
        var authValues = {
            username: user,
            realm: challenge.realm,
            nonce: challenge.nonce,
            uri: path,
            qop: qop,
            response: digestResponse,
            nc: nc,
            cnonce: cnonce,
            algorithm: challenge.algorithm,
            opaque: challenge.opaque
        }

        authHeader = []
        for (var k in authValues) {
            if (authValues[k]) {
                if (k === 'qop' || k === 'nc' || k === 'algorithm') {
                    authHeader.push(k + '=' + authValues[k])
                } else {
                    authHeader.push(k + '="' + authValues[k] + '"')
                }
            }
        }
        authHeader = 'Digest ' + authHeader.join(', ')
        return authHeader
    }
RFC 2617: handle both standard and -sess algorithms.

If the algorithm directive's value ends with "-sess", then HA1 is
  HA1=digestCompute(digestCompute(username:realm:password):nonce:cnonce)

If the algorithm directive's value does not end with "-sess", then HA1 is
  HA1=digestCompute(username:realm:password)