22 static const char base64_table[64] = {
23 'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
24 'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
25 'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
26 'Y',
'Z',
'a',
'b',
'c',
'd',
'e',
'f',
27 'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
28 'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
29 'w',
'x',
'y',
'z',
'0',
'1',
'2',
'3',
30 '4',
'5',
'6',
'7',
'8',
'9',
'+',
'/',
33 static unsigned char base64_invert[128];
34 static bool got_base64_invert =
false;
40 HTTPAuthorization(
const HTTPAuthorization::Tokens &tokens,
41 const URLSpec &url,
bool is_proxy) {
42 Tokens::const_iterator ti;
43 ti = tokens.find(
"realm");
44 if (ti != tokens.end()) {
45 _realm = (*ti).second;
48 URLSpec canon = get_canonical_url(url);
50 ti = tokens.find(
"domain");
51 if (ti != tokens.end() && !is_proxy) {
53 const string &domain = (*ti).second;
55 while (p < domain.length()) {
56 while (p < domain.length() && isspace(domain[p])) {
60 while (q < domain.length() && !isspace(domain[q])) {
64 string domain_str = domain.substr(p, q - p);
66 if (domain_url.has_server()) {
68 _domain.push_back(get_canonical_url(domain_url).get_url());
73 _domain.push_back(domain_url.get_url());
82 string canon_str = canon.
get_url();
83 size_t slash = canon_str.rfind(
'/');
84 nassertv(slash != string::npos);
85 _domain.push_back(canon_str.substr(0, slash + 1));
93 ~HTTPAuthorization() {
101 bool HTTPAuthorization::
110 void HTTPAuthorization::
111 parse_authentication_schemes(HTTPAuthorization::AuthenticationSchemes &schemes,
112 const string &field_value) {
119 while (p < field_value.length() && isspace(field_value[p])) {
123 if (p < field_value.length()) {
125 while (q < field_value.length() && !isspace(field_value[q])) {
130 Tokens *tokens = &(schemes[scheme]);
134 while (p < field_value.length()) {
136 while (q < field_value.length() && field_value[q] !=
'=' &&
137 field_value[q] !=
',' && !isspace(field_value[q])) {
140 if (field_value[q] ==
'=') {
144 p = scan_quoted_or_unquoted_string(value, field_value, q + 1);
145 (*tokens)[token] = value;
148 while (p < field_value.length() &&
149 (field_value[p] ==
',' || isspace(field_value[p]))) {
156 tokens = &(schemes[scheme]);
169 get_canonical_url(
const URLSpec &url) {
183 string HTTPAuthorization::
184 base64_encode(
const string &s) {
187 size_t num_words = (s.size() + 2) / 3;
189 result.reserve(num_words * 4);
191 for (p = 0; p + 2 < s.size(); p += 3) {
193 ((unsigned)s[p] << 16) |
194 ((unsigned)s[p + 1] << 8) |
195 ((unsigned)s[p + 2]);
196 result += base64_table[(word >> 18) & 0x3f];
197 result += base64_table[(word >> 12) & 0x3f];
198 result += base64_table[(word >> 6) & 0x3f];
199 result += base64_table[(word) & 0x3f];
203 unsigned int word = ((unsigned)s[p] << 16);
206 word |= ((unsigned)s[p] << 8);
208 nassertr(p == s.size(), result);
210 result += base64_table[(word >> 18) & 0x3f];
211 result += base64_table[(word >> 12) & 0x3f];
212 result += base64_table[(word >> 6) & 0x3f];
215 result += base64_table[(word >> 18) & 0x3f];
216 result += base64_table[(word >> 12) & 0x3f];
228 string HTTPAuthorization::
229 base64_decode(
const string &s) {
231 if (!got_base64_invert) {
233 for (i = 0; i < 128; i++) {
234 base64_invert[i] = 0xff;
237 for (
int i = 0; i < 64; i++) {
238 base64_invert[(int)base64_table[i]] = i;
241 base64_invert[(int)
'='] = 0;
243 got_base64_invert =
true;
248 size_t num_words = s.size() / 4;
250 result.reserve(num_words * 3);
252 for (p = 0; p < s.size(); p += 4) {
253 unsigned int c0 = base64_invert[s[p] & 0x7f];
254 unsigned int c1 = base64_invert[s[p + 1] & 0x7f];
255 unsigned int c2 = base64_invert[s[p + 2] & 0x7f];
256 unsigned int c3 = base64_invert[s[p + 3] & 0x7f];
259 (c0 << 18) | (c1 << 12) | (c2 << 6) | c3;
261 result += (char)((word >> 16) & 0xff);
262 if (s[p + 2] !=
'=') {
263 result += (char)((word >> 8) & 0xff);
264 if (s[p + 3] !=
'=') {
265 result += (char)(word & 0xff);
280 size_t HTTPAuthorization::
281 scan_quoted_or_unquoted_string(
string &result,
const string &source,
285 if (start < source.length()) {
286 if (source[start] ==
'"') {
288 size_t p = start + 1;
289 while (p < source.length() && source[p] !=
'"') {
290 if (source[p] ==
'\\') {
293 if (p < source.length()) {
302 if (p < source.length()) {
310 while (p < source.length() && source[p] !=
',' && !isspace(source[p])) {
322 #endif // HAVE_OPENSSL PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A container for a URL, e.g.
string downcase(const string &s)
Returns the input string with all uppercase letters converted to lowercase.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_scheme
Returns the scheme specified by the URL, or empty string if no scheme is specified.
set_path
Replaces the path part of the URL specification.
get_path
Returns the path specified by the URL, or "/" if no path is specified.
set_username
Replaces the username part of the URL specification.
get_port
Returns the port number specified by the URL, or the default port if not specified.
const std::string & get_url() const
Returns the complete URL specification.
set_scheme
Replaces the scheme part of the URL specification.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
set_port
Replaces the port part of the URL specification.