/usr/include/pion/net/HTTPParser.hpp is in libpion-net-dev 4.0.7+dfsg-3.1ubuntu2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 | // ------------------------------------------------------------------
// pion-net: a C++ framework for building lightweight HTTP interfaces
// ------------------------------------------------------------------
// Copyright (C) 2007-2008 Atomic Labs, Inc. (http://www.atomiclabs.com)
//
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
//
#ifndef __PION_HTTPPARSER_HEADER__
#define __PION_HTTPPARSER_HEADER__
#include <string>
#include <boost/noncopyable.hpp>
#include <boost/logic/tribool.hpp>
#include <boost/system/error_code.hpp>
#include <boost/thread/once.hpp>
#include <pion/PionConfig.hpp>
#include <pion/PionLogger.hpp>
#include <pion/net/HTTPMessage.hpp>
namespace pion { // begin namespace pion
namespace net { // begin namespace net (Pion Network Library)
// forward declarations used for finishing HTTP messages
class HTTPRequest;
class HTTPResponse;
///
/// HTTPParser: parses HTTP messages
///
class PION_NET_API HTTPParser :
private boost::noncopyable
{
public:
/// maximum length for HTTP payload content
static const std::size_t DEFAULT_CONTENT_MAX;
/// class-specific error code values
enum ErrorValue {
ERROR_METHOD_CHAR = 1,
ERROR_METHOD_SIZE,
ERROR_URI_CHAR,
ERROR_URI_SIZE,
ERROR_QUERY_CHAR,
ERROR_QUERY_SIZE,
ERROR_VERSION_EMPTY,
ERROR_VERSION_CHAR,
ERROR_STATUS_EMPTY,
ERROR_STATUS_CHAR,
ERROR_HEADER_CHAR,
ERROR_HEADER_NAME_SIZE,
ERROR_HEADER_VALUE_SIZE,
ERROR_INVALID_CONTENT_LENGTH,
ERROR_CHUNK_CHAR,
ERROR_MISSING_CHUNK_DATA,
ERROR_MISSING_HEADER_DATA,
ERROR_MISSING_TOO_MUCH_CONTENT,
};
/// class-specific error category
class ErrorCategory
: public boost::system::error_category
{
public:
const char *name() const { return "HTTPParser"; }
std::string message(int ev) const {
switch (ev) {
case ERROR_METHOD_CHAR:
return "invalid method character";
case ERROR_METHOD_SIZE:
return "method exceeds maximum size";
case ERROR_URI_CHAR:
return "invalid URI character";
case ERROR_URI_SIZE:
return "method exceeds maximum size";
case ERROR_QUERY_CHAR:
return "invalid query string character";
case ERROR_QUERY_SIZE:
return "query string exceeds maximum size";
case ERROR_VERSION_EMPTY:
return "HTTP version undefined";
case ERROR_VERSION_CHAR:
return "invalid version character";
case ERROR_STATUS_EMPTY:
return "HTTP status undefined";
case ERROR_STATUS_CHAR:
return "invalid status character";
case ERROR_HEADER_CHAR:
return "invalid header character";
case ERROR_HEADER_NAME_SIZE:
return "header name exceeds maximum size";
case ERROR_HEADER_VALUE_SIZE:
return "header value exceeds maximum size";
case ERROR_INVALID_CONTENT_LENGTH:
return "invalid Content-Length header";
case ERROR_CHUNK_CHAR:
return "invalid chunk character";
case ERROR_MISSING_HEADER_DATA:
return "missing header data";
case ERROR_MISSING_CHUNK_DATA:
return "missing chunk data";
case ERROR_MISSING_TOO_MUCH_CONTENT:
return "missing too much content";
}
return "HTTPParser error";
}
};
/**
* creates new HTTPParser objects
*
* @param is_request if true, the message is parsed as an HTTP request;
* if false, the message is parsed as an HTTP response
* @param max_content_length maximum length for HTTP payload content
*/
HTTPParser(const bool is_request, std::size_t max_content_length = DEFAULT_CONTENT_MAX)
: m_logger(PION_GET_LOGGER("pion.net.HTTPParser")), m_is_request(is_request),
m_read_ptr(NULL), m_read_end_ptr(NULL), m_message_parse_state(PARSE_START),
m_headers_parse_state(is_request ? PARSE_METHOD_START : PARSE_HTTP_VERSION_H),
m_chunked_content_parse_state(PARSE_CHUNK_SIZE_START), m_status_code(0),
m_bytes_content_remaining(0), m_bytes_content_read(0),
m_bytes_last_read(0), m_bytes_total_read(0),
m_max_content_length(max_content_length),
m_parse_headers_only(false), m_save_raw_headers(false)
{}
/// default destructor
virtual ~HTTPParser() {}
/**
* parses an HTTP message including all payload content it might contain
*
* @param http_msg the HTTP message object to populate from parsing
* @param ec error_code contains additional information for parsing errors
*
* @return boost::tribool result of parsing:
* false = message has an error,
* true = finished parsing HTTP message,
* indeterminate = not yet finished parsing HTTP message
*/
boost::tribool parse(HTTPMessage& http_msg, boost::system::error_code& ec);
/**
* attempts to continue parsing despite having missed data (length is known but content is not)
*
* @param http_msg the HTTP message object to populate from parsing
* @param len the length in bytes of the missing data
* @param ec error_code contains additional information for parsing errors
*
* @return boost::tribool result of parsing:
* false = message has an error,
* true = finished parsing HTTP message,
* indeterminate = not yet finished parsing HTTP message
*/
boost::tribool parseMissingData(HTTPMessage& http_msg, std::size_t len,
boost::system::error_code& ec);
/**
* finishes parsing an HTTP response message
*
* @param http_msg the HTTP message object to finish
*/
void finish(HTTPMessage& http_msg) const;
/**
* resets the location and size of the read buffer
*
* @param ptr pointer to the first bytes available to be read
* @param len number of bytes available to be read
*/
inline void setReadBuffer(const char *ptr, size_t len) {
m_read_ptr = ptr;
m_read_end_ptr = ptr + len;
}
/**
* loads a read position bookmark
*
* @param read_ptr points to the next character to be consumed in the read_buffer
* @param read_end_ptr points to the end of the read_buffer (last byte + 1)
*/
inline void loadReadPosition(const char *&read_ptr, const char *&read_end_ptr) const {
read_ptr = m_read_ptr;
read_end_ptr = m_read_end_ptr;
}
/**
* checks to see if a premature EOF was encountered while parsing. This
* should be called if there is no more data to parse, and if the last
* call to the parse() function returned boost::indeterminate
*
* @param http_msg the HTTP message object being parsed
* @return true if premature EOF, false if message is OK & finished parsing
*/
inline bool checkPrematureEOF(HTTPMessage& http_msg) {
if (m_message_parse_state != PARSE_CONTENT_NO_LENGTH)
return true;
m_message_parse_state = PARSE_END;
http_msg.concatenateChunks();
finish(http_msg);
return false;
}
/**
* controls headers-only parsing (default is disabled; content parsed also)
*
* @param b if true, then the parse() function returns true after headers
*/
inline void parseHeadersOnly(bool b = true) { m_parse_headers_only = b; }
/**
* skip parsing all headers and parse payload content only
*
* @param http_msg the HTTP message object being parsed
*/
inline void skipHeaderParsing(HTTPMessage& http_msg) {
boost::system::error_code ec;
finishHeaderParsing(http_msg, ec);
}
/// resets the parser to its initial state
inline void reset(void) {
m_message_parse_state = PARSE_START;
m_headers_parse_state = (m_is_request ? PARSE_METHOD_START : PARSE_HTTP_VERSION_H);
m_chunked_content_parse_state = PARSE_CHUNK_SIZE_START;
m_status_code = 0;
m_status_message.erase();
m_method.erase();
m_resource.erase();
m_query_string.erase();
m_raw_headers.erase();
m_bytes_content_read = m_bytes_last_read = m_bytes_total_read = 0;
}
/// returns true if there are no more bytes available in the read buffer
inline bool eof(void) const { return m_read_ptr == NULL || m_read_ptr >= m_read_end_ptr; }
/// returns the number of bytes available in the read buffer
inline std::size_t bytes_available(void) const { return (eof() ? 0 : (std::size_t)(m_read_end_ptr - m_read_ptr)); }
/// returns the number of bytes read during the last parse operation
inline std::size_t gcount(void) const { return m_bytes_last_read; }
/// returns the total number of bytes read while parsing the HTTP message
inline std::size_t getTotalBytesRead(void) const { return m_bytes_total_read; }
/// returns the total number of bytes read while parsing the payload content
inline std::size_t getContentBytesRead(void) const { return m_bytes_content_read; }
/// returns the maximum length for HTTP payload content
inline std::size_t getMaxContentLength(void) const { return m_max_content_length; }
/// returns the raw HTTP headers saved by the parser
inline const std::string& getRawHeaders(void) const { return m_raw_headers; }
/// returns true if the parser is saving raw HTTP header contents
inline bool getSaveRawHeaders(void) const { return m_save_raw_headers; }
/// returns true if the parser is being used to parse an HTTP request
inline bool isParsingRequest(void) const { return m_is_request; }
/// returns true if the parser is being used to parse an HTTP response
inline bool isParsingResponse(void) const { return ! m_is_request; }
/// sets the maximum length for HTTP payload content
inline void setMaxContentLength(std::size_t n) { m_max_content_length = n; }
/// resets the maximum length for HTTP payload content to the default value
inline void resetMaxContentLength(void) { m_max_content_length = DEFAULT_CONTENT_MAX; }
/// sets parameter for saving raw HTTP header content
inline void setSaveRawHeaders(bool b) { m_save_raw_headers = b; }
/// sets the logger to be used
inline void setLogger(PionLogger log_ptr) { m_logger = log_ptr; }
/// returns the logger currently in use
inline PionLogger getLogger(void) { return m_logger; }
/**
* parse key-value pairs out of a url-encoded string
* (i.e. this=that&a=value)
*
* @param dict dictionary for key-values pairs
* @param ptr points to the start of the encoded string
* @param len length of the encoded string, in bytes
*
* @return bool true if successful
*/
static bool parseURLEncoded(HTTPTypes::QueryParams& dict,
const char *ptr, const std::size_t len);
/**
* parse key-value pairs out of a "Cookie" request header
* (i.e. this=that; a=value)
*
* @param dict dictionary for key-values pairs
* @param ptr points to the start of the header string to be parsed
* @param len length of the encoded string, in bytes
* @param set_cookie_header set true if parsing Set-Cookie response header
*
* @return bool true if successful
*/
static bool parseCookieHeader(HTTPTypes::CookieParams& dict,
const char *ptr, const std::size_t len,
bool set_cookie_header);
/**
* parse key-value pairs out of a "Cookie" request header
* (i.e. this=that; a=value)
*
* @param dict dictionary for key-values pairs
* @param cookie_header header string to be parsed
* @param set_cookie_header set true if parsing Set-Cookie response header
*
* @return bool true if successful
*/
static inline bool parseCookieHeader(HTTPTypes::CookieParams& dict,
const std::string& cookie_header, bool set_cookie_header)
{
return parseCookieHeader(dict, cookie_header.c_str(), cookie_header.size(), set_cookie_header);
}
/**
* parse key-value pairs out of a url-encoded string
* (i.e. this=that&a=value)
*
* @param dict dictionary for key-values pairs
* @param query the encoded query string to be parsed
*
* @return bool true if successful
*/
static inline bool parseURLEncoded(HTTPTypes::QueryParams& dict,
const std::string& query)
{
return parseURLEncoded(dict, query.c_str(), query.size());
}
/**
* parses an X-Forwarded-For HTTP header, and extracts from it an IP
* address that best matches the client's public IP address (if any are found)
*
* @param header the X-Forwarded-For HTTP header to parse
* @param public_ip the extract IP address, if found
*
* @return bool true if a public IP address was found and extracted
*/
static bool parseForwardedFor(const std::string& header, std::string& public_ip);
/// returns an instance of HTTPParser::ErrorCategory
static inline ErrorCategory& getErrorCategory(void) {
boost::call_once(HTTPParser::createErrorCategory, m_instance_flag);
return *m_error_category_ptr;
}
protected:
/**
* parses an HTTP message up to the end of the headers using bytes
* available in the read buffer
*
* @param http_msg the HTTP message object to populate from parsing
* @param ec error_code contains additional information for parsing errors
*
* @return boost::tribool result of parsing:
* false = message has an error,
* true = finished parsing HTTP headers,
* indeterminate = not yet finished parsing HTTP headers
*/
boost::tribool parseHeaders(HTTPMessage& http_msg, boost::system::error_code& ec);
/**
* updates an HTTPMessage object with data obtained from parsing headers
*
* @param http_msg the HTTP message object to populate from parsing
*/
void updateMessageWithHeaderData(HTTPMessage& http_msg) const;
/**
* should be called after parsing HTTP headers, to prepare for payload content parsing
* available in the read buffer
*
* @param http_msg the HTTP message object to populate from parsing
* @param ec error_code contains additional information for parsing errors
*
* @return boost::tribool result of parsing:
* false = message has an error,
* true = finished parsing HTTP message (no content),
* indeterminate = payload content is available to be parsed
*/
boost::tribool finishHeaderParsing(HTTPMessage& http_msg,
boost::system::error_code& ec);
/**
* parses a chunked HTTP message-body using bytes available in the read buffer
*
* @param chunk_buffers buffers to be populated from parsing chunked content
* @param ec error_code contains additional information for parsing errors
*
* @return boost::tribool result of parsing:
* false = message has an error,
* true = finished parsing message,
* indeterminate = message is not yet finished
*/
boost::tribool parseChunks(HTTPMessage::ChunkCache& chunk_buffers,
boost::system::error_code& ec);
/**
* consumes payload content in the parser's read buffer
*
* @param http_msg the HTTP message object to consume content for
* @param ec error_code contains additional information for parsing errors
*
* @return boost::tribool result of parsing:
* false = message has an error,
* true = finished parsing message,
* indeterminate = message is not yet finished
*/
boost::tribool consumeContent(HTTPMessage& http_msg,
boost::system::error_code& ec);
/**
* consume the bytes available in the read buffer, converting them into
* the next chunk for the HTTP message
*
* @param chunk_buffers buffers to be populated from parsing chunked content
* @return std::size_t number of content bytes consumed, if any
*/
std::size_t consumeContentAsNextChunk(HTTPMessage::ChunkCache& chunk_buffers);
/**
* compute and sets a HTTP Message data integrity status
* @param http_msg target HTTP message
* @param msg_parsed_ok message parsing result
*/
static void computeMsgStatus(HTTPMessage& http_msg, bool msg_parsed_ok);
/**
* sets an error code
*
* @param ec error code variable to define
* @param ev error value to raise
*/
static inline void setError(boost::system::error_code& ec, ErrorValue ev) {
ec = boost::system::error_code(static_cast<int>(ev), getErrorCategory());
}
/// creates the unique HTTPParser ErrorCategory
static void createErrorCategory(void);
// misc functions used by the parsing functions
inline static bool isChar(int c);
inline static bool isControl(int c);
inline static bool isSpecial(int c);
inline static bool isDigit(int c);
inline static bool isHexDigit(int c);
inline static bool isCookieAttribute(const std::string& name, bool set_cookie_header);
/// maximum length for response status message
static const boost::uint32_t STATUS_MESSAGE_MAX;
/// maximum length for the request method
static const boost::uint32_t METHOD_MAX;
/// maximum length for the resource requested
static const boost::uint32_t RESOURCE_MAX;
/// maximum length for the query string
static const boost::uint32_t QUERY_STRING_MAX;
/// maximum length for an HTTP header name
static const boost::uint32_t HEADER_NAME_MAX;
/// maximum length for an HTTP header value
static const boost::uint32_t HEADER_VALUE_MAX;
/// maximum length for the name of a query string variable
static const boost::uint32_t QUERY_NAME_MAX;
/// maximum length for the value of a query string variable
static const boost::uint32_t QUERY_VALUE_MAX;
/// maximum length for the name of a cookie name
static const boost::uint32_t COOKIE_NAME_MAX;
/// maximum length for the value of a cookie; also used for path and domain
static const boost::uint32_t COOKIE_VALUE_MAX;
/// primary logging interface used by this class
mutable PionLogger m_logger;
/// true if the message is an HTTP request; false if it is an HTTP response
const bool m_is_request;
/// points to the next character to be consumed in the read_buffer
const char * m_read_ptr;
/// points to the end of the read_buffer (last byte + 1)
const char * m_read_end_ptr;
private:
/// state used to keep track of where we are in parsing the HTTP message
enum MessageParseState {
PARSE_START, PARSE_HEADERS, PARSE_CONTENT,
PARSE_CONTENT_NO_LENGTH, PARSE_CHUNKS, PARSE_END
};
/// state used to keep track of where we are in parsing the HTTP headers
/// (only used if MessageParseState == PARSE_HEADERS)
enum HeadersParseState {
PARSE_METHOD_START, PARSE_METHOD, PARSE_URI_STEM, PARSE_URI_QUERY,
PARSE_HTTP_VERSION_H, PARSE_HTTP_VERSION_T_1, PARSE_HTTP_VERSION_T_2,
PARSE_HTTP_VERSION_P, PARSE_HTTP_VERSION_SLASH,
PARSE_HTTP_VERSION_MAJOR_START, PARSE_HTTP_VERSION_MAJOR,
PARSE_HTTP_VERSION_MINOR_START, PARSE_HTTP_VERSION_MINOR,
PARSE_STATUS_CODE_START, PARSE_STATUS_CODE, PARSE_STATUS_MESSAGE,
PARSE_EXPECTING_NEWLINE, PARSE_EXPECTING_CR,
PARSE_HEADER_WHITESPACE, PARSE_HEADER_START, PARSE_HEADER_NAME,
PARSE_SPACE_BEFORE_HEADER_VALUE, PARSE_HEADER_VALUE,
PARSE_EXPECTING_FINAL_NEWLINE, PARSE_EXPECTING_FINAL_CR
};
/// state used to keep track of where we are in parsing chunked content
/// (only used if MessageParseState == PARSE_CHUNKS)
enum ChunkedContentParseState {
PARSE_CHUNK_SIZE_START, PARSE_CHUNK_SIZE,
PARSE_EXPECTING_CR_AFTER_CHUNK_SIZE,
PARSE_EXPECTING_LF_AFTER_CHUNK_SIZE, PARSE_CHUNK,
PARSE_EXPECTING_CR_AFTER_CHUNK, PARSE_EXPECTING_LF_AFTER_CHUNK,
PARSE_EXPECTING_FINAL_CR_AFTER_LAST_CHUNK,
PARSE_EXPECTING_FINAL_LF_AFTER_LAST_CHUNK
};
/// the current state of parsing HTTP headers
MessageParseState m_message_parse_state;
/// the current state of parsing HTTP headers
HeadersParseState m_headers_parse_state;
/// the current state of parsing chunked content
ChunkedContentParseState m_chunked_content_parse_state;
/// Used for parsing the HTTP response status code
boost::uint16_t m_status_code;
/// Used for parsing the HTTP response status message
std::string m_status_message;
/// Used for parsing the request method
std::string m_method;
/// Used for parsing the name of resource requested
std::string m_resource;
/// Used for parsing the query string portion of a URI
std::string m_query_string;
/// Used to store the raw contents of HTTP headers when m_save_raw_headers is true
std::string m_raw_headers;
/// Used for parsing the name of HTTP headers
std::string m_header_name;
/// Used for parsing the value of HTTP headers
std::string m_header_value;
/// Used for parsing the chunk size
std::string m_chunk_size_str;
/// number of bytes in the chunk currently being parsed
std::size_t m_size_of_current_chunk;
/// number of bytes read so far in the chunk currently being parsed
std::size_t m_bytes_read_in_current_chunk;
/// number of payload content bytes that have not yet been read
std::size_t m_bytes_content_remaining;
/// number of bytes read so far into the message's payload content
std::size_t m_bytes_content_read;
/// number of bytes read during last parse operation
std::size_t m_bytes_last_read;
/// total number of bytes read while parsing the HTTP message
std::size_t m_bytes_total_read;
/// maximum length for HTTP payload content
std::size_t m_max_content_length;
/// if true, then only HTTP headers will be parsed (no content parsing)
bool m_parse_headers_only;
/// if true, the raw contents of HTTP headers are stored into m_raw_headers
bool m_save_raw_headers;
/// points to a single and unique instance of the HTTPParser ErrorCategory
static ErrorCategory * m_error_category_ptr;
/// used to ensure thread safety of the HTTPParser ErrorCategory
static boost::once_flag m_instance_flag;
};
// inline functions for HTTPParser
inline bool HTTPParser::isChar(int c)
{
return(c >= 0 && c <= 127);
}
inline bool HTTPParser::isControl(int c)
{
return( (c >= 0 && c <= 31) || c == 127);
}
inline bool HTTPParser::isSpecial(int c)
{
switch (c) {
case '(': case ')': case '<': case '>': case '@':
case ',': case ';': case ':': case '\\': case '"':
case '/': case '[': case ']': case '?': case '=':
case '{': case '}': case ' ': case '\t':
return true;
default:
return false;
}
}
inline bool HTTPParser::isDigit(int c)
{
return(c >= '0' && c <= '9');
}
inline bool HTTPParser::isHexDigit(int c)
{
return((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
}
inline bool HTTPParser::isCookieAttribute(const std::string& name, bool set_cookie_header)
{
return (name.empty() || name[0] == '$' || (set_cookie_header &&
(name=="Comment" || name=="Domain" || name=="Max-Age" || name=="Path" || name=="Secure" || name=="Version" || name=="Expires")
) );
}
} // end namespace net
} // end namespace pion
#endif
|