![]() ![]() |
![]() |
1 martin 1.48 //%LICENSE//////////////////////////////////////////////////////////////// | ||
2 martin 1.49 // | ||
3 martin 1.48 // Licensed to The Open Group (TOG) under one or more contributor license 4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with 5 // this work for additional information regarding copyright ownership. 6 // Each contributor licenses this file to you under the OpenPegasus Open 7 // Source License; you may not use this file except in compliance with the 8 // License. | ||
9 martin 1.49 // | ||
10 martin 1.48 // Permission is hereby granted, free of charge, to any person obtaining a 11 // copy of this software and associated documentation files (the "Software"), 12 // to deal in the Software without restriction, including without limitation 13 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 // and/or sell copies of the Software, and to permit persons to whom the 15 // Software is furnished to do so, subject to the following conditions: | ||
16 martin 1.49 // | ||
17 martin 1.48 // The above copyright notice and this permission notice shall be included 18 // in all copies or substantial portions of the Software. | ||
19 martin 1.49 // | ||
20 martin 1.48 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
21 martin 1.49 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
22 martin 1.48 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
27 martin 1.49 // | ||
28 martin 1.48 ////////////////////////////////////////////////////////////////////////// | ||
29 mike 1.2 // 30 //%///////////////////////////////////////////////////////////////////////////// 31 32 #include <Pegasus/Common/Config.h> 33 #include <iostream> | ||
34 mike 1.29 #include <cstring> | ||
35 mike 1.2 #include "HTTPMessage.h" | ||
36 kumpf 1.51 #include "System.h" | ||
37 mike 1.34 #include "ArrayIterator.h" | ||
38 mike 1.2 39 PEGASUS_USING_STD; 40 41 PEGASUS_NAMESPACE_BEGIN 42 | ||
43 kumpf 1.51 static const char* _HTTP_HEADER_CONTENT_TYPE = "content-type"; | ||
44 mike 1.2 45 //------------------------------------------------------------------------------ 46 // 47 // Implementation notes: 48 // | ||
49 david.dillard 1.22 // According to the HTTP specification: | ||
50 mike 1.2 // 51 // 1. Method names are case-sensitive. 52 // 2. Field names are case-insensitive. 53 // 3. The first line of a message is known as the "start-line". 54 // 4. Subsequent lines are known as headers. 55 // 5. Headers have a field-name and field-value. 56 // 6. Start-lines may be request-lines or status-lines. Request lines 57 // have this form: 58 // 59 // Request-Line = Method SP Request-URI SP HTTP-Version CRLF 60 // 61 // Status-lines have this form: 62 // 63 // Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF 64 // 65 //------------------------------------------------------------------------------ 66 | ||
67 sushma.fernandes 1.41 char* HTTPMessage::findSeparator(const char* data, Uint32 size) | ||
68 mike 1.2 { | ||
69 mike 1.47 // [^\0\r\n] 70 static const unsigned char _skip[256] = | ||
71 mike 1.2 { | ||
72 mike 1.47 0,1,1,1,1,1,1,1,1,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 73 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 74 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 75 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 76 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 77 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 78 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 79 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 80 }; 81 82 // Note that data is null-terminated. 83 const unsigned char* p = (const unsigned char*)data; 84 85 for (;;) 86 { 87 // Search for a '\0', '\r', or '\n'. 88 while (_skip[*p]) 89 p++; 90 91 if (!p[0]) | ||
92 kumpf 1.50 break; | ||
93 mike 1.47 if (p[0] == '\r' && p[1] == '\n') 94 return (char*)p; 95 if (p[0] == '\n') | ||
96 kumpf 1.36 return (char*)p; | ||
97 mike 1.2 | ||
98 kumpf 1.36 p++; | ||
99 mike 1.2 } 100 101 return 0; 102 } 103 | ||
104 sushma.fernandes 1.41 void HTTPMessage::skipHeaderWhitespace(const char*& str) | ||
105 venkat.puvvada 1.40 { | ||
106 sushma.fernandes 1.41 while (*str && (*str == ' ' || *str == '\t')) | ||
107 venkat.puvvada 1.40 { 108 ++str; 109 } 110 } 111 | ||
112 sushma.fernandes 1.41 Boolean HTTPMessage::expectHeaderToken(const char*& str, const char *token) | ||
113 venkat.puvvada 1.40 { 114 PEGASUS_ASSERT(token); | ||
115 sushma.fernandes 1.41 116 skipHeaderWhitespace(str); | ||
117 venkat.puvvada 1.40 for ( ; *token ; ++str, ++token) 118 { 119 if (!*str || tolower(*str) != tolower(*token)) 120 { 121 return false; 122 } 123 } 124 return true; 125 } 126 | ||
127 mike 1.2 HTTPMessage::HTTPMessage( | ||
128 mike 1.28 const Buffer& message_, | ||
129 brian.campbell 1.16 Uint32 queueId_, const CIMException *cimException_) | ||
130 mike 1.2 : | ||
131 david.dillard 1.22 Message(HTTP_MESSAGE), 132 message(message_), | ||
133 humberto 1.15 queueId(queueId_), | ||
134 kumpf 1.26 authInfo(0), | ||
135 humberto 1.15 acceptLanguagesDecoded(false), 136 contentLanguagesDecoded(false) | ||
137 mike 1.2 { | ||
138 kumpf 1.36 if (cimException_) 139 cimException = *cimException_; | ||
140 mike 1.2 } 141 | ||
142 mday 1.3 | ||
143 se.gupta 1.18 HTTPMessage::HTTPMessage(const HTTPMessage & msg) | ||
144 kumpf 1.36 : Base(msg) | ||
145 mday 1.3 { | ||
146 kumpf 1.36 message = msg.message; 147 queueId = msg.queueId; 148 authInfo = msg.authInfo; 149 acceptLanguages = msg.acceptLanguages; 150 contentLanguages = msg.contentLanguages; 151 acceptLanguagesDecoded = msg.acceptLanguagesDecoded; 152 contentLanguagesDecoded = msg.contentLanguagesDecoded; 153 cimException = msg.cimException; 154 } | ||
155 mday 1.3 156 | ||
157 mike 1.2 void HTTPMessage::parse( 158 String& startLine, 159 Array<HTTPHeader>& headers, 160 Uint32& contentLength) const 161 { 162 startLine.clear(); 163 headers.clear(); 164 contentLength = 0; 165 166 char* data = (char*)message.getData(); | ||
167 kumpf 1.39 Uint32 size = message.size(); | ||
168 david.dillard 1.20 char* line = data; | ||
169 mike 1.2 char* sep; 170 Boolean firstTime = true; 171 | ||
172 sushma.fernandes 1.41 while ((sep = findSeparator(line, (Uint32)(size - (line - data))))) | ||
173 mike 1.2 { | ||
174 kumpf 1.36 // Look for double separator which terminates the header? | ||
175 mike 1.2 | ||
176 kumpf 1.36 if (line == sep) 177 { 178 // Establish pointer to content (account for "\n" and "\r\n"). 179 180 char* content = line + ((*sep == '\r') ? 2 : 1); 181 182 // Determine length of content: 183 | ||
184 a.dunfey 1.38 contentLength = (Uint32)(message.size() - (content - data)); | ||
185 kumpf 1.36 break; 186 } 187 | ||
188 a.dunfey 1.38 Uint32 lineLength = (Uint32)(sep - line); | ||
189 kumpf 1.36 190 if (firstTime) 191 startLine.assign(line, lineLength); 192 else 193 { 194 // Find the colon: 195 196 char* colon = 0; 197 198 for (Uint32 i = 0; i < lineLength; i++) 199 { 200 if (line[i] == ':') 201 { 202 colon = &line[i]; 203 break; 204 } 205 } 206 207 // This should always be true: 208 209 if (colon) 210 kumpf 1.36 { 211 // Get the name part: 212 213 char* end; 214 215 for (end = colon - 1; end > line && isspace(*end); end--) 216 ; 217 218 end++; 219 220 // Get the value part: 221 222 char* start; 223 224 for (start = colon + 1; start < sep && isspace(*start); start++) 225 ; 226 | ||
227 kumpf 1.51 HTTPHeader header( 228 Buffer(line, (Uint32)(end - line), 20), 229 Buffer(start, (Uint32)(sep - start), 50)); | ||
230 kumpf 1.36 231 // From the HTTP/1.1 specification (RFC 2616) section 4.2 232 // Message Headers: 233 // 234 // Multiple message-header fields with the same field-name 235 // MAY be present in a message if and only if the entire 236 // field-value for that header field is defined as a 237 // comma-separated list [i.e., #(values)]. It MUST be 238 // possible to combine the multiple header fields into one 239 // "field-name: field-value" pair, without changing the 240 // semantics of the message, by appending each subsequent 241 // field-value to the first, each separated by a comma. The 242 // order in which header fields with the same field-name are 243 // received is therefore significant to the interpretation 244 // of the combined field value, and thus a proxy MUST NOT 245 // change the order of these field values when a message is 246 // forwarded. 247 248 // This implementation concatenates duplicate header values, 249 // with a comma separator. If the resulting value is invalid, 250 // that should be detected when the value is used. 251 kumpf 1.36 252 Uint32 headerIndex = 0; 253 for (; headerIndex < headers.size(); headerIndex++) 254 { | ||
255 kumpf 1.51 if (System::strcasecmp( 256 headers[headerIndex].first.getData(), 257 header.first.getData()) == 0) | ||
258 kumpf 1.36 { 259 break; 260 } 261 } 262 263 if (headerIndex == headers.size()) 264 { | ||
265 kumpf 1.51 headers.append(header); | ||
266 kumpf 1.36 } 267 else 268 { | ||
269 kumpf 1.51 headers[headerIndex].second.append(", ", 2); 270 headers[headerIndex].second.append( 271 header.second.getData(), header.second.size()); | ||
272 kumpf 1.36 } 273 } 274 } | ||
275 mike 1.2 | ||
276 kumpf 1.36 line = sep + ((*sep == '\r') ? 2 : 1); 277 firstTime = false; | ||
278 mike 1.2 } 279 } 280 | ||
281 joyce.j 1.24 282 #ifdef PEGASUS_DEBUG | ||
283 mike 1.2 void HTTPMessage::printAll(ostream& os) const 284 { 285 Message::print(os); 286 287 String startLine; 288 Array<HTTPHeader> headers; 289 Uint32 contentLength; 290 parse(startLine, headers, contentLength); 291 | ||
292 karl 1.13 // get pointer to start of data. | ||
293 david.dillard 1.20 const char* content = message.getData() + message.size() - contentLength; | ||
294 mike 1.2 // Print the first line: 295 | ||
296 karl 1.13 os << endl << startLine << endl; | ||
297 mike 1.2 298 // Print the headers: 299 300 Boolean image = false; 301 302 for (Uint32 i = 0; i < headers.size(); i++) 303 { | ||
304 kumpf 1.51 cout << headers[i].first.getData() << ": " << 305 headers[i].second.getData() << endl; | ||
306 david.dillard 1.22 | ||
307 kumpf 1.51 if (System::strcasecmp( 308 headers[i].first.getData(), _HTTP_HEADER_CONTENT_TYPE) == 0) | ||
309 kumpf 1.36 { | ||
310 kumpf 1.51 if (strncmp(headers[i].second.getData(), "image/", 6) == 0) | ||
311 kumpf 1.36 image = true; 312 } | ||
313 mike 1.2 } 314 | ||
315 karl 1.13 os << endl; | ||
316 mike 1.2 317 // Print the content: 318 319 for (Uint32 i = 0; i < contentLength; i++) 320 { | ||
321 kumpf 1.36 //char c = content[i]; | ||
322 mike 1.2 | ||
323 kumpf 1.36 if (image) 324 { 325 if ((i % 60) == 0) 326 os << endl; 327 328 char c = content[i]; 329 330 if (c >= ' ' && c < '~') 331 os << c; 332 else 333 os << '.'; 334 } 335 else 336 cout << content[i]; | ||
337 mike 1.2 } 338 | ||
339 karl 1.13 os << endl; | ||
340 mike 1.2 } | ||
341 joyce.j 1.24 #endif | ||
342 mike 1.2 | ||
343 brian.campbell 1.16 /* 344 * Find the header prefix (i.e 2-digit number in front of cim keyword) if any. | ||
345 david.dillard 1.22 * If a fieldName is given it will use that, otherwise the FIRST field 346 * starting with the standard keyword will be used. Given field names that do | ||
347 brian.campbell 1.16 * not start with the standard keyword will never match. 348 * if there is a keyword match, the prefix will be populated, else set to empty 349 */ 350 351 void HTTPMessage::lookupHeaderPrefix( | ||
352 mike 1.34 Array<HTTPHeader>& headers_, | ||
353 kumpf 1.51 const char* fieldName, | ||
354 brian.campbell 1.16 String& prefix) 355 { | ||
356 kumpf 1.36 ArrayIterator<HTTPHeader> headers(headers_); | ||
357 mike 1.34 | ||
358 kumpf 1.36 static const char keyword[] = "CIM"; 359 prefix.clear(); | ||
360 brian.campbell 1.16 | ||
361 kumpf 1.36 for (Uint32 i = 0, n = headers.size(); i < n; i++) 362 { | ||
363 kumpf 1.51 const char* h = headers[i].first.getData(); | ||
364 brian.campbell 1.16 | ||
365 kumpf 1.51 if ((headers[i].first.size() >= 3) && 366 (h[0] >= '0') && (h[0] <= '9') && 367 (h[1] >= '0') && (h[1] <= '9') && 368 (h[2] == '-')) | ||
369 kumpf 1.36 { | ||
370 kumpf 1.51 const char* fieldNameCurrent = h + 3; | ||
371 brian.campbell 1.16 | ||
372 kumpf 1.37 // ONLY fields starting with keyword can have prefixed according 373 // to spec | ||
374 kumpf 1.51 if (!String::equalNoCase(String(fieldNameCurrent, 3), keyword)) | ||
375 kumpf 1.36 continue; 376 | ||
377 kumpf 1.51 prefix = String(h, 3); | ||
378 kumpf 1.36 379 // no field name given, just return the first prefix encountered | ||
380 kumpf 1.51 if (!fieldName) | ||
381 kumpf 1.36 break; 382 | ||
383 kumpf 1.51 if (System::strcasecmp(fieldNameCurrent, fieldName) != 0) | ||
384 kumpf 1.36 prefix.clear(); 385 else break; 386 } 387 } | ||
388 brian.campbell 1.16 } 389 | ||
390 kumpf 1.51 Boolean HTTPMessage::_lookupHeaderIndex( | ||
391 mike 1.34 Array<HTTPHeader>& headers_, | ||
392 kumpf 1.51 const char* fieldName, 393 Uint32& headerIndex, | ||
394 kumpf 1.5 Boolean allowNamespacePrefix) | ||
395 mike 1.2 { | ||
396 mike 1.34 ArrayIterator<HTTPHeader> headers(headers_); 397 | ||
398 mike 1.2 for (Uint32 i = 0, n = headers.size(); i < n; i++) 399 { | ||
400 kumpf 1.51 if ((System::strcasecmp(headers[i].first.getData(), fieldName) == 0) || | ||
401 kumpf 1.5 (allowNamespacePrefix && (headers[i].first.size() >= 3) && | ||
402 kumpf 1.25 (headers[i].first[0] >= '0') && (headers[i].first[0] <= '9') && 403 (headers[i].first[1] >= '0') && (headers[i].first[1] <= '9') && | ||
404 kumpf 1.51 (headers[i].first[2] == '-') && 405 (System::strcasecmp( 406 headers[i].first.getData() + 3, fieldName) == 0))) | ||
407 kumpf 1.36 { | ||
408 kumpf 1.51 headerIndex = i; | ||
409 kumpf 1.36 return true; 410 } | ||
411 mike 1.2 } 412 413 // Not found: 414 return false; 415 } 416 | ||
417 kumpf 1.51 Boolean HTTPMessage::lookupHeader( 418 Array<HTTPHeader>& headers, 419 const char* fieldName, 420 String& fieldValue, 421 Boolean allowNamespacePrefix) 422 { 423 Uint32 index = PEG_NOT_FOUND; 424 425 if (_lookupHeaderIndex(headers, fieldName, index, allowNamespacePrefix)) 426 { 427 fieldValue = String( 428 headers[index].second.getData(), 429 headers[index].second.size()); 430 return true; 431 } 432 433 return false; 434 } 435 436 Boolean HTTPMessage::lookupHeader( 437 Array<HTTPHeader>& headers, 438 kumpf 1.51 const char* fieldName, 439 const char*& fieldValue, 440 Boolean allowNamespacePrefix) 441 { 442 Uint32 index = PEG_NOT_FOUND; 443 444 if (_lookupHeaderIndex(headers, fieldName, index, allowNamespacePrefix)) 445 { 446 fieldValue = headers[index].second.getData(); 447 return true; 448 } 449 450 return false; 451 } 452 | ||
453 mike 1.2 Boolean HTTPMessage::parseRequestLine( 454 const String& startLine, 455 String& methodName, 456 String& requestUri, 457 String& httpVersion) 458 { 459 // Request-Line = Method SP Request-URI SP HTTP-Version CRLF 460 461 // Extract the method-name: 462 463 Uint32 space1 = startLine.find(' '); 464 | ||
465 kumpf 1.10 if (space1 == PEG_NOT_FOUND) | ||
466 kumpf 1.36 return false; | ||
467 mike 1.2 468 methodName = startLine.subString(0, space1); 469 470 // Extrat the request-URI: 471 472 Uint32 space2 = startLine.find(space1 + 1, ' '); 473 | ||
474 kumpf 1.10 if (space2 == PEG_NOT_FOUND) | ||
475 kumpf 1.36 return false; | ||
476 mike 1.2 477 Uint32 uriPos = space1 + 1; 478 479 requestUri = startLine.subString(uriPos, space2 - uriPos); 480 481 // Extract the HTTP version: 482 483 httpVersion = startLine.subString(space2 + 1); | ||
484 kumpf 1.4 485 return true; 486 } 487 488 Boolean HTTPMessage::parseStatusLine( 489 const String& statusLine, 490 String& httpVersion, 491 Uint32& statusCode, 492 String& reasonPhrase) 493 { 494 // Request-Line = Method SP Request-URI SP HTTP-Version CRLF 495 // Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF 496 497 // Extract the HTTP version: 498 499 Uint32 space1 = statusLine.find(' '); 500 | ||
501 kumpf 1.10 if (space1 == PEG_NOT_FOUND) | ||
502 kumpf 1.36 return false; | ||
503 kumpf 1.4 504 httpVersion = statusLine.subString(0, space1); 505 506 // Extract the status code: 507 508 Uint32 space2 = statusLine.find(space1 + 1, ' '); 509 | ||
510 kumpf 1.10 if (space2 == PEG_NOT_FOUND) | ||
511 kumpf 1.36 return false; | ||
512 kumpf 1.4 513 Uint32 statusCodePos = space1 + 1; 514 String statusCodeStr; 515 statusCodeStr = statusLine.subString(statusCodePos, space2 - statusCodePos); | ||
516 kumpf 1.11 if (!sscanf(statusCodeStr.getCString(), "%u", &statusCode)) | ||
517 kumpf 1.4 return false; 518 519 // Extract the reason phrase: 520 521 reasonPhrase = statusLine.subString(space2 + 1); | ||
522 mike 1.2 523 return true; 524 } 525 | ||
526 kumpf 1.44 Boolean HTTPMessage::parseContentTypeHeader( | ||
527 kumpf 1.51 const char* contentTypeHeader, | ||
528 kumpf 1.44 String& type, 529 String& charset) | ||
530 venkat.puvvada 1.40 { | ||
531 kumpf 1.51 const char* str = contentTypeHeader; | ||
532 kumpf 1.44 skipHeaderWhitespace(str); 533 534 // Get the type string | ||
535 venkat.puvvada 1.40 | ||
536 kumpf 1.44 const char* end = str; 537 while (*end && (*end != ' ') && (*end != '\t') && (*end != ';')) | ||
538 venkat.puvvada 1.40 { | ||
539 kumpf 1.44 end++; | ||
540 venkat.puvvada 1.40 } 541 | ||
542 kumpf 1.44 type.assign(str, end-str); 543 str = end; | ||
544 sushma.fernandes 1.41 skipHeaderWhitespace(str); | ||
545 venkat.puvvada 1.40 | ||
546 kumpf 1.44 // Get the charset 547 548 if (*str == ';') | ||
549 venkat.puvvada 1.40 { | ||
550 kumpf 1.44 str++; 551 if (!expectHeaderToken(str, "charset") || 552 !expectHeaderToken(str, "=")) 553 { 554 return false; 555 } 556 skipHeaderWhitespace(str); | ||
557 venkat.puvvada 1.40 | ||
558 kumpf 1.44 // The value may optionally be enclosed in quotes 559 if (*str == '"') 560 { 561 str++; 562 end = strchr(str, '"'); 563 if (!end) 564 { 565 return false; 566 } 567 charset.assign(str, end-str); 568 str = end + 1; 569 } 570 else | ||
571 dave.sudlik 1.42 { | ||
572 kumpf 1.44 end = str; 573 while (*end && (*end != ' ') && (*end != '\t')) 574 { 575 end++; 576 } 577 charset.assign(str, end-str); 578 str = end; | ||
579 dave.sudlik 1.42 } 580 } | ||
581 kumpf 1.44 else 582 { 583 // No charset specified; assume UTF-8. 584 charset = "utf-8"; 585 } | ||
586 dave.sudlik 1.42 | ||
587 sushma.fernandes 1.41 skipHeaderWhitespace(str); | ||
588 venkat.puvvada 1.40 | ||
589 kumpf 1.44 // Check for unexpected characters at the end of the value | ||
590 venkat.puvvada 1.40 return !*str; 591 } 592 | ||
593 thilo.boehm 1.43 // 594 // parse the local authentication header 595 // 596 Boolean HTTPMessage::parseLocalAuthHeader( 597 const String& authHeader, 598 String& authType, 599 String& userName, 600 String& cookie) 601 { 602 PEG_METHOD_ENTER(TRC_HTTP, "HTTPMessage::parseLocalAuthHeader()"); 603 604 // 605 // Extract the authentication type: 606 // 607 Uint32 space = authHeader.find(' '); 608 609 if ( space == PEG_NOT_FOUND ) 610 { 611 PEG_METHOD_EXIT(); 612 return false; 613 } 614 thilo.boehm 1.43 615 authType = authHeader.subString(0, space); 616 617 Uint32 startQuote = authHeader.find(space, '"'); 618 619 if ( startQuote == PEG_NOT_FOUND ) 620 { 621 PEG_METHOD_EXIT(); 622 return false; 623 } 624 625 Uint32 endQuote = authHeader.find(startQuote + 1, '"'); 626 627 if ( endQuote == PEG_NOT_FOUND ) 628 { 629 PEG_METHOD_EXIT(); 630 return false; 631 } 632 633 String temp = authHeader.subString( 634 startQuote + 1, (endQuote - startQuote - 1)); 635 thilo.boehm 1.43 636 // 637 // Extract the user name and cookie: 638 // 639 Uint32 colon = temp.find(0, ':'); 640 641 if ( colon == PEG_NOT_FOUND ) 642 { 643 userName = temp; 644 } 645 else 646 { 647 userName = temp.subString(0, colon); 648 cookie = temp; 649 } 650 651 PEG_METHOD_EXIT(); 652 653 return true; 654 } 655 656 thilo.boehm 1.43 // 657 // parse the HTTP authentication header 658 // 659 Boolean HTTPMessage::parseHttpAuthHeader( 660 const String& authHeader, String& authTypeString, String& cookie) 661 { 662 PEG_METHOD_ENTER(TRC_HTTP, "HTTPMessage::parseHttpAuthHeader()"); 663 664 // 665 // Extract the authentication type: 666 // 667 Uint32 space = authHeader.find(' '); 668 669 if ( space == PEG_NOT_FOUND ) 670 { 671 PEG_METHOD_EXIT(); 672 return false; 673 } 674 675 authTypeString = authHeader.subString(0, space); 676 677 thilo.boehm 1.43 // 678 // Extract the cookie: 679 // 680 cookie = authHeader.subString(space + 1); 681 682 PEG_METHOD_EXIT(); 683 684 return true; 685 } 686 | ||
687 mike 1.2 PEGASUS_NAMESPACE_END |
No CVS admin address has been configured |
Powered by ViewCVS 0.9.2 |