| 900 | : 0; |
| 901 | const unsigned char b2 = available > 2 ? static_cast<unsigned char>(basicAuthorizationSourceByte( |
| 902 | usernameBytes, passwordBytes, inputOffset + 2)) |
| 903 | : 0; |
| 904 | |
| 905 | output[outputOffset + 0] = Base64[(b0 >> 2) & 0x3F]; |
| 906 | output[outputOffset + 1] = Base64[((b0 & 0x03) << 4) | ((b1 >> 4) & 0x0F)]; |
| 907 | output[outputOffset + 2] = available > 1 ? Base64[((b1 & 0x0F) << 2) | ((b2 >> 6) & 0x03)] : '='; |
| 908 | output[outputOffset + 3] = available > 2 ? Base64[b2 & 0x3F] : '='; |
| 909 | } |
| 910 | |
| 911 | authorizationHeader = {{destination.data(), PrefixBytes + encodedBytes}, false, StringEncoding::Ascii}; |
| 912 | return Result(true); |
| 913 | } |
| 914 | |
| 915 | bool SC::HttpClientSession::findBasicAuthChallenge(const HttpClientResponse& response, |
| 916 | HttpClientSessionAuthChallenge::Target target, |
| 917 | HttpClientSessionAuthChallenge& challenge) |
| 918 | { |
| 919 | challenge = HttpClientSessionAuthChallenge(); |
| 920 | challenge.target = target; |
| 921 | if (target != HttpClientSessionAuthChallenge::Origin and target != HttpClientSessionAuthChallenge::Proxy) |
| 922 | { |
| 923 | return false; |
| 924 | } |
| 925 | |
| 926 | const StringSpan headerName = target == HttpClientSessionAuthChallenge::Proxy ? StringSpan("Proxy-Authenticate") |
| 927 | : StringSpan("WWW-Authenticate"); |
| 928 | |
| 929 | HttpClientResponseHeaderIterator iterator; |
| 930 | StringSpan value; |
| 931 | while (response.findNextHeader(headerName, iterator, value)) |
| 932 | { |
| 933 | if (findBasicChallengeInValue(value, target, challenge)) |
| 934 | { |
| 935 | return true; |
| 936 | } |
| 937 | } |
| 938 | return false; |
| 939 | } |
| 940 | |
| 941 | SC::Result SC::HttpClientSession::makeBasicAuthorizationForChallenge(const HttpClientResponse& response, |
| 942 | HttpClientSessionAuthChallenge::Target target, |
| 943 | StringSpan username, StringSpan password, |
| 944 | Span<char> destination, |
| 945 | StringSpan& authorizationHeader) |
| 946 | { |
| 947 | if (target != HttpClientSessionAuthChallenge::Origin and target != HttpClientSessionAuthChallenge::Proxy) |
| 948 | return Result::Error(HttpClientResultCategory, HttpClientError::SessionAuthChallengeTargetInvalid); |
| 949 | const int expectedStatusCode = target == HttpClientSessionAuthChallenge::Proxy ? 407 : 401; |
| 950 | if (response.statusCode != expectedStatusCode) |
| 951 | return Result::Error(HttpClientResultCategory, HttpClientError::SessionAuthResponseStatusInvalid); |
| 952 | |
| 953 | HttpClientSessionAuthChallenge challenge; |
| 954 | if (not findBasicAuthChallenge(response, target, challenge)) |
| 955 | return Result::Error(HttpClientResultCategory, HttpClientError::SessionBasicChallengeMissing); |
| 956 | return makeBasicAuthorization(username, password, destination, authorizationHeader); |
| 957 | } |
| 958 | |
| 959 | SC::Result SC::HttpClientSession::appendMatchingCookies(StringSpan url, size_t& numHeaders) |
nothing calls this directly
no test coverage detected