Updated Branches: refs/heads/master b984db31f -> 83d43ab13
http://git-wip-us.apache.org/repos/asf/trafficserver/blob/83d43ab1/lib/atscppapi/src/include/atscppapi/Headers.h ---------------------------------------------------------------------- diff --git a/lib/atscppapi/src/include/atscppapi/Headers.h b/lib/atscppapi/src/include/atscppapi/Headers.h index af02707..c83c5c8 100644 --- a/lib/atscppapi/src/include/atscppapi/Headers.h +++ b/lib/atscppapi/src/include/atscppapi/Headers.h @@ -24,218 +24,580 @@ #ifndef ATSCPPAPI_HEADERS_H_ #define ATSCPPAPI_HEADERS_H_ -#include <map> -#include <list> -#include <atscppapi/CaseInsensitiveStringComparator.h> #include <atscppapi/noncopyable.h> +#include <string> namespace atscppapi { struct HeadersState; +struct HeaderFieldIteratorState; +struct HeaderFieldState; +struct HeaderFieldValueIteratorState; class Request; class ClientRequest; class Response; /** - * @brief Encapsulates the headers portion of a request or response. + * @brief A HeaderFieldName is a lightweight wrapper around a string that allows for case insensitive comparisons. + * Because header field names must be case insensitive this allows easy case insentive comparisons of names. + * */ -class Headers: noncopyable { +class HeaderFieldName { + private: + std::string name_; + public: + typedef std::string::size_type size_type; + + /** + * Constructor: build a new HeaderField name with the given string + */ + HeaderFieldName(const std::string &name); + + /** + * std::string conversion + * @return a string which is this HeaderFieldName + */ + operator std::string(); + + /** + * const char * conversion + * @return a const char * which is this HeaderFieldName + */ + operator const char*(); + + /** + * @return the length of this HeaderFieldName + */ + size_type length(); + + /** + * @return a string which is this HeaderFieldName + */ + std::string str(); + + /** + * @return a const char * which points to the name of this HeaderFIeldName + */ + const char *c_str(); + + /** + * Case insensitive comparison of this HeaderFieldName + * @return true if the two strings are equal. + */ + bool operator==(const char *field_name); + + /** + * Case insensitive comparison of this HeaderFieldName + * @return true if the two strings are equal. + */ + bool operator==(const std::string &field_name); + + /** + * Case insensitive comparison of this HeaderFieldName + * @return true if the two strings are not equal. + */ + bool operator!=(const char *field_name); + + /** + * Case insensitive comparison of this HeaderFieldName + * @return true if the two strings are not equal. + */ + bool operator!=(const std::string &field_name); +}; + +class HeaderField; + +/** + * @brief A header field value iterator iterates through all header fields. + */ +class header_field_value_iterator : public std::iterator<std::forward_iterator_tag, int> +{ + private: + HeaderFieldValueIteratorState *state_; + public: + /** + * Constructor for header_field_value_iterator, this shouldn't need to be used directly. + * @param bufp the TSMBuffer associated with the headers + * @param mloc the TSMLoc associated with the headers. + * @param field_loc the TSMLoc assocated with the field. + * @param index the index of the value in the HeaderField + * @warning This shouldn't need to be used directly! + */ + header_field_value_iterator(void *bufp, void *hdr_loc, void *field_loc, int index); + + /** + * Copy Constructor for header_field_value_iterator, this shouldn't need to be used directly. + * @param header_field_value_iterator an existing iterator to copy + * @warning This shouldn't need to be used directly! + */ + header_field_value_iterator(const header_field_value_iterator& it); + ~header_field_value_iterator(); + + /** + * Dereference this iterator into a string (get the value pointed to by this iterator) + * @return a string which is the value pointed to by this iterator + */ + std::string operator*(); + + /** + * Advance the iterator to the next header field value + * @return a reference to a the next iterator + */ + header_field_value_iterator& operator++(); + + /** + * Advance the current iterator to the next header field + * @return a new iterator which points to the next element + */ + header_field_value_iterator operator++(int); + + /** + * Compare two iterators returning true if they are equal + * @return true if two iterators are equal + */ + bool operator==(const header_field_value_iterator& rhs) const; + + /** + * Compare two iterators returning true if they are NOT equal + * @return true if two iterators are not equal. + */ + bool operator!=(const header_field_value_iterator& rhs) const; + + friend class HeaderField; +}; +class header_field_iterator; + +/** + * @brief A HeaderField is a class that contains the header field name and all of the values. + * @note You may have several HeaderFields with the same name for a given set of Headers. + */ +class HeaderField { +private: + HeaderFieldState *state_; public: - - enum Type { TYPE_REQUEST, TYPE_RESPONSE }; + typedef unsigned int size_type; + typedef header_field_value_iterator iterator; - Headers(Type type = TYPE_REQUEST); + /** + * Constructor for HeaderField, this shouldn't be used directly unless you're trying to mix the C++ and C apis. + * @param bufp the TSMBuffer associated with the header field + * @param mloc the TSMLoc associated with the headers + * @param field_loc the TSMLoc associated with the header field + * @warning This should only be used if you're mixing the C++ and C apis, it will be constructed automatically if using only the C++ api. + */ + HeaderField(void *bufp, void *hdr_loc, void *field_loc); + ~HeaderField(); - Type getType() const; + /** + * Get the size of the HeaderField, this is the number of values associated with the header field. + * @return the number of values in this HeaderField. + */ + size_type size() const; - typedef std::map<std::string, std::list<std::string>, CaseInsensitiveStringComparator> NameValuesMap; + /** + * Returns an iterator to the start of the values + * @return an iterator point to the start of this header field's values + */ + iterator begin(); - typedef NameValuesMap::size_type size_type; - typedef NameValuesMap::const_iterator const_iterator; - typedef NameValuesMap::const_reverse_iterator const_reverse_iterator; + /** + * Returns an iterator to the end of this header field's values. + * @return an iterator that points beyond the last element of the header field's values. + */ + iterator end(); /** - * @return Iterator to first header. + * Get the name of this HeaderField + * @return a HeaderFieldName object. + * @see HeaderFieldName which is a thin wrapper around a string to allow for case insensitive comparisons. */ - const_iterator begin() const; + HeaderFieldName name() const; /** - * @return Iterator to end of headers. - */ - const_iterator end() const; + * Join all the values of this HeaderField into a single string seperated by the join string. + * @param an optional join string (defaults to ",") + * @return a string which is all of the joined values of this HeaderField + */ + std::string values(const char *join = ","); /** - * @return Iterator to last header. - */ - const_reverse_iterator rbegin() const; + * Join all the values of this HeaderField into a single string seperated by the join string. + * @param a join string + * @return a string which is all of the joined values of this HeaderField + */ + std::string values(const std::string &join); /** - * @return Iterator to "reverse end" - */ - const_reverse_iterator rend() const; + * Join all the values of this HeaderField into a single string seperated by the join string. + * @param a optional join character + * @return a string which is all of the joined values of this HeaderField + */ + std::string values(const char join); /** - * @param key Name of header - * @return Iterator to header if exists, else end() - */ - const_iterator find(const std::string &key) const; + * Check if this HeaderField is empty (no values). + * @return a boolean value representing whether or not the header field has values. + */ + bool empty(); /** - * @param key Name of header - * @return 1 if header exists, 0 if not. + * Remove all values from this HeaderField + * @return true if the clear succeeeds. */ - size_type count(const std::string &key) const; + bool clear(); /** - * Erases header with given name. - * - * @param key Name of header - * @return 1 if header was erased, 0 if not. + * Remove a single value from this HeaderField which is pointed to by the given iterator + * @param an iterator which points to a single HeaderField value. + * @return true if the header value was successfully erased. */ - size_type erase(const std::string &key); + bool erase(iterator it); /** - * Sets the given header and values. If a header of same name existed, that is - * deleted. Else header is appended. - * - * @param pair Contains the name and list of values. - * - * @return Iterator to header set. + * Append a value or a seperated list of values to this HeaderField + * @param a string containing the value(s). + * @return true if the values was appended. */ - const_iterator set(const std::pair<std::string, std::list<std::string> > &pair); + bool append(const std::string &value); /** - * Sets the given header and values. If a header of same name existed, that is - * deleted. Else header is appended. - * - * @param key Name of header - * @param val List of values - * - * @return Iterator to header set. + * Append a value or a seperated list of values to this HeaderField + * @param a string containing the value. + * @param the length of the value that is being appended. + * @return true if the values was appended. */ - const_iterator set(const std::string &key, const std::list<std::string> &val); + bool append(const char *value, int length = -1); /** - * Sets the given header and values. If a header of same name existed, that is - * deleted. Else header is appended. - * - * @param key Name of header - * @param val Value - * - * @return Iterator to header set. + * Change the name of this HeaderField to the given key. + * @param string - the new name of the header field + * @return true if the header field name was successfully changed. */ - const_iterator set(const std::string &key, const std::string &val); + bool setName(const std::string &str); /** - * Appends a new header. If a header of the same name exists, value(s) is tacked - * on that the end of current value(s). - * - * @param pair Contains the name and list of values. - * - * @return Iterator to header appended. + * Compares the name of the header field only (not the values). + * @note This is a case insensitive comparison. + * @return true if the name is equal (case insensitive comparison). */ - const_iterator append(const std::pair<std::string, std::list<std::string> > &pair); + bool operator==(const char *field_name) const; - /** - * Appends a new header. If a header of the same name exists, value(s) is tacked - * on that the end of current value(s). - * - * @param key Name of header - * @param val List of values - * - * @return Iterator to header appended. + /** Compares the name of the header field only (not the values). + * @note This is a case insensitive comparison. + * @return true if the name is equal (case insensitive comparison). */ - const_iterator append(const std::string &key, const std::list<std::string> &val); + bool operator==(const std::string &field_name) const; - /** - * Appends a new header. If a header of the same name exists, value(s) is tacked - * on that the end of current value(s). - * - * @param key Name of header - * @param val Value - * - * @return Iterator to header appended. + /** Compares the name of the header field only (not the values). + * @note This is a case insensitive comparison. + * @return true if the name is NOT equal (case insensitive comparison). */ - const_iterator append(const std::string &key, const std::string &val); + bool operator!=(const char *field_name) const; - /** - * Joins provided list of values with delimiter (defaulting to ','). - * - * @return Composite string + /** Compares the name of the header field only (not the values). + * @note This is a case insensitive comparison. + * @return true if the name is NOT equal (case insensitive comparison). */ - static std::string getJoinedValues(const std::list<std::string> &values, char delimiter = ','); + bool operator!=(const std::string &field_name) const ; /** - * Joins values of provided header with delimiter (defaulting to ','). - * - * @return Composite string if header exists, else empty strings. + * Set the VALUES of the header field to the given value string + * @param string - the values to set on the current header field + * @return true if the value is sucessfully changed. */ - std::string getJoinedValues(const std::string &key, char value_delimiter = ','); + bool operator=(const std::string &field_value); /** - * @return True if there are no headers. + * Set the VALUES of the header field to the given value string + * @param the values to set on the current header field + * @return true if the value is sucessfully changed. */ - bool empty() const; + bool operator=(const char *field_value); /** - * @return Largest possible size of underlying map. + * Get the index value from this HeaderField + * @param the index to retrieve a copy of + * @return a copy of the string which is the index^th value in this HeaderField + * @note as currently written this returns an immutable string, it will NOT allow you to + * change the value. + */ + std::string operator[](const int index); + + /** + * Get a string representing all the header field's values + * @return a string representation of all the header fields + */ + friend std::ostream& operator<<(std::ostream& os, HeaderField& obj); + + /** + * Get a string representing all the header field's values. + * @return a string representation of all the header fields + */ + std::string str(); + friend class Headers; + friend class header_field_iterator; +}; + +/** + * @brief A header field iterator is an iterator that dereferences to a HeaderField. + */ +class header_field_iterator : public std::iterator<std::forward_iterator_tag, int> +{ + private: + HeaderFieldIteratorState *state_; + public: + header_field_iterator(); + ~header_field_iterator(); + + /** + * Constructor for header_field_iterator, this shouldn't need to be used directly. + * @param bufp the TSMBuffer associated with the headers + * @param mloc the TSMLoc associated with the headers. + * @param field_loc the TSMLoc assocated with the field. + * @warning This shouldn't need to be used directly! + */ + header_field_iterator(void *bufp, void *hdr_loc, void *field_loc); + + /** + * Constructor for header_field_iterator, this shouldn't need to be used directly. + * @param HeaderField the header field to use for constructing the iterator. + * @warning This shouldn't need to be used directly! + */ + header_field_iterator(HeaderField &hf); + + /** + * Copy Constructor for header_field_iterator, this shouldn't need to be used directly. + * @param header_field_iterator: for constructing the iterator. + * @warning This shouldn't need to be used directly! + */ + header_field_iterator(const header_field_iterator& it); + + /** + * Advance the iterator to the next header field + * @return a reference to a the next iterator + */ + header_field_iterator& operator++(); + + /** + * Advance the current iterator to the next header field + * @return a new iterator which points to the next element + */ + header_field_iterator operator++(int); + + /** + * Comparison operator, compare two iterators + * @return true if the two iterators point to the same HeaderField + */ + bool operator==(const header_field_iterator& rhs) const; + + /** + * Inequality Operator, compare two iterators + * @return false if the two iterators are the same. + */ + bool operator!=(const header_field_iterator& rhs) const; + + /** + * Dereference an iterator + * @return a HeaderField pointed to by this iterator + */ + HeaderField operator*(); + + /** + * Dereference an iterator + * @return a HeaderField pointed to by this iterator + */ + HeaderField operator()(); + + friend class Headers; +}; + +/** + * @brief Encapsulates the headers portion of a request or response. + */ +class Headers: noncopyable { +public: + /** + * Constructor for Headers, this shouldn't be used directly unless you're trying to mix the C++ and C apis. + * @warning This should only be used if you're mixing the C++ and C apis, it will be constructed automatically if using only the C++ api. */ - size_type max_size() const; + Headers(); /** - * @return Number of headers currently stored. + * Constructor for Headers, this shouldn't be used directly unless you're trying to mix the C++ and C apis. + * @param bufp the TSMBuffer associated with the headers + * @param mloc the TSMLoc associated with the headers. + * @warning This should only be used if you're mixing the C++ and C apis, it will be constructed automatically if using only the C++ api. */ + Headers(void *bufp, void *mloc); + + /** + * Context Values are a way to share data between plugins, the key is always a string + * and the value can be a shared_ptr to any type that extends ContextValue. + * @param bufp the TSMBuffer associated with the headers + * @param mloc the TSMLoc associated with the headers. + * @warning This should only be used if you're mixing the C++ and C apis. + */ + void reset(void *bufp, void *mloc); + + /** + * Check if the header class has been initialized. If you're only using the C++ api then this + * should always return true. + * @return a boolean value representing whether or not the Headers have been initialized.. + */ + bool isInitialized() const; + + typedef unsigned int size_type; + typedef header_field_iterator iterator; + + /** + * Check if the headers are empty + * @return a boolean value representing whether or not the Headers are empty + */ + bool empty(); + + /** + * Get the size of the headers (the number of HeaderFields). + * @return the number of HeaderFields + */ size_type size() const; - typedef std::map<std::string, std::list<std::string> > RequestCookieMap; + /** + * Get the size of the headers (the number of HeaderFields). + * @return the number of HeaderFields + */ + size_type lengthBytes() const; /** - * @return Cookies in the "Cookie" headers of a request object. - */ - const RequestCookieMap &getRequestCookies() const; - - struct ResponseCookie { - std::string name_; - std::string value_; - std::string comment_; - std::string domain_; - int max_age_; - std::string path_; - bool secure_; - int version_; - ResponseCookie() : max_age_(0), secure_(false), version_(0) { }; - }; - - /** - * @return Cookies in the "Set-Cookie" headers of a response object. - */ - const std::list<ResponseCookie> &getResponseCookies() const; + * Returns an iterator to the start of the HeaderFields. + * @return an iterator point to the start of the header fields. + */ + iterator begin(); + + /** + * Returns an iterator to the end of the HeaderFields (beyond the last element). + * @return an iterator that points beyond the last element in the header fields. + */ + iterator end(); + + /** + * Clears all headers. + * @return true if the headers were succesfully cleared. + */ + bool clear(); + + /** + * Erase a single header field pointed to by an iterator + * @param an iterator pointing to a header field. + * @return true if the header field pointed to by the iterator was erased. + */ + bool erase(iterator it); + + /** + * Erase all headers whose name matches key (this is a case insensitive match). + * @param the name of the header fields to erase + * @return the number of elements erased that matched the key + */ + size_type erase(const std::string &key); - /** Adds a request cookie */ - bool addCookie(const std::string &name, const std::string &value); + /** + * Erase all headers whose name matches key (this is a case insensitive match). + * @param the name of the header fields to erase + * @param the length of the key (optional). + * @return the number of elements erased that matched the key + */ + size_type erase(const char *key, int length = -1); + + /** + * Count all headers whose name matches key (this is a case insensitive match). + * @param the name of the header fields to erase + * @param the length of the key (optional). + * @return the number of elements erased that matched the key + */ + size_type count(const char *key, int length = -1); - /** Adds a response cookie */ - bool addCookie(const ResponseCookie &response_cookie); - - /** Sets, i.e., clears current value and adds new value, of a request cookie */ - bool setCookie(const std::string &name, const std::string &value); + /** + * Count all headers whose name matches key (this is a case insensitive match). + * @param the name of the header fields to count + * @return the number of elements whose name is key. + */ + size_type count(const std::string &key); + + /** + * Join all headers whos name is key with the optionally specified join string + * @param the name of the headers to join into a single string + * @param an optional join string (defaults to ",") + * @return a string which is all of the joined values of headers matching key. + */ + std::string values(const std::string &key, const char *join = ","); - /** Sets, i.e., clears current value and adds new value, of a response cookie */ - bool setCookie(const ResponseCookie &response_cookie); + /** + * Join all headers whos name is key with the optionally specified join string + * @param the name of the headers to join into a single string + * @param the string to join the fields with + * @return a string which is all of the joined values of headers matching key. + */ + std::string values(const std::string &key, const std::string &join); + + /** + * Join all headers whos name is key with the optionally specified join character + * @param the name of the headers to join into a single string + * @param the join character. + * @return a string which is all of the joined values of headers matching key. + */ + std::string values(const std::string &key, const char join); + + /** + * Returns an iterator to the first HeaderField with the name key. + * @param key the name of first header field ot find. + * @return an iterator that points to the first matching header field with name key. + */ + iterator find(const std::string &key); + + /** + * Returns an iterator to the first HeaderField with the name key. + * @param key the name of first header field ot find. + * @param the length of the key specified (optional). + * @return an iterator that points to the first matching header field with name key. + */ + iterator find(const char *key, int length = -1); + + /** + * Append a HeaderField. + * @param key the name of the header field to append + * @param value the value of the header field to append + * @return an iterator to the appended header field or the end() iterator if append fails. + */ + iterator append(const std::string &key, const std::string &value); + + /** + * Erase all headers with name specified by key and then re-create the header with the specified values. + * @param key the name of the header field to erased and re-created. + * @param value the value of the header field to set. + * @return an iterator to the new header field or the end() iterator if append fails. + */ + iterator eraseAndSet(const std::string &key, const std::string &value); + + /** + * Set the header field values to the value given, the header field will be created + * if it does not already exist. + * @param key the name of the header field whose value to set. + * @return an iterator to the new header field or the end() iterator if append fails. + * @warning This will create a header field with the given name, thus it should not be + * used to check for the existance of a header, use count() or find() instead. + */ + HeaderField operator[](const std::string &key); + + /** + * Get a string representing all the header fields. + * @return a string representation of all the header fields + */ + std::string str(); - /** Deletes a cookie */ - bool deleteCookie(const std::string &name); + friend std::ostream& operator<<(std::ostream &os, Headers &obj); ~Headers(); private: HeadersState *state_; - bool checkAndInitHeaders() const; - void init(void *hdr_buf, void *hdr_loc); - void initDetached(); - void setType(Type type); - void updateRequestCookieHeaderFromMap(); - const_iterator doBasicAppend(const std::pair<std::string, std::list<std::string> > &pair); - size_type doBasicErase(const std::string &key); friend class Request; friend class ClientRequest; friend class Response;
