22static 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',
'+',
'/',
33static unsigned char base64_invert[128];
34static bool got_base64_invert =
false;
40HTTPAuthorization(
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));
101bool HTTPAuthorization::
110void HTTPAuthorization::
111parse_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])) {
129 string scheme = HTTPChannel::downcase(field_value.substr(p, q - p));
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] ==
'=') {
142 string token = HTTPChannel::downcase(field_value.substr(p, q - p));
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]))) {
155 scheme = HTTPChannel::downcase(field_value.substr(p, q - p));
156 tokens = &(schemes[scheme]);
169get_canonical_url(
const URLSpec &url) {
183string HTTPAuthorization::
184base64_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];
228string HTTPAuthorization::
229base64_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);
280size_t HTTPAuthorization::
281scan_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])) {
A container for a URL, e.g.
set_port
Replaces the port part of the URL specification.
set_scheme
Replaces the scheme part of the URL specification.
set_path
Replaces the path part of the URL specification.
const std::string & get_url() const
Returns the complete URL specification.
get_path
Returns the path specified by the URL, or "/" if no path is specified.
get_scheme
Returns the scheme specified by the URL, or empty string if no scheme is specified.
get_port
Returns the port number specified by the URL, or the default port if not specified.
set_username
Replaces the username part of the URL specification.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.