00001 /** 00002 Licensed to the Apache Software Foundation (ASF) under one 00003 or more contributor license agreements. See the NOTICE file 00004 distributed with this work for additional information 00005 regarding copyright ownership. The ASF licenses this file 00006 to you under the Apache License, Version 2.0 (the 00007 "License"); you may not use this file except in compliance 00008 with the License. You may obtain a copy of the License at 00009 00010 http://www.apache.org/licenses/LICENSE-2.0 00011 00012 Unless required by applicable law or agreed to in writing, software 00013 distributed under the License is distributed on an "AS IS" BASIS, 00014 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 See the License for the specific language governing permissions and 00016 limitations under the License. 00017 */ 00018 00019 /** 00020 * @file Headers.h 00021 */ 00022 00023 #pragma once 00024 #ifndef ATSCPPAPI_HEADERS_H_ 00025 #define ATSCPPAPI_HEADERS_H_ 00026 00027 #include <atscppapi/noncopyable.h> 00028 #include <string> 00029 00030 namespace atscppapi { 00031 00032 struct HeadersState; 00033 struct HeaderFieldIteratorState; 00034 struct HeaderFieldValueIteratorState; 00035 class Request; 00036 class ClientRequest; 00037 class Response; 00038 00039 /** 00040 * @brief A HeaderFieldName is a lightweight wrapper around a string that allows for case insensitive comparisons. 00041 * Because header field names must be case insensitive this allows easy case insentive comparisons of names. 00042 * 00043 */ 00044 class HeaderFieldName { 00045 private: 00046 std::string name_; 00047 public: 00048 typedef std::string::size_type size_type; 00049 00050 /** 00051 * Constructor: build a new HeaderField name with the given string 00052 */ 00053 HeaderFieldName(const std::string &name); 00054 00055 /** 00056 * std::string conversion 00057 * @return a string which is this HeaderFieldName 00058 */ 00059 operator std::string(); 00060 00061 /** 00062 * const char * conversion 00063 * @return a const char * which is this HeaderFieldName 00064 */ 00065 operator const char*(); 00066 00067 /** 00068 * @return the length of this HeaderFieldName 00069 */ 00070 size_type length(); 00071 00072 /** 00073 * @return a string which is this HeaderFieldName 00074 */ 00075 std::string str(); 00076 00077 /** 00078 * @return a const char * which points to the name of this HeaderFIeldName 00079 */ 00080 const char *c_str(); 00081 00082 /** 00083 * Case insensitive comparison of this HeaderFieldName 00084 * @return true if the two strings are equal. 00085 */ 00086 bool operator==(const char *field_name); 00087 00088 /** 00089 * Case insensitive comparison of this HeaderFieldName 00090 * @return true if the two strings are equal. 00091 */ 00092 bool operator==(const std::string &field_name); 00093 00094 /** 00095 * Case insensitive comparison of this HeaderFieldName 00096 * @return true if the two strings are not equal. 00097 */ 00098 bool operator!=(const char *field_name); 00099 00100 /** 00101 * Case insensitive comparison of this HeaderFieldName 00102 * @return true if the two strings are not equal. 00103 */ 00104 bool operator!=(const std::string &field_name); 00105 }; 00106 00107 class HeaderField; 00108 00109 /** 00110 * @brief A header field value iterator iterates through all header fields. 00111 */ 00112 class header_field_value_iterator : public std::iterator<std::forward_iterator_tag, int> 00113 { 00114 private: 00115 HeaderFieldValueIteratorState *state_; 00116 public: 00117 /** 00118 * Constructor for header_field_value_iterator, this shouldn't need to be used directly. 00119 * @param bufp the TSMBuffer associated with the headers 00120 * @param mloc the TSMLoc associated with the headers. 00121 * @param field_loc the TSMLoc assocated with the field. 00122 * @param index the index of the value in the HeaderField 00123 * @warning This shouldn't need to be used directly! 00124 */ 00125 header_field_value_iterator(void *bufp, void *hdr_loc, void *field_loc, int index); 00126 00127 /** 00128 * Copy Constructor for header_field_value_iterator, this shouldn't need to be used directly. 00129 * @param header_field_value_iterator an existing iterator to copy 00130 * @warning This shouldn't need to be used directly! 00131 */ 00132 header_field_value_iterator(const header_field_value_iterator& it); 00133 ~header_field_value_iterator(); 00134 00135 /** 00136 * Dereference this iterator into a string (get the value pointed to by this iterator) 00137 * @return a string which is the value pointed to by this iterator 00138 */ 00139 std::string operator*(); 00140 00141 /** 00142 * Advance the iterator to the next header field value 00143 * @return a reference to a the next iterator 00144 */ 00145 header_field_value_iterator& operator++(); 00146 00147 /** 00148 * Advance the current iterator to the next header field 00149 * @return a new iterator which points to the next element 00150 */ 00151 header_field_value_iterator operator++(int); 00152 00153 /** 00154 * Compare two iterators returning true if they are equal 00155 * @return true if two iterators are equal 00156 */ 00157 bool operator==(const header_field_value_iterator& rhs) const; 00158 00159 /** 00160 * Compare two iterators returning true if they are NOT equal 00161 * @return true if two iterators are not equal. 00162 */ 00163 bool operator!=(const header_field_value_iterator& rhs) const; 00164 00165 friend class HeaderField; 00166 }; 00167 00168 /** 00169 * @brief A header field iterator is an iterator that dereferences to a HeaderField. 00170 */ 00171 class header_field_iterator : public std::iterator<std::forward_iterator_tag, int> 00172 { 00173 private: 00174 HeaderFieldIteratorState *state_; 00175 header_field_iterator(void *hdr_buf, void *hdr_loc, void *field_loc); 00176 public: 00177 ~header_field_iterator(); 00178 00179 /** 00180 * Copy Constructor for header_field_iterator, this shouldn't need to be used directly. 00181 * @param header_field_iterator: for constructing the iterator. 00182 * @warning This shouldn't need to be used directly! 00183 */ 00184 header_field_iterator(const header_field_iterator& it); 00185 00186 header_field_iterator &operator=(const header_field_iterator &rhs); 00187 00188 /** 00189 * Advance the iterator to the next header field 00190 * @return a reference to a the next iterator 00191 */ 00192 header_field_iterator& operator++(); 00193 00194 /** 00195 * Advance the current iterator to the next header field 00196 * @return a new iterator which points to the next element 00197 */ 00198 header_field_iterator operator++(int); 00199 00200 /** 00201 * Advance the iterator to the next header field with the same name 00202 * @return a reference to a the next iterator 00203 */ 00204 header_field_iterator& nextDup(); 00205 00206 /** 00207 * Comparison operator, compare two iterators 00208 * @return true if the two iterators point to the same HeaderField 00209 */ 00210 bool operator==(const header_field_iterator& rhs) const; 00211 00212 /** 00213 * Inequality Operator, compare two iterators 00214 * @return false if the two iterators are the same. 00215 */ 00216 bool operator!=(const header_field_iterator& rhs) const; 00217 00218 /** 00219 * Dereference an iterator 00220 * @return a HeaderField pointed to by this iterator 00221 */ 00222 HeaderField operator*(); 00223 00224 friend class HeaderField; 00225 friend class Headers; 00226 }; 00227 00228 /** 00229 * @brief A HeaderField is a class that contains the header field name and all of the values. 00230 * @note You may have several HeaderFields with the same name for a given set of Headers. 00231 */ 00232 class HeaderField { 00233 private: 00234 header_field_iterator iter_; 00235 HeaderField(header_field_iterator iter) : iter_(iter) { } 00236 00237 public: 00238 typedef unsigned int size_type; 00239 typedef header_field_value_iterator iterator; 00240 00241 ~HeaderField(); 00242 00243 /** 00244 * Get the size of the HeaderField, this is the number of values associated with the header field. 00245 * @return the number of values in this HeaderField. 00246 */ 00247 size_type size() const; 00248 00249 /** 00250 * Returns an iterator to the start of the values 00251 * @return an iterator point to the start of this header field's values 00252 */ 00253 iterator begin(); 00254 00255 /** 00256 * Returns an iterator to the end of this header field's values. 00257 * @return an iterator that points beyond the last element of the header field's values. 00258 */ 00259 iterator end(); 00260 00261 /** 00262 * Get the name of this HeaderField 00263 * @return a HeaderFieldName object. 00264 * @see HeaderFieldName which is a thin wrapper around a string to allow for case insensitive comparisons. 00265 */ 00266 HeaderFieldName name() const; 00267 00268 /** 00269 * Join all the values of this HeaderField into a single string seperated by the join string. 00270 * @param an optional join string (defaults to ",") 00271 * @return a string which is all of the joined values of this HeaderField 00272 */ 00273 std::string values(const char *join = ","); 00274 00275 /** 00276 * Join all the values of this HeaderField into a single string seperated by the join string. 00277 * @param a join string 00278 * @return a string which is all of the joined values of this HeaderField 00279 */ 00280 std::string values(const std::string &join); 00281 00282 /** 00283 * Join all the values of this HeaderField into a single string seperated by the join string. 00284 * @param a optional join character 00285 * @return a string which is all of the joined values of this HeaderField 00286 */ 00287 std::string values(const char join); 00288 00289 /** 00290 * Check if this HeaderField is empty (no values). 00291 * @return a boolean value representing whether or not the header field has values. 00292 */ 00293 bool empty(); 00294 00295 /** 00296 * Remove all values from this HeaderField 00297 * @return true if the clear succeeds. 00298 */ 00299 bool clear(); 00300 00301 /** 00302 * Remove a single value from this HeaderField which is pointed to by the given iterator 00303 * @param an iterator which points to a single HeaderField value. 00304 * @return true if the header value was successfully erased. 00305 */ 00306 bool erase(iterator it); 00307 00308 /** 00309 * Append a value or a seperated list of values to this HeaderField 00310 * @param a string containing the value(s). 00311 * @return true if the values was appended. 00312 */ 00313 bool append(const std::string &value); 00314 00315 /** 00316 * Append a value or a seperated list of values to this HeaderField 00317 * @param a string containing the value. 00318 * @param the length of the value that is being appended. 00319 * @return true if the values was appended. 00320 */ 00321 bool append(const char *value, int length = -1); 00322 00323 /** 00324 * Change the name of this HeaderField to the given key. 00325 * @param string - the new name of the header field 00326 * @return true if the header field name was successfully changed. 00327 */ 00328 bool setName(const std::string &str); 00329 00330 /** 00331 * Compares the name of the header field only (not the values). 00332 * @note This is a case insensitive comparison. 00333 * @return true if the name is equal (case insensitive comparison). 00334 */ 00335 bool operator==(const char *field_name) const; 00336 00337 /** Compares the name of the header field only (not the values). 00338 * @note This is a case insensitive comparison. 00339 * @return true if the name is equal (case insensitive comparison). 00340 */ 00341 bool operator==(const std::string &field_name) const; 00342 00343 /** Compares the name of the header field only (not the values). 00344 * @note This is a case insensitive comparison. 00345 * @return true if the name is NOT equal (case insensitive comparison). 00346 */ 00347 bool operator!=(const char *field_name) const; 00348 00349 /** Compares the name of the header field only (not the values). 00350 * @note This is a case insensitive comparison. 00351 * @return true if the name is NOT equal (case insensitive comparison). 00352 */ 00353 bool operator!=(const std::string &field_name) const ; 00354 00355 /** 00356 * Set the VALUES of the header field to the given value string 00357 * @param string - the values to set on the current header field 00358 * @return true if the value is sucessfully changed. 00359 */ 00360 bool operator=(const std::string &field_value); 00361 00362 /** 00363 * Set the VALUES of the header field to the given value string 00364 * @param the values to set on the current header field 00365 * @return true if the value is sucessfully changed. 00366 */ 00367 bool operator=(const char *field_value); 00368 00369 /** 00370 * Get the index value from this HeaderField 00371 * @param the index to retrieve a copy of 00372 * @return a copy of the string which is the index^th value in this HeaderField 00373 * @note as currently written this returns an immutable string, it will NOT allow you to 00374 * change the value. 00375 */ 00376 std::string operator[](const int index); 00377 00378 /** 00379 * Get a string representing all the header field's values 00380 * @return a string representation of all the header fields 00381 */ 00382 friend std::ostream& operator<<(std::ostream& os, HeaderField& obj); 00383 00384 /** 00385 * Get a string representing all the header field's values. 00386 * @return a string representation of all the header fields 00387 */ 00388 std::string str(); 00389 friend class Headers; 00390 friend class header_field_iterator; 00391 }; 00392 00393 /** 00394 * @brief Encapsulates the headers portion of a request or response. 00395 */ 00396 class Headers: noncopyable { 00397 public: 00398 /** 00399 * Constructor for Headers. This creates a "detached" headers, i.e., not tied to any transaction. 00400 */ 00401 Headers(); 00402 00403 /** 00404 * Constructor for Headers, this shouldn't be used directly unless you're trying to mix the C++ and C apis. 00405 * @param bufp the TSMBuffer associated with the headers 00406 * @param mloc the TSMLoc associated with the headers. 00407 * @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. 00408 */ 00409 Headers(void *bufp, void *mloc); 00410 00411 /** 00412 * Context Values are a way to share data between plugins, the key is always a string 00413 * and the value can be a shared_ptr to any type that extends ContextValue. 00414 * @param bufp the TSMBuffer associated with the headers 00415 * @param mloc the TSMLoc associated with the headers. 00416 * @warning This should only be used if you're mixing the C++ and C apis. 00417 */ 00418 void reset(void *bufp, void *mloc); 00419 00420 /** 00421 * Check if the header class has been initialized. If you're only using the C++ api then this 00422 * should always return true. 00423 * @return a boolean value representing whether or not the Headers have been initialized.. 00424 */ 00425 bool isInitialized() const; 00426 00427 typedef unsigned int size_type; 00428 typedef header_field_iterator iterator; 00429 00430 /** 00431 * Check if the headers are empty 00432 * @return a boolean value representing whether or not the Headers are empty 00433 */ 00434 bool empty(); 00435 00436 /** 00437 * Get the size of the headers (the number of HeaderFields). 00438 * @return the number of HeaderFields 00439 */ 00440 size_type size() const; 00441 00442 /** 00443 * Get the size of the headers (the number of HeaderFields). 00444 * @return the number of HeaderFields 00445 */ 00446 size_type lengthBytes() const; 00447 00448 /** 00449 * Returns an iterator to the start of the HeaderFields. 00450 * @return an iterator point to the start of the header fields. 00451 */ 00452 iterator begin(); 00453 00454 /** 00455 * Returns an iterator to the end of the HeaderFields (beyond the last element). 00456 * @return an iterator that points beyond the last element in the header fields. 00457 */ 00458 iterator end(); 00459 00460 /** 00461 * Clears all headers. 00462 * @return true if the headers were succesfully cleared. 00463 */ 00464 bool clear(); 00465 00466 /** 00467 * Erase a single header field pointed to by an iterator 00468 * @param an iterator pointing to a header field. 00469 * @return true if the header field pointed to by the iterator was erased. 00470 */ 00471 bool erase(iterator it); 00472 00473 /** 00474 * Erase all headers whose name matches key (this is a case insensitive match). 00475 * @param the name of the header fields to erase 00476 * @return the number of elements erased that matched the key 00477 */ 00478 size_type erase(const std::string &key); 00479 00480 /** 00481 * Erase all headers whose name matches key (this is a case insensitive match). 00482 * @param the name of the header fields to erase 00483 * @param the length of the key (optional). 00484 * @return the number of elements erased that matched the key 00485 */ 00486 size_type erase(const char *key, int length = -1); 00487 00488 /** 00489 * Count all headers whose name matches key (this is a case insensitive match). 00490 * @param the name of the header fields to erase 00491 * @param the length of the key (optional). 00492 * @return the number of elements erased that matched the key 00493 */ 00494 size_type count(const char *key, int length = -1); 00495 00496 /** 00497 * Count all headers whose name matches key (this is a case insensitive match). 00498 * @param the name of the header fields to count 00499 * @return the number of elements whose name is key. 00500 */ 00501 size_type count(const std::string &key); 00502 00503 /** 00504 * Join all headers whos name is key with the optionally specified join string 00505 * @param the name of the headers to join into a single string 00506 * @param an optional join string (defaults to ",") 00507 * @return a string which is all of the joined values of headers matching key. 00508 */ 00509 std::string values(const std::string &key, const char *join = ","); 00510 00511 /** 00512 * Join all headers whos name is key with the optionally specified join string 00513 * @param the name of the headers to join into a single string 00514 * @param the string to join the fields with 00515 * @return a string which is all of the joined values of headers matching key. 00516 */ 00517 std::string values(const std::string &key, const std::string &join); 00518 00519 /** 00520 * Join all headers whos name is key with the optionally specified join character 00521 * @param the name of the headers to join into a single string 00522 * @param the join character. 00523 * @return a string which is all of the joined values of headers matching key. 00524 */ 00525 std::string values(const std::string &key, const char join); 00526 00527 /** 00528 * Returns the value at given position of header with given name 00529 * @param name of header 00530 * @param position of value 00531 * @return value 00532 */ 00533 std::string value(const std::string key, size_type index = 0); 00534 00535 /** 00536 * Returns an iterator to the first HeaderField with the name key. 00537 * @param key the name of first header field ot find. 00538 * @return an iterator that points to the first matching header field with name key. 00539 */ 00540 iterator find(const std::string &key); 00541 00542 /** 00543 * Returns an iterator to the first HeaderField with the name key. 00544 * @param key the name of first header field ot find. 00545 * @param the length of the key specified (optional). 00546 * @return an iterator that points to the first matching header field with name key. 00547 */ 00548 iterator find(const char *key, int length = -1); 00549 00550 /** 00551 * Append a HeaderField. 00552 * @param key the name of the header field to append 00553 * @param value the value of the header field to append 00554 * @return an iterator to the appended header field or the end() iterator if append fails. 00555 */ 00556 iterator append(const std::string &key, const std::string &value); 00557 00558 /** 00559 * Erase all headers with name specified by key and then re-create the header with the specified values. 00560 * @param key the name of the header field to erased and re-created. 00561 * @param value the value of the header field to set. 00562 * @return an iterator to the new header field or the end() iterator if append fails. 00563 */ 00564 iterator set(const std::string &key, const std::string &value); 00565 00566 /** 00567 * Set the header field values to the value given, the header field will be created 00568 * if it does not already exist. 00569 * @param key the name of the header field whose value to set. 00570 * @return an iterator to the new header field or the end() iterator if append fails. 00571 * @warning This will create a header field with the given name, thus it should not be 00572 * used to check for the existance of a header, use count() or find() instead. 00573 */ 00574 HeaderField operator[](const std::string &key); 00575 00576 /** 00577 * Get a human-readable/log-friendly string representing all the header fields. 00578 * @return a string representation of all the header fields 00579 */ 00580 std::string str(); 00581 00582 /** 00583 * Get a string that can be put on the wire 00584 * @return a string representation of all the header fields 00585 */ 00586 std::string wireStr(); 00587 00588 friend std::ostream& operator<<(std::ostream &os, Headers &obj); 00589 00590 ~Headers(); 00591 private: 00592 HeadersState *state_; 00593 friend class Request; 00594 friend class ClientRequest; 00595 friend class Response; 00596 }; 00597 00598 } 00599 00600 #endif