• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

HTTP.h

Go to the documentation of this file.
00001 /** @file
00002 
00003   A brief file description
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022  */
00023 
00024 #ifndef __HTTP_H__
00025 #define __HTTP_H__
00026 
00027 
00028 #include <assert.h>
00029 #include "Arena.h"
00030 #include "INK_MD5.h"
00031 #include "MIME.h"
00032 #include "URL.h"
00033 
00034 #include "ink_apidefs.h"
00035 
00036 #define HTTP_VERSION(a,b)  ((((a) & 0xFFFF) << 16) | ((b) & 0xFFFF))
00037 #define HTTP_MINOR(v)      ((v) & 0xFFFF)
00038 #define HTTP_MAJOR(v)      (((v) >> 16) & 0xFFFF)
00039 
00040 
00041 enum HTTPStatus
00042 {
00043   HTTP_STATUS_NONE = 0,
00044 
00045   HTTP_STATUS_CONTINUE = 100,
00046   HTTP_STATUS_SWITCHING_PROTOCOL = 101,
00047 
00048   HTTP_STATUS_OK = 200,
00049   HTTP_STATUS_CREATED = 201,
00050   HTTP_STATUS_ACCEPTED = 202,
00051   HTTP_STATUS_NON_AUTHORITATIVE_INFORMATION = 203,
00052   HTTP_STATUS_NO_CONTENT = 204,
00053   HTTP_STATUS_RESET_CONTENT = 205,
00054   HTTP_STATUS_PARTIAL_CONTENT = 206,
00055 
00056   HTTP_STATUS_MULTIPLE_CHOICES = 300,
00057   HTTP_STATUS_MOVED_PERMANENTLY = 301,
00058   HTTP_STATUS_MOVED_TEMPORARILY = 302,
00059   HTTP_STATUS_SEE_OTHER = 303,
00060   HTTP_STATUS_NOT_MODIFIED = 304,
00061   HTTP_STATUS_USE_PROXY = 305,
00062   HTTP_STATUS_TEMPORARY_REDIRECT = 307,
00063 
00064   HTTP_STATUS_BAD_REQUEST = 400,
00065   HTTP_STATUS_UNAUTHORIZED = 401,
00066   HTTP_STATUS_PAYMENT_REQUIRED = 402,
00067   HTTP_STATUS_FORBIDDEN = 403,
00068   HTTP_STATUS_NOT_FOUND = 404,
00069   HTTP_STATUS_METHOD_NOT_ALLOWED = 405,
00070   HTTP_STATUS_NOT_ACCEPTABLE = 406,
00071   HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED = 407,
00072   HTTP_STATUS_REQUEST_TIMEOUT = 408,
00073   HTTP_STATUS_CONFLICT = 409,
00074   HTTP_STATUS_GONE = 410,
00075   HTTP_STATUS_LENGTH_REQUIRED = 411,
00076   HTTP_STATUS_PRECONDITION_FAILED = 412,
00077   HTTP_STATUS_REQUEST_ENTITY_TOO_LARGE = 413,
00078   HTTP_STATUS_REQUEST_URI_TOO_LONG = 414,
00079   HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE = 415,
00080   HTTP_STATUS_RANGE_NOT_SATISFIABLE = 416,
00081 
00082   HTTP_STATUS_INTERNAL_SERVER_ERROR = 500,
00083   HTTP_STATUS_NOT_IMPLEMENTED = 501,
00084   HTTP_STATUS_BAD_GATEWAY = 502,
00085   HTTP_STATUS_SERVICE_UNAVAILABLE = 503,
00086   HTTP_STATUS_GATEWAY_TIMEOUT = 504,
00087   HTTP_STATUS_HTTPVER_NOT_SUPPORTED = 505
00088 };
00089 
00090 enum HTTPKeepAlive
00091 {
00092   HTTP_KEEPALIVE_UNDEFINED = 0,
00093   HTTP_NO_KEEPALIVE,
00094   HTTP_KEEPALIVE
00095 };
00096 
00097 enum HTTPWarningCode
00098 {
00099   HTTP_WARNING_CODE_NONE = 0,
00100 
00101   HTTP_WARNING_CODE_RESPONSE_STALE = 110,
00102   HTTP_WARNING_CODE_REVALIDATION_FAILED = 111,
00103   HTTP_WARNING_CODE_DISCONNECTED_OPERATION = 112,
00104   HTTP_WARNING_CODE_HERUISTIC_EXPIRATION = 113,
00105   HTTP_WARNING_CODE_TRANSFORMATION_APPLIED = 114,
00106   HTTP_WARNING_CODE_MISC_WARNING = 199
00107 };
00108 
00109 /* squild log codes */
00110 enum SquidLogCode
00111 {
00112   SQUID_LOG_EMPTY = '0',
00113   SQUID_LOG_TCP_HIT = '1',
00114   SQUID_LOG_TCP_DISK_HIT = '2',
00115   SQUID_LOG_TCP_MEM_HIT = '.',  // Don't want to change others codes
00116   SQUID_LOG_TCP_MISS = '3',
00117   SQUID_LOG_TCP_EXPIRED_MISS = '4',
00118   SQUID_LOG_TCP_REFRESH_HIT = '5',
00119   SQUID_LOG_TCP_REF_FAIL_HIT = '6',
00120   SQUID_LOG_TCP_REFRESH_MISS = '7',
00121   SQUID_LOG_TCP_CLIENT_REFRESH = '8',
00122   SQUID_LOG_TCP_IMS_HIT = '9',
00123   SQUID_LOG_TCP_IMS_MISS = 'a',
00124   SQUID_LOG_TCP_SWAPFAIL = 'b',
00125   SQUID_LOG_TCP_DENIED = 'c',
00126   SQUID_LOG_TCP_WEBFETCH_MISS = 'd',
00127   SQUID_LOG_TCP_FUTURE_2 = 'f',
00128   SQUID_LOG_TCP_HIT_REDIRECT = '[',       // standard redirect
00129   SQUID_LOG_TCP_MISS_REDIRECT = ']',      // standard redirect
00130   SQUID_LOG_TCP_HIT_X_REDIRECT = '<',     // extended redirect
00131   SQUID_LOG_TCP_MISS_X_REDIRECT = '>',    // extended redirect
00132   SQUID_LOG_UDP_HIT = 'g',
00133   SQUID_LOG_UDP_WEAK_HIT = 'h',
00134   SQUID_LOG_UDP_HIT_OBJ = 'i',
00135   SQUID_LOG_UDP_MISS = 'j',
00136   SQUID_LOG_UDP_DENIED = 'k',
00137   SQUID_LOG_UDP_INVALID = 'l',
00138   SQUID_LOG_UDP_RELOADING = 'm',
00139   SQUID_LOG_UDP_FUTURE_1 = 'n',
00140   SQUID_LOG_UDP_FUTURE_2 = 'o',
00141   SQUID_LOG_ERR_READ_TIMEOUT = 'p',
00142   SQUID_LOG_ERR_LIFETIME_EXP = 'q',
00143   SQUID_LOG_ERR_NO_CLIENTS_BIG_OBJ = 'r',
00144   SQUID_LOG_ERR_READ_ERROR = 's',
00145   SQUID_LOG_ERR_CLIENT_ABORT = 't',
00146   SQUID_LOG_ERR_CONNECT_FAIL = 'u',
00147   SQUID_LOG_ERR_INVALID_REQ = 'v',
00148   SQUID_LOG_ERR_UNSUP_REQ = 'w',
00149   SQUID_LOG_ERR_INVALID_URL = 'x',
00150   SQUID_LOG_ERR_NO_FDS = 'y',
00151   SQUID_LOG_ERR_DNS_FAIL = 'z',
00152   SQUID_LOG_ERR_NOT_IMPLEMENTED = 'A',
00153   SQUID_LOG_ERR_CANNOT_FETCH = 'B',
00154   SQUID_LOG_ERR_NO_RELAY = 'C',
00155   SQUID_LOG_ERR_DISK_IO = 'D',
00156   SQUID_LOG_ERR_ZERO_SIZE_OBJECT = 'E',
00157   SQUID_LOG_ERR_PROXY_DENIED = 'G',
00158   SQUID_LOG_ERR_WEBFETCH_DETECTED = 'H',
00159   SQUID_LOG_ERR_FUTURE_1 = 'I',
00160   SQUID_LOG_ERR_UNKNOWN = 'Z'
00161 };
00162 
00163 /* squid hieratchy codes */
00164 enum SquidHierarchyCode
00165 {
00166   SQUID_HIER_EMPTY = '0',
00167   SQUID_HIER_NONE = '1',
00168   SQUID_HIER_DIRECT = '2',
00169   SQUID_HIER_SIBLING_HIT = '3',
00170   SQUID_HIER_PARENT_HIT = '4',
00171   SQUID_HIER_DEFAULT_PARENT = '5',
00172   SQUID_HIER_SINGLE_PARENT = '6',
00173   SQUID_HIER_FIRST_UP_PARENT = '7',
00174   SQUID_HIER_NO_PARENT_DIRECT = '8',
00175   SQUID_HIER_FIRST_PARENT_MISS = '9',
00176   SQUID_HIER_LOCAL_IP_DIRECT = 'a',
00177   SQUID_HIER_FIREWALL_IP_DIRECT = 'b',
00178   SQUID_HIER_NO_DIRECT_FAIL = 'c',
00179   SQUID_HIER_SOURCE_FASTEST = 'd',
00180   SQUID_HIER_SIBLING_UDP_HIT_OBJ = 'e',
00181   SQUID_HIER_PARENT_UDP_HIT_OBJ = 'f',
00182   SQUID_HIER_PASSTHROUGH_PARENT = 'g',
00183   SQUID_HIER_SSL_PARENT_MISS = 'h',
00184   SQUID_HIER_INVALID_CODE = 'i',
00185   SQUID_HIER_TIMEOUT_DIRECT = 'j',
00186   SQUID_HIER_TIMEOUT_SIBLING_HIT = 'k',
00187   SQUID_HIER_TIMEOUT_PARENT_HIT = 'l',
00188   SQUID_HIER_TIMEOUT_DEFAULT_PARENT = 'm',
00189   SQUID_HIER_TIMEOUT_SINGLE_PARENT = 'n',
00190   SQUID_HIER_TIMEOUT_FIRST_UP_PARENT = 'o',
00191   SQUID_HIER_TIMEOUT_NO_PARENT_DIRECT = 'p',
00192   SQUID_HIER_TIMEOUT_FIRST_PARENT_MISS = 'q',
00193   SQUID_HIER_TIMEOUT_LOCAL_IP_DIRECT = 'r',
00194   SQUID_HIER_TIMEOUT_FIREWALL_IP_DIRECT = 's',
00195   SQUID_HIER_TIMEOUT_NO_DIRECT_FAIL = 't',
00196   SQUID_HIER_TIMEOUT_SOURCE_FASTEST = 'u',
00197   SQUID_HIER_TIMEOUT_SIBLING_UDP_HIT_OBJ = 'v',
00198   SQUID_HIER_TIMEOUT_PARENT_UDP_HIT_OBJ = 'w',
00199   SQUID_HIER_TIMEOUT_PASSTHROUGH_PARENT = 'x',
00200   SQUID_HIER_TIMEOUT_TIMEOUT_SSL_PARENT_MISS = 'y',
00201   SQUID_HIER_INVALID_ASSIGNED_CODE = 'z'
00202 };
00203 
00204 /* squid hit/miss codes */
00205 enum SquidHitMissCode
00206 {
00207   SQUID_HIT_RESERVED = '0',
00208   SQUID_HIT_LEVEL_1 = '1',
00209   SQUID_HIT_LEVEL_2 = '2',
00210   SQUID_HIT_LEVEL_3 = '3',
00211   SQUID_HIT_LEVEL_4 = '4',
00212   SQUID_HIT_LEVEL_5 = '5',
00213   SQUID_HIT_LEVEL_6 = '6',
00214   SQUID_HIT_LEVEL_7 = '7',
00215   SQUID_HIT_LEVEL_8 = '8',
00216   SQUID_HIT_LEVEl_9 = '9',
00217   SQUID_MISS_NONE = '1',
00218   SQUID_MISS_ICP_AUTH = '2',
00219   SQUID_MISS_HTTP_NON_CACHE = '3',
00220   SQUID_MISS_ICP_STOPLIST = '4',
00221   SQUID_MISS_HTTP_NO_DLE = '5',
00222   SQUID_MISS_HTTP_NO_LE = '6',
00223   SQUID_MISS_HTTP_CONTENT = '7',
00224   SQUID_MISS_PRAGMA_NOCACHE = '8',
00225   SQUID_MISS_PASS = '9',
00226   SQUID_MISS_PRE_EXPIRED = 'a',
00227   SQUID_MISS_ERROR = 'b',
00228   SQUID_MISS_CACHE_BYPASS = 'c',
00229   SQUID_HIT_MISS_INVALID_ASSIGNED_CODE = 'z'
00230 };
00231 
00232 
00233 enum HTTPType
00234 {
00235   HTTP_TYPE_UNKNOWN,
00236   HTTP_TYPE_REQUEST,
00237   HTTP_TYPE_RESPONSE
00238 };
00239 
00240 struct HTTPHdrImpl:public HdrHeapObjImpl
00241 {
00242   // HdrHeapObjImpl is 4 bytes
00243   HTTPType m_polarity;          // request or response or unknown
00244   int32_t m_version;              // cooked version number
00245   // 12 bytes means 4 bytes padding here on 64-bit architectures
00246   union
00247   {
00248     struct
00249     {
00250       URLImpl *m_url_impl;
00251       const char *m_ptr_method;
00252       uint16_t m_len_method;
00253       int16_t m_method_wks_idx;
00254     } req;
00255 
00256     struct
00257     {
00258       const char *m_ptr_reason;
00259       uint16_t m_len_reason;
00260       int16_t m_status;
00261     } resp;
00262   } u;
00263 
00264   MIMEHdrImpl *m_fields_impl;
00265 
00266   // Marshaling Functions
00267   int marshal(MarshalXlate *ptr_xlate, int num_ptr, MarshalXlate *str_xlate, int num_str);
00268   void unmarshal(intptr_t offset);
00269   void move_strings(HdrStrHeap *new_heap);
00270   size_t strings_length();
00271 
00272   // Sanity Check Functions
00273   void check_strings(HeapCheck *heaps, int num_heaps);
00274 };
00275 
00276 struct HTTPValAccept
00277 {
00278   char *type;
00279   char *subtype;
00280   double qvalue;
00281 };
00282 
00283 
00284 struct HTTPValAcceptCharset
00285 {
00286   char *charset;
00287   double qvalue;
00288 };
00289 
00290 
00291 struct HTTPValAcceptEncoding
00292 {
00293   char *encoding;
00294   double qvalue;
00295 };
00296 
00297 
00298 struct HTTPValAcceptLanguage
00299 {
00300   char *language;
00301   double qvalue;
00302 };
00303 
00304 
00305 struct HTTPValFieldList
00306 {
00307   char *name;
00308   HTTPValFieldList *next;
00309 };
00310 
00311 
00312 struct HTTPValCacheControl
00313 {
00314   const char *directive;
00315 
00316   union
00317   {
00318     int delta_seconds;
00319     HTTPValFieldList *field_names;
00320   } u;
00321 };
00322 
00323 
00324 struct HTTPValRange
00325 {
00326   int start;
00327   int end;
00328   HTTPValRange *next;
00329 };
00330 
00331 
00332 struct HTTPValTE
00333 {
00334   char *encoding;
00335   double qvalue;
00336 };
00337 
00338 
00339 struct HTTPParser
00340 {
00341   bool m_parsing_http;
00342   MIMEParser m_mime_parser;
00343 };
00344 
00345 
00346 extern const char *HTTP_METHOD_CONNECT;
00347 extern const char *HTTP_METHOD_DELETE;
00348 extern const char *HTTP_METHOD_GET;
00349 extern const char *HTTP_METHOD_HEAD;
00350 extern const char *HTTP_METHOD_ICP_QUERY;
00351 extern const char *HTTP_METHOD_OPTIONS;
00352 extern const char *HTTP_METHOD_POST;
00353 extern const char *HTTP_METHOD_PURGE;
00354 extern const char *HTTP_METHOD_PUT;
00355 extern const char *HTTP_METHOD_TRACE;
00356 extern const char *HTTP_METHOD_PUSH;
00357 
00358 extern int HTTP_WKSIDX_CONNECT;
00359 extern int HTTP_WKSIDX_DELETE;
00360 extern int HTTP_WKSIDX_GET;
00361 extern int HTTP_WKSIDX_HEAD;
00362 extern int HTTP_WKSIDX_ICP_QUERY;
00363 extern int HTTP_WKSIDX_OPTIONS;
00364 extern int HTTP_WKSIDX_POST;
00365 extern int HTTP_WKSIDX_PURGE;
00366 extern int HTTP_WKSIDX_PUT;
00367 extern int HTTP_WKSIDX_TRACE;
00368 extern int HTTP_WKSIDX_PUSH;
00369 extern int HTTP_WKSIDX_METHODS_CNT;
00370 
00371 
00372 extern int HTTP_LEN_CONNECT;
00373 extern int HTTP_LEN_DELETE;
00374 extern int HTTP_LEN_GET;
00375 extern int HTTP_LEN_HEAD;
00376 extern int HTTP_LEN_ICP_QUERY;
00377 extern int HTTP_LEN_OPTIONS;
00378 extern int HTTP_LEN_POST;
00379 extern int HTTP_LEN_PURGE;
00380 extern int HTTP_LEN_PUT;
00381 extern int HTTP_LEN_TRACE;
00382 extern int HTTP_LEN_PUSH;
00383 
00384 extern const char *HTTP_VALUE_BYTES;
00385 extern const char *HTTP_VALUE_CHUNKED;
00386 extern const char *HTTP_VALUE_CLOSE;
00387 extern const char *HTTP_VALUE_COMPRESS;
00388 extern const char *HTTP_VALUE_DEFLATE;
00389 extern const char *HTTP_VALUE_GZIP;
00390 extern const char *HTTP_VALUE_IDENTITY;
00391 extern const char *HTTP_VALUE_KEEP_ALIVE;
00392 extern const char *HTTP_VALUE_MAX_AGE;
00393 extern const char *HTTP_VALUE_MAX_STALE;
00394 extern const char *HTTP_VALUE_MIN_FRESH;
00395 extern const char *HTTP_VALUE_MUST_REVALIDATE;
00396 extern const char *HTTP_VALUE_NONE;
00397 extern const char *HTTP_VALUE_NO_CACHE;
00398 extern const char *HTTP_VALUE_NO_STORE;
00399 extern const char *HTTP_VALUE_NO_TRANSFORM;
00400 extern const char *HTTP_VALUE_ONLY_IF_CACHED;
00401 extern const char *HTTP_VALUE_PRIVATE;
00402 extern const char *HTTP_VALUE_PROXY_REVALIDATE;
00403 extern const char *HTTP_VALUE_PUBLIC;
00404 extern const char *HTTP_VALUE_S_MAXAGE;
00405 extern const char *HTTP_VALUE_NEED_REVALIDATE_ONCE;
00406 extern const char *HTTP_VALUE_100_CONTINUE;
00407 
00408 extern int HTTP_LEN_BYTES;
00409 extern int HTTP_LEN_CHUNKED;
00410 extern int HTTP_LEN_CLOSE;
00411 extern int HTTP_LEN_COMPRESS;
00412 extern int HTTP_LEN_DEFLATE;
00413 extern int HTTP_LEN_GZIP;
00414 extern int HTTP_LEN_IDENTITY;
00415 extern int HTTP_LEN_KEEP_ALIVE;
00416 extern int HTTP_LEN_MAX_AGE;
00417 extern int HTTP_LEN_MAX_STALE;
00418 extern int HTTP_LEN_MIN_FRESH;
00419 extern int HTTP_LEN_MUST_REVALIDATE;
00420 extern int HTTP_LEN_NONE;
00421 extern int HTTP_LEN_NO_CACHE;
00422 extern int HTTP_LEN_NO_STORE;
00423 extern int HTTP_LEN_NO_TRANSFORM;
00424 extern int HTTP_LEN_ONLY_IF_CACHED;
00425 extern int HTTP_LEN_PRIVATE;
00426 extern int HTTP_LEN_PROXY_REVALIDATE;
00427 extern int HTTP_LEN_PUBLIC;
00428 extern int HTTP_LEN_S_MAXAGE;
00429 extern int HTTP_LEN_NEED_REVALIDATE_ONCE;
00430 extern int HTTP_LEN_100_CONTINUE;
00431 
00432 /* Private */
00433 void http_hdr_adjust(HTTPHdrImpl *hdrp, int32_t offset, int32_t length, int32_t delta);
00434 
00435 /* Public */
00436 void http_init();
00437 
00438 inkcoreapi HTTPHdrImpl *http_hdr_create(HdrHeap *heap, HTTPType polarity);
00439 void http_hdr_init(HdrHeap *heap, HTTPHdrImpl *hh, HTTPType polarity);
00440 HTTPHdrImpl *http_hdr_clone(HTTPHdrImpl *s_hh, HdrHeap *s_heap, HdrHeap *d_heap);
00441 void http_hdr_copy_onto(HTTPHdrImpl *s_hh, HdrHeap *s_heap, HTTPHdrImpl *d_hh, HdrHeap *d_heap, bool inherit_strs);
00442 
00443 inkcoreapi int http_hdr_print(HdrHeap *heap, HTTPHdrImpl *hh, char *buf, int bufsize, int *bufindex, int *dumpoffset);
00444 
00445 void http_hdr_describe(HdrHeapObjImpl *obj, bool recurse = true);
00446 
00447 int http_hdr_length_get(HTTPHdrImpl *hh);
00448 // HTTPType               http_hdr_type_get (HTTPHdrImpl *hh);
00449 
00450 // int32_t                  http_hdr_version_get (HTTPHdrImpl *hh);
00451 inkcoreapi void http_hdr_version_set(HTTPHdrImpl *hh, int32_t ver);
00452 
00453 const char *http_hdr_method_get(HTTPHdrImpl *hh, int *length);
00454 inkcoreapi void http_hdr_method_set(HdrHeap *heap, HTTPHdrImpl *hh,
00455                                     const char *method, int16_t method_wks_idx, int method_length, bool must_copy);
00456 
00457 void http_hdr_url_set(HdrHeap *heap, HTTPHdrImpl *hh, URLImpl *url);
00458 
00459 // HTTPStatus             http_hdr_status_get (HTTPHdrImpl *hh);
00460 void http_hdr_status_set(HTTPHdrImpl *hh, HTTPStatus status);
00461 const char *http_hdr_reason_get(HTTPHdrImpl *hh, int *length);
00462 void http_hdr_reason_set(HdrHeap *heap, HTTPHdrImpl *hh, const char *value, int length, bool must_copy);
00463 const char *http_hdr_reason_lookup(unsigned status);
00464 
00465 void http_parser_init(HTTPParser *parser);
00466 void http_parser_clear(HTTPParser *parser);
00467 MIMEParseResult http_parser_parse_req(HTTPParser *parser, HdrHeap *heap,
00468                                       HTTPHdrImpl *hh, const char **start,
00469                                       const char *end, bool must_copy_strings, bool eof);
00470 MIMEParseResult http_parser_parse_resp(HTTPParser *parser, HdrHeap *heap,
00471                                        HTTPHdrImpl *hh, const char **start,
00472                                        const char *end, bool must_copy_strings, bool eof);
00473 HTTPStatus http_parse_status(const char *start, const char *end);
00474 int32_t http_parse_version(const char *start, const char *end);
00475 
00476 
00477 /*
00478 HTTPValAccept*         http_parse_accept (const char *buf, Arena *arena);
00479 HTTPValAcceptCharset*  http_parse_accept_charset (const char *buf, Arena *arena);
00480 HTTPValAcceptEncoding* http_parse_accept_encoding (const char *buf, Arena *arena);
00481 HTTPValAcceptLanguage* http_parse_accept_language (const char *buf, Arena *arena);
00482 HTTPValCacheControl*   http_parse_cache_control (const char *buf, Arena *arena);
00483 const char*            http_parse_cache_directive (const char **buf);
00484 HTTPValRange*          http_parse_range (const char *buf, Arena *arena);
00485 */
00486 HTTPValTE *http_parse_te(const char *buf, int len, Arena *arena);
00487 
00488 
00489 class HTTPVersion
00490 {
00491 public:
00492   HTTPVersion();
00493   explicit HTTPVersion(int32_t version);
00494   HTTPVersion(int ver_major, int ver_minor);
00495 
00496   void set(HTTPVersion ver);
00497   void set(int ver_major, int ver_minor);
00498 
00499   HTTPVersion & operator =(const HTTPVersion & hv);
00500   int operator ==(const HTTPVersion & hv) const;
00501   int operator !=(const HTTPVersion & hv) const;
00502   int operator >(const HTTPVersion & hv) const;
00503   int operator <(const HTTPVersion & hv) const;
00504   int operator >=(const HTTPVersion & hv) const;
00505   int operator <=(const HTTPVersion & hv) const;
00506 
00507 public:
00508     int32_t m_version;
00509 };
00510 
00511 class IOBufferReader;
00512 
00513 class HTTPHdr: public MIMEHdr
00514 {
00515 public:
00516   HTTPHdrImpl *m_http;
00517   // This is all cached data and so is mutable.
00518   mutable URL m_url_cached;
00519   mutable MIMEField *m_host_mime;
00520   mutable int m_host_length; ///< Length of hostname.
00521   mutable int m_port; ///< Target port.
00522   mutable bool m_target_cached; ///< Whether host name and port are cached.
00523   mutable bool m_target_in_url; ///< Whether host name and port are in the URL.
00524   /// Set if the port was effectively specified in the header.
00525   /// @c true if the target (in the URL or the HOST field) also specified
00526   /// a port. That is, @c true if whatever source had the target host
00527   /// also had a port, @c false otherwise.
00528   mutable bool m_port_in_header;
00529 
00530   HTTPHdr();
00531   ~HTTPHdr();
00532 
00533   int valid() const;
00534 
00535   void create(HTTPType polarity, HdrHeap *heap = NULL);
00536   void clear();
00537   void reset();
00538   void copy(const HTTPHdr *hdr);
00539   void copy_shallow(const HTTPHdr *hdr);
00540 
00541   int unmarshal(char *buf, int len, RefCountObj *block_ref);
00542 
00543   int print(char *buf, int bufsize, int *bufindex, int *dumpoffset);
00544 
00545   int length_get();
00546 
00547   HTTPType type_get() const;
00548 
00549   HTTPVersion version_get();
00550   void version_set(HTTPVersion version);
00551 
00552   const char *method_get(int *length);
00553   int method_get_wksidx();
00554   void method_set(const char *value, int length);
00555 
00556   URL *url_create(URL *url);
00557 
00558   URL *url_get() const;
00559   URL *url_get(URL *url);
00560   /** Get a string with the effective URL in it.
00561       If @a length is not @c NULL then the length of the string
00562       is stored in the int pointed to by @a length.
00563 
00564       Note that this can be different from getting the @c URL
00565       and invoking @c URL::string_get if the host is in a header
00566       field and not explicitly in the URL.
00567    */
00568   char* url_string_get(
00569     Arena* arena = 0, ///< Arena to use, or @c malloc if NULL.
00570     int* length = 0 ///< Store string length here.
00571   );
00572   /** Get a string with the effective URL in it.
00573       This is automatically allocated if needed in the request heap.
00574 
00575       @see url_string_get
00576    */
00577   char* url_string_get_ref(
00578     int* length = 0 ///< Store string length here.
00579   );
00580 
00581   /** Print the URL.
00582       Output is not null terminated.
00583       @return 0 on failure, non-zero on success.
00584    */
00585   int url_print(
00586       char* buff, ///< Output buffer
00587       int length, ///< Length of @a buffer
00588       int* offset, ///< [in,out] ???
00589       int* skip ///< [in,out] ???
00590   );
00591 
00592   /** Get the URL path.
00593       This is a reference, not allocated.
00594       @return A pointer to the path or @c NULL if there is no valid URL.
00595   */
00596   char const* path_get(
00597                        int* length ///< Storage for path length.
00598                        );
00599 
00600   /** Get the target host name.
00601       The length is returned in @a length if non-NULL.
00602       @note The results are cached so this is fast after the first call.
00603       @return A pointer to the host name.
00604   */
00605   char const* host_get(int* length = 0);
00606 
00607   /** Get the target port.
00608       If the target port is not found then it is adjusted to the
00609       default port for the URL type.
00610       @note The results are cached so this is fast after the first call.
00611       @return The canonicalized target port.
00612   */
00613   int port_get();
00614 
00615   /** Get the URL scheme.
00616       This is a reference, not allocated.
00617       @return A pointer to the scheme or @c NULL if there is no valid URL.
00618   */
00619   char const* scheme_get(
00620                        int* length ///< Storage for path length.
00621                        );
00622   void url_set(URL *url);
00623   void url_set_as_server_url(URL *url);
00624   void url_set(const char *str, int length);
00625 
00626   /// Check location of target host.
00627   /// @return @c true if the host was in the URL, @c false otherwise.
00628   /// @note This returns @c false if the host is missing.
00629   bool is_target_in_url() const;
00630 
00631   /// Check if a port was specified in the target.
00632   /// @return @c true if the port was part of the target.
00633   bool is_port_in_header() const;
00634 
00635   /// If the target is in the fields and not the URL, copy it to the @a url.
00636   /// If @a url is @c NULL the cached URL in this header is used.
00637   /// @note In the default case the copy is avoided if the cached URL already
00638   /// has the target. If @a url is non @c NULL the copy is always performed.
00639   void set_url_target_from_host_field(URL* url = 0);
00640 
00641   /// Mark the target cache as invalid.
00642   /// @internal Ugly but too many places currently that touch the
00643   /// header internals, they must be able to do this.
00644   void mark_target_dirty() const;
00645 
00646   HTTPStatus status_get();
00647   void status_set(HTTPStatus status);
00648 
00649   const char *reason_get(int *length);
00650   void reason_set(const char *value, int length);
00651 
00652   MIMEParseResult parse_req(HTTPParser *parser, const char **start, const char *end, bool eof);
00653   MIMEParseResult parse_resp(HTTPParser *parser, const char **start, const char *end, bool eof);
00654 
00655   MIMEParseResult parse_req(HTTPParser *parser, IOBufferReader *r, int *bytes_used, bool eof);
00656   MIMEParseResult parse_resp(HTTPParser *parser, IOBufferReader *r, int *bytes_used, bool eof);
00657 
00658 public:
00659   // Utility routines
00660   bool is_cache_control_set(const char *cc_directive_wks);
00661   bool is_pragma_no_cache_set();
00662 
00663 protected:
00664   /** Load the target cache.
00665       @see m_host, m_port, m_target_in_url
00666   */
00667   void _fill_target_cache() const;
00668   /** Test the cache and fill it if necessary.
00669       @internal In contrast to @c _fill_target_cache, this method
00670       is inline and checks whether the cache is already filled.
00671       @ _fill_target_cache @b always does a cache fill.
00672   */
00673   void _test_and_fill_target_cache() const;
00674 
00675   static Arena* const USE_HDR_HEAP_MAGIC;
00676 
00677 private:
00678   // No gratuitous copies!
00679   HTTPHdr(const HTTPHdr & m);
00680   HTTPHdr & operator =(const HTTPHdr & m);
00681 
00682   friend class UrlPrintHack; // don't ask.
00683 };
00684 
00685 
00686 /*-------------------------------------------------------------------------
00687   -------------------------------------------------------------------------*/
00688 
00689 inline HTTPVersion::HTTPVersion()
00690 :m_version(HTTP_VERSION(0, 9))
00691 {
00692 }
00693 
00694 /*-------------------------------------------------------------------------
00695   -------------------------------------------------------------------------*/
00696 
00697 inline HTTPVersion::HTTPVersion(int32_t version)
00698 :m_version(version)
00699 {
00700 }
00701 
00702 /*-------------------------------------------------------------------------
00703   -------------------------------------------------------------------------*/
00704 
00705 inline HTTPVersion::HTTPVersion(int ver_major, int ver_minor)
00706   :
00707 m_version(HTTP_VERSION(ver_major, ver_minor))
00708 {
00709 }
00710 
00711 /*-------------------------------------------------------------------------
00712   -------------------------------------------------------------------------*/
00713 
00714 inline void
00715 HTTPVersion::set(HTTPVersion ver)
00716 {
00717   m_version = ver.m_version;
00718 }
00719 
00720 /*-------------------------------------------------------------------------
00721   -------------------------------------------------------------------------*/
00722 
00723 inline void
00724 HTTPVersion::set(int ver_major, int ver_minor)
00725 {
00726   m_version = HTTP_VERSION(ver_major, ver_minor);
00727 }
00728 
00729 /*-------------------------------------------------------------------------
00730   -------------------------------------------------------------------------*/
00731 
00732 inline HTTPVersion &
00733 HTTPVersion::operator =(const HTTPVersion & hv)
00734 {
00735   m_version = hv.m_version;
00736 
00737   return *this;
00738 }
00739 
00740 /*-------------------------------------------------------------------------
00741   -------------------------------------------------------------------------*/
00742 
00743 inline int
00744 HTTPVersion::operator ==(const HTTPVersion & hv) const
00745 {
00746   return (m_version == hv.m_version);
00747 }
00748 
00749 /*-------------------------------------------------------------------------
00750   -------------------------------------------------------------------------*/
00751 
00752 inline int
00753 HTTPVersion::operator !=(const HTTPVersion & hv) const
00754 {
00755   return (m_version != hv.m_version);
00756 }
00757 
00758 /*-------------------------------------------------------------------------
00759   -------------------------------------------------------------------------*/
00760 
00761 inline int
00762 HTTPVersion::operator >(const HTTPVersion & hv) const
00763 {
00764   return (m_version > hv.m_version);
00765 }
00766 
00767 /*-------------------------------------------------------------------------
00768   -------------------------------------------------------------------------*/
00769 
00770 inline int
00771 HTTPVersion::operator <(const HTTPVersion & hv) const
00772 {
00773   return (m_version < hv.m_version);
00774 }
00775 
00776 /*-------------------------------------------------------------------------
00777   -------------------------------------------------------------------------*/
00778 
00779 inline int
00780 HTTPVersion::operator >=(const HTTPVersion & hv) const
00781 {
00782   return (m_version >= hv.m_version);
00783 }
00784 
00785 /*-------------------------------------------------------------------------
00786   -------------------------------------------------------------------------*/
00787 
00788 inline int
00789 HTTPVersion::operator <=(const HTTPVersion & hv) const
00790 {
00791   return (m_version <= hv.m_version);
00792 }
00793 
00794 
00795 /*-------------------------------------------------------------------------
00796   -------------------------------------------------------------------------*/
00797 
00798 inline
00799 HTTPHdr::HTTPHdr()
00800   : MIMEHdr(), m_http(NULL), m_url_cached(), m_target_cached(false)
00801 { }
00802 
00803 
00804 /*-------------------------------------------------------------------------
00805   -------------------------------------------------------------------------*/
00806 inline
00807 HTTPHdr::~HTTPHdr()
00808 {                               /* nop */
00809 }
00810 
00811 /*-------------------------------------------------------------------------
00812   -------------------------------------------------------------------------*/
00813 
00814 inline int
00815 HTTPHdr::valid() const
00816 {
00817   return (m_http && m_mime && m_heap);
00818 }
00819 
00820 /*-------------------------------------------------------------------------
00821   -------------------------------------------------------------------------*/
00822 
00823 inline void
00824 HTTPHdr::create(HTTPType polarity, HdrHeap *heap)
00825 {
00826   if (heap) {
00827     m_heap = heap;
00828   } else if (!m_heap) {
00829     m_heap = new_HdrHeap();
00830   }
00831 
00832   m_http = http_hdr_create(m_heap, polarity);
00833   m_mime = m_http->m_fields_impl;
00834 }
00835 
00836 inline void
00837 HTTPHdr::clear()
00838 {
00839 
00840   if (m_http && m_http->m_polarity == HTTP_TYPE_REQUEST) {
00841     m_url_cached.clear();
00842   }
00843   this->HdrHeapSDKHandle::clear();
00844   m_http = NULL;
00845   m_mime = NULL;
00846 }
00847 
00848 inline void
00849 HTTPHdr::reset()
00850 {
00851   m_heap = NULL;
00852   m_http = NULL;
00853   m_mime = NULL;
00854   m_url_cached.reset();
00855 }
00856 
00857 /*-------------------------------------------------------------------------
00858   -------------------------------------------------------------------------*/
00859 
00860 inline void
00861 HTTPHdr::copy(const HTTPHdr *hdr)
00862 {
00863   ink_assert(hdr->valid());
00864 
00865   if (valid()) {
00866     http_hdr_copy_onto(hdr->m_http, hdr->m_heap, m_http, m_heap, (m_heap != hdr->m_heap) ? true : false);
00867   } else {
00868     m_heap = new_HdrHeap();
00869     m_http = http_hdr_clone(hdr->m_http, hdr->m_heap, m_heap);
00870     m_mime = m_http->m_fields_impl;
00871   }
00872 }
00873 
00874 /*-------------------------------------------------------------------------
00875   -------------------------------------------------------------------------*/
00876 
00877 inline void
00878 HTTPHdr::copy_shallow(const HTTPHdr *hdr)
00879 {
00880   ink_assert(hdr->valid());
00881 
00882   m_heap = hdr->m_heap;
00883   m_http = hdr->m_http;
00884   m_mime = hdr->m_mime;
00885 
00886   if (hdr->type_get() == HTTP_TYPE_REQUEST && m_url_cached.valid())
00887     m_url_cached.copy_shallow(&hdr->m_url_cached);
00888 }
00889 
00890 /*-------------------------------------------------------------------------
00891   -------------------------------------------------------------------------*/
00892 
00893 inline int
00894 HTTPHdr::print(char *buf, int bufsize, int *bufindex, int *dumpoffset)
00895 {
00896   ink_assert(valid());
00897   return http_hdr_print(m_heap, m_http, buf, bufsize, bufindex, dumpoffset);
00898 }
00899 
00900 /*-------------------------------------------------------------------------
00901   -------------------------------------------------------------------------*/
00902 
00903 inline int
00904 HTTPHdr::length_get()
00905 {
00906   ink_assert(valid());
00907   return http_hdr_length_get(m_http);
00908 }
00909 
00910 /*-------------------------------------------------------------------------
00911   -------------------------------------------------------------------------*/
00912 
00913 inline void
00914 HTTPHdr::_test_and_fill_target_cache() const {
00915   if (!m_target_cached) this->_fill_target_cache();
00916 }
00917 
00918 /*-------------------------------------------------------------------------
00919   -------------------------------------------------------------------------*/
00920 
00921 inline char const*
00922 HTTPHdr::host_get(int* length)
00923 {
00924   this->_test_and_fill_target_cache();
00925   if (m_target_in_url) {
00926     return url_get()->host_get(length);
00927   } else if (m_host_mime) {
00928     if (length) *length = m_host_length;
00929     return m_host_mime->m_ptr_value;
00930   }
00931 
00932   if (length) *length = 0;
00933   return NULL;
00934 }
00935 
00936 /*-------------------------------------------------------------------------
00937   -------------------------------------------------------------------------*/
00938 
00939 inline int
00940 HTTPHdr::port_get()
00941 {
00942   this->_test_and_fill_target_cache();
00943   return m_port;
00944 }
00945 
00946 /*-------------------------------------------------------------------------
00947   -------------------------------------------------------------------------*/
00948 
00949 inline bool
00950 HTTPHdr::is_target_in_url() const
00951 {
00952   this->_test_and_fill_target_cache();
00953   return m_target_in_url;
00954 }
00955 
00956 /*-------------------------------------------------------------------------
00957   -------------------------------------------------------------------------*/
00958 
00959 inline bool
00960 HTTPHdr::is_port_in_header() const
00961 {
00962   this->_test_and_fill_target_cache();
00963   return m_port_in_header;
00964 }
00965 
00966 /*-------------------------------------------------------------------------
00967   -------------------------------------------------------------------------*/
00968 
00969 inline void
00970 HTTPHdr::mark_target_dirty() const
00971 {
00972   m_target_cached = false;
00973 }
00974 /*-------------------------------------------------------------------------
00975   -------------------------------------------------------------------------*/
00976 
00977 inline HTTPType
00978 http_hdr_type_get(HTTPHdrImpl *hh)
00979 {
00980   return (hh->m_polarity);
00981 }
00982 
00983 /*-------------------------------------------------------------------------
00984   -------------------------------------------------------------------------*/
00985 
00986 inline HTTPType
00987 HTTPHdr::type_get() const
00988 {
00989   ink_assert(valid());
00990   return http_hdr_type_get(m_http);
00991 }
00992 
00993 /*-------------------------------------------------------------------------
00994   -------------------------------------------------------------------------*/
00995 
00996 inline int32_t
00997 http_hdr_version_get(HTTPHdrImpl *hh)
00998 {
00999   return (hh->m_version);
01000 }
01001 
01002 /*-------------------------------------------------------------------------
01003   -------------------------------------------------------------------------*/
01004 
01005 inline HTTPVersion
01006 HTTPHdr::version_get()
01007 {
01008   ink_assert(valid());
01009   return HTTPVersion(http_hdr_version_get(m_http));
01010 }
01011 
01012 /*-------------------------------------------------------------------------
01013   -------------------------------------------------------------------------*/
01014 
01015 inline void
01016 HTTPHdr::version_set(HTTPVersion version)
01017 {
01018   ink_assert(valid());
01019   http_hdr_version_set(m_http, version.m_version);
01020 }
01021 
01022 /*-------------------------------------------------------------------------
01023   -------------------------------------------------------------------------*/
01024 
01025 inline const char *
01026 HTTPHdr::method_get(int *length)
01027 {
01028   ink_assert(valid());
01029   ink_assert(m_http->m_polarity == HTTP_TYPE_REQUEST);
01030 
01031   return http_hdr_method_get(m_http, length);
01032 }
01033 
01034 
01035 inline int
01036 HTTPHdr::method_get_wksidx()
01037 {
01038   ink_assert(valid());
01039   ink_assert(m_http->m_polarity == HTTP_TYPE_REQUEST);
01040 
01041   return (m_http->u.req.m_method_wks_idx);
01042 }
01043 
01044 
01045 /*-------------------------------------------------------------------------
01046   -------------------------------------------------------------------------*/
01047 
01048 inline void
01049 HTTPHdr::method_set(const char *value, int length)
01050 {
01051   ink_assert(valid());
01052   ink_assert(m_http->m_polarity == HTTP_TYPE_REQUEST);
01053 
01054   int method_wks_idx = hdrtoken_tokenize(value, length);
01055   http_hdr_method_set(m_heap, m_http, value, method_wks_idx, length, true);
01056 }
01057 
01058 /*-------------------------------------------------------------------------
01059   -------------------------------------------------------------------------*/
01060 
01061 inline URL *
01062 HTTPHdr::url_create(URL *u)
01063 {
01064   ink_assert(valid());
01065   ink_assert(m_http->m_polarity == HTTP_TYPE_REQUEST);
01066 
01067   u->set(this);
01068   u->create(m_heap);
01069   return (u);
01070 }
01071 
01072 /*-------------------------------------------------------------------------
01073   -------------------------------------------------------------------------*/
01074 
01075 inline URL *
01076 HTTPHdr::url_get() const
01077 {
01078   ink_assert(valid());
01079   ink_assert(m_http->m_polarity == HTTP_TYPE_REQUEST);
01080 
01081   // It's entirely possible that someone changed URL in our impl
01082   // without updating the cached copy in the C++ layer.  Check
01083   // to see if this happened before handing back the url
01084 
01085   URLImpl *real_impl = m_http->u.req.m_url_impl;
01086   if (m_url_cached.m_url_impl != real_impl) {
01087     m_url_cached.set(this);
01088     m_url_cached.m_url_impl = real_impl;
01089     this->mark_target_dirty();
01090   }
01091   return (&m_url_cached);
01092 }
01093 
01094 /*-------------------------------------------------------------------------
01095   -------------------------------------------------------------------------*/
01096 
01097 inline URL *
01098 HTTPHdr::url_get(URL *url)
01099 {
01100   ink_assert(valid());
01101   ink_assert(m_http->m_polarity == HTTP_TYPE_REQUEST);
01102 
01103   url->set(this);               // attach refcount
01104   url->m_url_impl = m_http->u.req.m_url_impl;
01105   return (url);
01106 }
01107 
01108 /*-------------------------------------------------------------------------
01109   -------------------------------------------------------------------------*/
01110 
01111 inline void
01112 HTTPHdr::url_set(URL *url)
01113 {
01114   ink_assert(valid());
01115   ink_assert(m_http->m_polarity == HTTP_TYPE_REQUEST);
01116 
01117   URLImpl *url_impl = m_http->u.req.m_url_impl;
01118   ::url_copy_onto(url->m_url_impl, url->m_heap, url_impl, m_heap, true);
01119 }
01120 
01121 /*-------------------------------------------------------------------------
01122   -------------------------------------------------------------------------*/
01123 
01124 inline void
01125 HTTPHdr::url_set_as_server_url(URL *url)
01126 {
01127   ink_assert(valid());
01128   ink_assert(m_http->m_polarity == HTTP_TYPE_REQUEST);
01129 
01130   URLImpl *url_impl = m_http->u.req.m_url_impl;
01131   ::url_copy_onto_as_server_url(url->m_url_impl, url->m_heap, url_impl, m_heap, true);
01132 }
01133 
01134 /*-------------------------------------------------------------------------
01135   -------------------------------------------------------------------------*/
01136 
01137 inline void
01138 HTTPHdr::url_set(const char *str, int length)
01139 {
01140   URLImpl *url_impl;
01141 
01142   ink_assert(valid());
01143   ink_assert(m_http->m_polarity == HTTP_TYPE_REQUEST);
01144 
01145   url_impl = m_http->u.req.m_url_impl;
01146   ::url_clear(url_impl);
01147   ::url_parse(m_heap, url_impl, &str, str + length, true);
01148 }
01149 
01150 /*-------------------------------------------------------------------------
01151   -------------------------------------------------------------------------*/
01152 
01153 inline HTTPStatus
01154 http_hdr_status_get(HTTPHdrImpl *hh)
01155 {
01156   ink_assert(hh->m_polarity == HTTP_TYPE_RESPONSE);
01157   return (HTTPStatus) hh->u.resp.m_status;
01158 }
01159 
01160 /*-------------------------------------------------------------------------
01161   -------------------------------------------------------------------------*/
01162 
01163 inline HTTPStatus
01164 HTTPHdr::status_get()
01165 {
01166   ink_assert(valid());
01167   ink_assert(m_http->m_polarity == HTTP_TYPE_RESPONSE);
01168 
01169   return (NULL == m_http) ? HTTP_STATUS_NONE : http_hdr_status_get(m_http);
01170 }
01171 
01172 /*-------------------------------------------------------------------------
01173   -------------------------------------------------------------------------*/
01174 
01175 inline void
01176 HTTPHdr::status_set(HTTPStatus status)
01177 {
01178   ink_assert(valid());
01179   ink_assert(m_http->m_polarity == HTTP_TYPE_RESPONSE);
01180 
01181   http_hdr_status_set(m_http, status);
01182 }
01183 
01184 /*-------------------------------------------------------------------------
01185   -------------------------------------------------------------------------*/
01186 
01187 inline const char *
01188 HTTPHdr::reason_get(int *length)
01189 {
01190   ink_assert(valid());
01191   ink_assert(m_http->m_polarity == HTTP_TYPE_RESPONSE);
01192 
01193   return http_hdr_reason_get(m_http, length);
01194 }
01195 
01196 /*-------------------------------------------------------------------------
01197   -------------------------------------------------------------------------*/
01198 
01199 inline void
01200 HTTPHdr::reason_set(const char *value, int length)
01201 {
01202   ink_assert(valid());
01203   ink_assert(m_http->m_polarity == HTTP_TYPE_RESPONSE);
01204 
01205   http_hdr_reason_set(m_heap, m_http, value, length, true);
01206 }
01207 
01208 /*-------------------------------------------------------------------------
01209   -------------------------------------------------------------------------*/
01210 
01211 inline MIMEParseResult
01212 HTTPHdr::parse_req(HTTPParser *parser, const char **start, const char *end, bool eof)
01213 {
01214   ink_assert(valid());
01215   ink_assert(m_http->m_polarity == HTTP_TYPE_REQUEST);
01216 
01217   return http_parser_parse_req(parser, m_heap, m_http, start, end, true, eof);
01218 }
01219 
01220 /*-------------------------------------------------------------------------
01221   -------------------------------------------------------------------------*/
01222 
01223 inline MIMEParseResult
01224 HTTPHdr::parse_resp(HTTPParser *parser, const char **start, const char *end, bool eof)
01225 {
01226   ink_assert(valid());
01227   ink_assert(m_http->m_polarity == HTTP_TYPE_RESPONSE);
01228 
01229   return http_parser_parse_resp(parser, m_heap, m_http, start, end, true, eof);
01230 }
01231 
01232 /*-------------------------------------------------------------------------
01233   -------------------------------------------------------------------------*/
01234 
01235 inline bool
01236 HTTPHdr::is_cache_control_set(const char *cc_directive_wks)
01237 {
01238   ink_assert(valid());
01239   ink_assert(hdrtoken_is_wks(cc_directive_wks));
01240 
01241   HdrTokenHeapPrefix *prefix = hdrtoken_wks_to_prefix(cc_directive_wks);
01242   ink_assert(prefix->wks_token_type == HDRTOKEN_TYPE_CACHE_CONTROL);
01243 
01244   uint32_t cc_mask = prefix->wks_type_specific.u.cache_control.cc_mask;
01245   if (get_cooked_cc_mask() & cc_mask)
01246     return (true);
01247   else
01248     return (false);
01249 }
01250 
01251 /*-------------------------------------------------------------------------
01252   -------------------------------------------------------------------------*/
01253 
01254 inline bool
01255 HTTPHdr::is_pragma_no_cache_set()
01256 {
01257   ink_assert(valid());
01258   return (get_cooked_pragma_no_cache());
01259 }
01260 
01261 inline char*
01262 HTTPHdr::url_string_get_ref(int* length)
01263 {
01264   return this->url_string_get(USE_HDR_HEAP_MAGIC, length);
01265 }
01266 
01267 inline char const*
01268 HTTPHdr::path_get(int* length)
01269 {
01270   URL* url = this->url_get();
01271   return url ? url->path_get(length) : 0;
01272 }
01273 
01274 inline char const*
01275 HTTPHdr::scheme_get(int* length)
01276 {
01277   URL* url = this->url_get();
01278   return url ? url->scheme_get(length) : 0;
01279 }
01280 
01281 /*-------------------------------------------------------------------------
01282   -------------------------------------------------------------------------*/
01283 
01284 enum
01285 {
01286   CACHE_ALT_MAGIC_ALIVE = 0xabcddeed,
01287   CACHE_ALT_MAGIC_MARSHALED = 0xdcbadeed,
01288   CACHE_ALT_MAGIC_DEAD = 0xdeadeed
01289 };
01290 
01291 // struct HTTPCacheAlt
01292 struct HTTPCacheAlt
01293 {
01294   HTTPCacheAlt();
01295   void copy(HTTPCacheAlt *to_copy);
01296   void copy_frag_offsets_from(HTTPCacheAlt* src);
01297   void destroy();
01298 
01299   uint32_t m_magic;
01300 
01301   // Writeable is set to true is we reside
01302   //  in a buffer owned by this structure.
01303   // INVARIANT: if own the buffer this HttpCacheAlt
01304   //   we also own the buffers for the request &
01305   //   response headers
01306   int32_t m_writeable;
01307   int32_t m_unmarshal_len;
01308 
01309   int32_t m_id;
01310   int32_t m_rid;
01311 
01312   int32_t m_object_key[4];
01313   int32_t m_object_size[2];
01314 
01315   HTTPHdr m_request_hdr;
01316   HTTPHdr m_response_hdr;
01317 
01318   time_t m_request_sent_time;
01319   time_t m_response_received_time;
01320 
01321   /// # of fragment offsets in this alternate.
01322   /// @note This is one less than the number of fragments.
01323   int m_frag_offset_count;
01324   /// Type of offset for a fragment.
01325   typedef uint64_t FragOffset;
01326   /// Table of fragment offsets.
01327   /// @note The offsets are forward looking so that frag[0] is the
01328   /// first byte past the end of fragment 0 which is also the first
01329   /// byte of fragment 1. For this reason there is no fragment offset
01330   /// for the last fragment.
01331   FragOffset *m_frag_offsets;
01332   /// # of fragment offsets built in to object.
01333   static int const N_INTEGRAL_FRAG_OFFSETS = 4;
01334   /// Integral fragment offset table.
01335   FragOffset m_integral_frag_offsets[N_INTEGRAL_FRAG_OFFSETS];
01336 
01337   // With clustering, our alt may be in cluster
01338   //  incoming channel buffer, when we are
01339   //  destroyed we decrement the refcount
01340   //  on that buffer so that it gets destroyed
01341   // We don't want to use a ref count ptr (Ptr<>)
01342   //  since our ownership model requires explicit
01343   //  destroys and ref count pointers defeat this
01344   RefCountObj *m_ext_buffer;
01345 };
01346 
01347 class HTTPInfo
01348 {
01349 public:
01350   typedef HTTPCacheAlt::FragOffset FragOffset; ///< Import type.
01351 
01352   HTTPCacheAlt *m_alt;
01353 
01354   HTTPInfo()
01355     : m_alt(NULL)
01356   { }
01357 
01358   ~HTTPInfo()
01359   {
01360     clear();
01361   }
01362 
01363   void clear() { m_alt = NULL; }
01364   bool valid() const { return m_alt != NULL; }
01365 
01366   void create();
01367   void destroy();
01368 
01369   void copy(HTTPInfo *to_copy);
01370   void copy_shallow(HTTPInfo *info) { m_alt = info->m_alt; }
01371   void copy_frag_offsets_from(HTTPInfo* src);
01372   HTTPInfo & operator =(const HTTPInfo & m);
01373 
01374   inkcoreapi int marshal_length();
01375   inkcoreapi int marshal(char *buf, int len);
01376   static int unmarshal(char *buf, int len, RefCountObj *block_ref);
01377   void set_buffer_reference(RefCountObj *block_ref);
01378   int get_handle(char *buf, int len);
01379 
01380   int32_t id_get() const { return m_alt->m_id; }
01381   int32_t rid_get() { return m_alt->m_rid; }
01382 
01383   void id_set(int32_t id) { m_alt->m_id = id; }
01384   void rid_set(int32_t id) { m_alt->m_rid = id; }
01385 
01386   INK_MD5 object_key_get();
01387   void object_key_get(INK_MD5 *);
01388   bool compare_object_key(const INK_MD5 *);
01389   int64_t object_size_get();
01390 
01391   void request_get(HTTPHdr *hdr) { hdr->copy_shallow(&m_alt->m_request_hdr); }
01392   void response_get(HTTPHdr *hdr) { hdr->copy_shallow(&m_alt->m_response_hdr); }
01393 
01394   HTTPHdr *request_get() { return &m_alt->m_request_hdr; }
01395   HTTPHdr *response_get() { return &m_alt->m_response_hdr; }
01396 
01397   URL *request_url_get(URL *url = NULL) { return m_alt->m_request_hdr.url_get(url); }
01398 
01399   time_t request_sent_time_get() { return m_alt->m_request_sent_time; }
01400   time_t response_received_time_get() { return m_alt->m_response_received_time; }
01401 
01402   void object_key_set(INK_MD5 & md5);
01403   void object_size_set(int64_t size);
01404 
01405   void request_set(const HTTPHdr *req) { m_alt->m_request_hdr.copy(req); }
01406   void response_set(const HTTPHdr *resp) { m_alt->m_response_hdr.copy(resp); }
01407 
01408   void request_sent_time_set(time_t t) { m_alt->m_request_sent_time = t; }
01409   void response_received_time_set(time_t t) { m_alt->m_response_received_time = t; }
01410 
01411   /// Get the fragment table.
01412   FragOffset* get_frag_table();
01413   /// Get the # of fragment offsets
01414   /// @note This is the size of the fragment offset table, and one less
01415   /// than the actual # of fragments.
01416   int get_frag_offset_count();
01417   /// Add an @a offset to the end of the fragment offset table.
01418   void push_frag_offset(FragOffset offset);
01419 
01420   // Sanity check functions
01421   static bool check_marshalled(char *buf, int len);
01422 
01423 private:
01424   HTTPInfo(const HTTPInfo & h);
01425 };
01426 
01427 inline void
01428 HTTPInfo::destroy()
01429 {
01430   if (m_alt) {
01431     if (m_alt->m_writeable) {
01432       m_alt->destroy();
01433     } else if (m_alt->m_ext_buffer) {
01434       if (m_alt->m_ext_buffer->refcount_dec() == 0) {
01435         m_alt->m_ext_buffer->free();
01436       }
01437     }
01438   }
01439   clear();
01440 }
01441 
01442 inline HTTPInfo &
01443 HTTPInfo::operator =(const HTTPInfo & m)
01444 {
01445   m_alt = m.m_alt;
01446   return *this;
01447 }
01448 
01449 inline INK_MD5
01450 HTTPInfo::object_key_get()
01451 {
01452   INK_MD5 val;
01453   int32_t* pi = reinterpret_cast<int32_t*>(&val);
01454 
01455   pi[0] = m_alt->m_object_key[0];
01456   pi[1] = m_alt->m_object_key[1];
01457   pi[2] = m_alt->m_object_key[2];
01458   pi[3] = m_alt->m_object_key[3];
01459 
01460   return val;
01461 }
01462 
01463 inline void
01464 HTTPInfo::object_key_get(INK_MD5 *md5)
01465 {
01466   int32_t* pi = reinterpret_cast<int32_t*>(md5);
01467   pi[0] = m_alt->m_object_key[0];
01468   pi[1] = m_alt->m_object_key[1];
01469   pi[2] = m_alt->m_object_key[2];
01470   pi[3] = m_alt->m_object_key[3];
01471 }
01472 
01473 inline bool
01474 HTTPInfo::compare_object_key(const INK_MD5 *md5)
01475 {
01476   int32_t const* pi = reinterpret_cast<int32_t const*>(md5);
01477   return ((m_alt->m_object_key[0] == pi[0]) &&
01478           (m_alt->m_object_key[1] == pi[1]) &&
01479           (m_alt->m_object_key[2] == pi[2]) &&
01480           (m_alt->m_object_key[3] == pi[3])
01481          );
01482 }
01483 
01484 inline int64_t
01485 HTTPInfo::object_size_get()
01486 {
01487   int64_t val;
01488   int32_t* pi = reinterpret_cast<int32_t*>(&val);
01489 
01490   pi[0] = m_alt->m_object_size[0];
01491   pi[1] = m_alt->m_object_size[1];
01492   return val;
01493 }
01494 
01495 inline void
01496 HTTPInfo::object_key_set(INK_MD5 & md5)
01497 {
01498   int32_t* pi = reinterpret_cast<int32_t*>(&md5);
01499   m_alt->m_object_key[0] = pi[0];
01500   m_alt->m_object_key[1] = pi[1];
01501   m_alt->m_object_key[2] = pi[2];
01502   m_alt->m_object_key[3] = pi[3];
01503 }
01504 
01505 inline void
01506 HTTPInfo::object_size_set(int64_t size)
01507 {
01508   int32_t* pi = reinterpret_cast<int32_t*>(&size);
01509   m_alt->m_object_size[0] = pi[0];
01510   m_alt->m_object_size[1] = pi[1];
01511 }
01512 
01513 inline HTTPInfo::FragOffset*
01514 HTTPInfo::get_frag_table()
01515 {
01516   return m_alt ? m_alt->m_frag_offsets : 0;
01517 }
01518 
01519 inline int
01520 HTTPInfo::get_frag_offset_count() {
01521   return m_alt ? m_alt->m_frag_offset_count : 0;
01522 }
01523 
01524 
01525 #endif /* __HTTP_H__ */

Generated by  doxygen 1.7.1