00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 #if !defined (_HttpTransact_h_)
00026 #define _HttpTransact_h_
00027 
00028 #include "libts.h"
00029 #include "P_HostDB.h"
00030 #include "P_Net.h"
00031 #include "HttpConfig.h"
00032 #include "HTTP.h"
00033 #include "HttpTransactCache.h"
00034 #include "StatSystem.h"
00035 #include "ControlMatcher.h"
00036 #include "CacheControl.h"
00037 #include "ParentSelection.h"
00038 #include "ProxyConfig.h"
00039 #include "Transform.h"
00040 
00041 #include "api/ts/remap.h"
00042 #include "RemapPluginInfo.h"
00043 #include "UrlMapping.h"
00044 #include <records/I_RecHttp.h>
00045 
00046 #include "congest/Congestion.h"
00047 
00048 #define MAX_DNS_LOOKUPS 2
00049 #define NUM_SECONDS_IN_ONE_YEAR (31536000)      // (365L * 24L * 3600L)
00050 
00051 #define HTTP_RELEASE_ASSERT(X) ink_release_assert(X)
00052 
00053 
00054 #define ACQUIRE_PRINT_LOCK()    //ink_mutex_acquire(&print_lock);
00055 #define RELEASE_PRINT_LOCK()    //ink_mutex_release(&print_lock);
00056 
00057 #define DUMP_HEADER(T,H,I,S) \
00058 { \
00059     if (diags->on(T)) { \
00060     ACQUIRE_PRINT_LOCK() \
00061     fprintf(stderr, "+++++++++ %s +++++++++\n", S); \
00062     fprintf(stderr, "-- State Machine Id: %" PRId64 "\n", I); \
00063         char b[4096]; \
00064         int used, tmp, offset; \
00065         int done; \
00066         offset = 0; \
00067     if ((H)->valid()) { \
00068           do { \
00069               used = 0; \
00070               tmp = offset; \
00071               done = (H)->print (b, 4095, &used, &tmp); \
00072               offset += used; \
00073               b[used] = '\0'; \
00074               fprintf (stderr, "%s", b); \
00075           } while (!done); \
00076         } \
00077     RELEASE_PRINT_LOCK() \
00078     } \
00079 }
00080 
00081 
00082 #define TRANSACT_SETUP_RETURN(n, r) \
00083 s->next_action = n; \
00084 s->transact_return_point = r; \
00085 DebugSpecific((s->state_machine && s->state_machine->debug_on), "http_trans", "Next action %s; %s", #n, #r); \
00086 
00087 #define TRANSACT_RETURN(n, r)  \
00088 TRANSACT_SETUP_RETURN(n, r) \
00089 return; \
00090 
00091 #define TRANSACT_RETURN_VAL(n, r, v) \
00092 TRANSACT_SETUP_RETURN(n, r) \
00093 return v; \
00094 
00095 
00096 #define SET_UNPREPARE_CACHE_ACTION(C) \
00097 { \
00098     if (C.action == HttpTransact::CACHE_PREPARE_TO_DELETE) { \
00099     C.action = HttpTransact::CACHE_DO_DELETE; \
00100     } else if (C.action == HttpTransact::CACHE_PREPARE_TO_UPDATE) { \
00101     C.action = HttpTransact::CACHE_DO_UPDATE; \
00102     } else { \
00103     C.action = HttpTransact::CACHE_DO_WRITE; \
00104     } \
00105 }
00106 
00107 typedef time_t ink_time_t;
00108 
00109 struct HttpConfigParams;
00110 struct MimeTableEntry;
00111 class HttpSM;
00112 
00113 #include "InkErrno.h"
00114 #define UNKNOWN_INTERNAL_ERROR           (INK_START_ERRNO - 1)
00115 
00116 enum ViaStringIndex_t
00117 {
00118   
00119   
00120   VIA_CLIENT = 0,
00121   VIA_CLIENT_REQUEST,
00122   VIA_CACHE,
00123   VIA_CACHE_RESULT,
00124   VIA_SERVER,
00125   VIA_SERVER_RESULT,
00126   VIA_CACHE_FILL,
00127   VIA_CACHE_FILL_ACTION,
00128   VIA_PROXY,
00129   VIA_PROXY_RESULT,
00130   VIA_ERROR,
00131   VIA_ERROR_TYPE,
00132   
00133   
00134   VIA_DETAIL_SEPARATOR,
00135   VIA_DETAIL_TUNNEL_DESCRIPTOR,
00136   VIA_DETAIL_TUNNEL,
00137   VIA_DETAIL_CACHE_DESCRIPTOR,
00138   VIA_DETAIL_CACHE_TYPE,
00139   VIA_DETAIL_CACHE_LOOKUP,
00140   VIA_DETAIL_ICP_DESCRIPTOR,
00141   VIA_DETAIL_ICP_CONNECT,
00142   VIA_DETAIL_PP_DESCRIPTOR,
00143   VIA_DETAIL_PP_CONNECT,
00144   VIA_DETAIL_SERVER_DESCRIPTOR,
00145   VIA_DETAIL_SERVER_CONNECT,
00146   
00147   
00148   MAX_VIA_INDICES
00149 };
00150 
00151 enum ViaString_t
00152 {
00153   
00154   VIA_CLIENT_STRING = 'u',
00155   VIA_CLIENT_ERROR = 'E',
00156   VIA_CLIENT_IMS = 'I',
00157   VIA_CLIENT_NO_CACHE = 'N',
00158   VIA_CLIENT_COOKIE = 'C',
00159   VIA_CLIENT_SIMPLE = 'S',
00160   
00161   VIA_CACHE_STRING = 'c',
00162   VIA_CACHE_MISS = 'M',
00163   VIA_IN_CACHE_NOT_ACCEPTABLE = 'A',
00164   VIA_IN_CACHE_STALE = 'S',
00165   VIA_IN_CACHE_FRESH = 'H',
00166   VIA_IN_RAM_CACHE_FRESH = 'R',
00167   
00168   VIA_SERVER_STRING = 's',
00169   VIA_SERVER_ERROR = 'E',
00170   VIA_SERVER_NOT_MODIFIED = 'N',
00171   VIA_SERVER_SERVED = 'S',
00172   
00173   VIA_CACHE_FILL_STRING = 'f',
00174   VIA_CACHE_DELETED = 'D',
00175   VIA_CACHE_WRITTEN = 'W',
00176   VIA_CACHE_UPDATED = 'U',
00177   
00178   VIA_PROXY_STRING = 'p',
00179   VIA_PROXY_NOT_MODIFIED = 'N',
00180   VIA_PROXY_SERVED = 'S',
00181   VIA_PROXY_SERVER_REVALIDATED = 'R',
00182   
00183   VIA_ERROR_STRING = 'e',
00184   VIA_ERROR_NO_ERROR = 'N',
00185   VIA_ERROR_AUTHORIZATION = 'A',
00186   VIA_ERROR_CONNECTION = 'C',
00187   VIA_ERROR_DNS_FAILURE = 'D',
00188   VIA_ERROR_FORBIDDEN = 'F',
00189   VIA_ERROR_HEADER_SYNTAX = 'H',
00190   VIA_ERROR_SERVER = 'S',
00191   VIA_ERROR_TIMEOUT = 'T',
00192   VIA_ERROR_CACHE_READ = 'R',
00193   
00194   
00195   
00196   VIA_DETAIL_SEPARATOR_STRING = ':',
00197   
00198   VIA_DETAIL_TUNNEL_DESCRIPTOR_STRING = 't',
00199   VIA_DETAIL_TUNNEL_HEADER_FIELD = 'F',
00200   VIA_DETAIL_TUNNEL_METHOD = 'M',
00201   VIA_DETAIL_TUNNEL_CACHE_OFF = 'O',
00202   VIA_DETAIL_TUNNEL_URL = 'U',
00203   VIA_DETAIL_TUNNEL_NO_FORWARD = 'N',
00204   VIA_DETAIL_TUNNEL_AUTHORIZATION = 'A',
00205   
00206   VIA_DETAIL_CACHE_DESCRIPTOR_STRING = 'c',
00207   VIA_DETAIL_CACHE = 'C',
00208   VIA_DETAIL_CLUSTER = 'L',
00209   VIA_DETAIL_ICP = 'I',
00210   VIA_DETAIL_PARENT = 'P',
00211   VIA_DETAIL_SERVER = 'S',
00212   
00213   VIA_DETAIL_HIT_CONDITIONAL = 'N',
00214   VIA_DETAIL_HIT_SERVED = 'H',
00215   VIA_DETAIL_MISS_CONDITIONAL = 'I',
00216   VIA_DETAIL_MISS_NOT_CACHED = 'M',
00217   VIA_DETAIL_MISS_EXPIRED = 'S',
00218   VIA_DETAIL_MISS_CONFIG = 'C',
00219   VIA_DETAIL_MISS_CLIENT = 'U',
00220   VIA_DETAIL_MISS_METHOD = 'D',
00221   VIA_DETAIL_MISS_COOKIE = 'K',
00222   
00223   VIA_DETAIL_ICP_DESCRIPTOR_STRING = 'i',
00224   VIA_DETAIL_ICP_SUCCESS = 'S',
00225   VIA_DETAIL_ICP_FAILURE = 'F',
00226   
00227   VIA_DETAIL_PP_DESCRIPTOR_STRING = 'p',
00228   VIA_DETAIL_PP_SUCCESS = 'S',
00229   VIA_DETAIL_PP_FAILURE = 'F',
00230   
00231   VIA_DETAIL_SERVER_DESCRIPTOR_STRING = 's',
00232   VIA_DETAIL_SERVER_SUCCESS = 'S',
00233   VIA_DETAIL_SERVER_FAILURE = 'F'
00234 };
00235 
00236 typedef struct _HttpApiInfo
00237 {
00238   char *parent_proxy_name;
00239   int parent_proxy_port;
00240   bool cache_untransformed;
00241   bool cache_transformed;
00242   bool logging_enabled;
00243   bool retry_intercept_failures;
00244 
00245   _HttpApiInfo()
00246   : parent_proxy_name(NULL),
00247     parent_proxy_port(-1),
00248     cache_untransformed(false), cache_transformed(true), logging_enabled(true), retry_intercept_failures(false)
00249   { }
00250 } HttpApiInfo;
00251 
00252 enum
00253 {
00254   HTTP_UNDEFINED_CL = -1
00255 };
00256 
00257 
00258 
00259 
00260 
00261 
00262 
00263 
00264 
00265 #define SET_VIA_STRING(I,S) s->via_string[I]=S;
00266 #define GET_VIA_STRING(I) (s->via_string[I])
00267 
00268 class HttpTransact
00269 {
00270 public:
00271   enum UrlRemapMode_t
00272   {
00273     URL_REMAP_DEFAULT = 0,      
00274     URL_REMAP_ALL,
00275     URL_REMAP_FOR_OS
00276   };
00277 
00278   enum AbortState_t
00279   {
00280     ABORT_UNDEFINED = 0,
00281     DIDNOT_ABORT,
00282     MAYBE_ABORTED,
00283     ABORTED
00284   };
00285 
00286   enum Authentication_t
00287   {
00288     AUTHENTICATION_SUCCESS = 0,
00289     AUTHENTICATION_MUST_REVALIDATE,
00290     AUTHENTICATION_MUST_PROXY,
00291     AUTHENTICATION_CACHE_AUTH
00292   };
00293 
00294   enum CacheAction_t
00295   {
00296     CACHE_DO_UNDEFINED = 0,
00297     CACHE_DO_NO_ACTION,
00298     CACHE_DO_DELETE,
00299     CACHE_DO_LOOKUP,
00300     CACHE_DO_REPLACE,
00301     CACHE_DO_SERVE,
00302     CACHE_DO_SERVE_AND_DELETE,
00303     CACHE_DO_SERVE_AND_UPDATE,
00304     CACHE_DO_UPDATE,
00305     CACHE_DO_WRITE,
00306     CACHE_PREPARE_TO_DELETE,
00307     CACHE_PREPARE_TO_UPDATE,
00308     CACHE_PREPARE_TO_WRITE,
00309     TOTAL_CACHE_ACTION_TYPES
00310   };
00311 
00312   enum CacheWriteLock_t
00313   {
00314     CACHE_WL_INIT,
00315     CACHE_WL_SUCCESS,
00316     CACHE_WL_FAIL,
00317     CACHE_WL_READ_RETRY
00318   };
00319 
00320   enum ClientTransactionResult_t
00321   {
00322     CLIENT_TRANSACTION_RESULT_UNDEFINED,
00323     CLIENT_TRANSACTION_RESULT_HIT_FRESH,
00324     CLIENT_TRANSACTION_RESULT_HIT_REVALIDATED,
00325     CLIENT_TRANSACTION_RESULT_MISS_COLD,
00326     CLIENT_TRANSACTION_RESULT_MISS_CHANGED,
00327     CLIENT_TRANSACTION_RESULT_MISS_CLIENT_NO_CACHE,
00328     CLIENT_TRANSACTION_RESULT_MISS_UNCACHABLE,
00329     CLIENT_TRANSACTION_RESULT_ERROR_ABORT,
00330     CLIENT_TRANSACTION_RESULT_ERROR_POSSIBLE_ABORT,
00331     CLIENT_TRANSACTION_RESULT_ERROR_CONNECT_FAIL,
00332     CLIENT_TRANSACTION_RESULT_ERROR_OTHER
00333   };
00334 
00335   enum Freshness_t
00336   {
00337     FRESHNESS_FRESH = 0,        
00338     FRESHNESS_WARNING,          
00339     FRESHNESS_STALE             
00340   };
00341 
00342   enum HostNameExpansionError_t
00343   {
00344     RETRY_EXPANDED_NAME,
00345     EXPANSION_FAILED,
00346     EXPANSION_NOT_ALLOWED,
00347     DNS_ATTEMPTS_EXHAUSTED,
00348     NO_PARENT_PROXY_EXPANSION,
00349     TOTAL_HOST_NAME_EXPANSION_TYPES
00350   };
00351 
00352   enum HttpTransactMagic_t
00353   {
00354     HTTP_TRANSACT_MAGIC_ALIVE = 0x00001234,
00355     HTTP_TRANSACT_MAGIC_DEAD = 0xDEAD1234,
00356     HTTP_TRANSACT_MAGIC_SEPARATOR = 0x12345678
00357   };
00358 
00359   enum LookingUp_t
00360   {
00361     ORIGIN_SERVER,
00362     UNDEFINED_LOOKUP,
00363     ICP_SUGGESTED_HOST,
00364     PARENT_PROXY,
00365     INCOMING_ROUTER,
00366     HOST_NONE
00367   };
00368 
00369   enum ProxyMode_t
00370   {
00371     UNDEFINED_MODE,
00372     GENERIC_PROXY,
00373     TUNNELLING_PROXY
00374   };
00375 
00376   enum RequestError_t
00377   {
00378     NO_REQUEST_HEADER_ERROR,
00379     BAD_HTTP_HEADER_SYNTAX,
00380     BAD_CONNECT_PORT,
00381     FAILED_PROXY_AUTHORIZATION,
00382     METHOD_NOT_SUPPORTED,
00383     MISSING_HOST_FIELD,
00384     NO_POST_CONTENT_LENGTH,
00385     NO_REQUEST_SCHEME,
00386     NON_EXISTANT_REQUEST_HEADER,
00387     SCHEME_NOT_SUPPORTED,
00388     UNACCEPTABLE_TE_REQUIRED,
00389     INVALID_POST_CONTENT_LENGTH,
00390     TOTAL_REQUEST_ERROR_TYPES
00391   };
00392 
00393   enum ResponseError_t
00394   {
00395     NO_RESPONSE_HEADER_ERROR,
00396     BOGUS_OR_NO_DATE_IN_RESPONSE,
00397     CONNECTION_OPEN_FAILED,
00398     MISSING_REASON_PHRASE,
00399     MISSING_STATUS_CODE,
00400     NON_EXISTANT_RESPONSE_HEADER,
00401     NOT_A_RESPONSE_HEADER,
00402     STATUS_CODE_SERVER_ERROR,
00403     TOTAL_RESPONSE_ERROR_TYPES
00404   };
00405 
00406   
00407   
00408   enum ServerState_t
00409   {
00410     STATE_UNDEFINED = 0,
00411     ACTIVE_TIMEOUT,
00412     BAD_INCOMING_RESPONSE,
00413     CONNECTION_ALIVE,
00414     CONNECTION_CLOSED,
00415     CONNECTION_ERROR,
00416     INACTIVE_TIMEOUT,
00417     OPEN_RAW_ERROR,
00418     PARSE_ERROR,
00419     TRANSACTION_COMPLETE,
00420     CONGEST_CONTROL_CONGESTED_ON_F,
00421     CONGEST_CONTROL_CONGESTED_ON_M
00422   };
00423 
00424   enum CacheWriteStatus_t
00425   {
00426     NO_CACHE_WRITE = 0,
00427     CACHE_WRITE_LOCK_MISS,
00428     CACHE_WRITE_IN_PROGRESS,
00429     CACHE_WRITE_ERROR,
00430     CACHE_WRITE_COMPLETE
00431   };
00432 
00433   enum HttpRequestFlavor_t
00434   {
00435     REQ_FLAVOR_INTERCEPTED = 0,
00436     REQ_FLAVOR_REVPROXY = 1,
00437     REQ_FLAVOR_FWDPROXY = 2,
00438     REQ_FLAVOR_SCHEDULED_UPDATE = 3
00439   };
00440 
00441 
00442   
00443 
00444   enum Source_t
00445   {
00446     SOURCE_NONE = 0,
00447     SOURCE_HTTP_ORIGIN_SERVER,
00448     SOURCE_RAW_ORIGIN_SERVER,
00449     SOURCE_CACHE,
00450     SOURCE_TRANSFORM,
00451     SOURCE_INTERNAL             
00452   };
00453 
00454 
00455   
00456   
00457 
00458   enum StateMachineAction_t
00459   {
00460     SM_ACTION_UNDEFINED = 0,
00461 
00462     
00463     SM_ACTION_DNS_LOOKUP,
00464     SM_ACTION_DNS_REVERSE_LOOKUP,
00465 
00466     SM_ACTION_CACHE_LOOKUP,
00467     SM_ACTION_CACHE_ISSUE_WRITE,
00468     SM_ACTION_CACHE_ISSUE_WRITE_TRANSFORM,
00469     SM_ACTION_CACHE_PREPARE_UPDATE,
00470     SM_ACTION_CACHE_ISSUE_UPDATE,
00471 
00472     SM_ACTION_ICP_QUERY,
00473 
00474     SM_ACTION_ORIGIN_SERVER_OPEN,
00475     SM_ACTION_ORIGIN_SERVER_RAW_OPEN,
00476     SM_ACTION_ORIGIN_SERVER_RR_MARK_DOWN,
00477 
00478     SM_ACTION_READ_PUSH_HDR,
00479     SM_ACTION_STORE_PUSH_BODY,
00480 
00481     SM_ACTION_INTERNAL_CACHE_DELETE,
00482     SM_ACTION_INTERNAL_CACHE_NOOP,
00483     SM_ACTION_INTERNAL_CACHE_UPDATE_HEADERS,
00484     SM_ACTION_INTERNAL_CACHE_WRITE,
00485     SM_ACTION_INTERNAL_100_RESPONSE,
00486     SM_ACTION_INTERNAL_REQUEST,
00487     SM_ACTION_SEND_ERROR_CACHE_NOOP,
00488 
00489 #ifdef PROXY_DRAIN
00490     SM_ACTION_DRAIN_REQUEST_BODY,
00491 #endif 
00492 
00493     SM_ACTION_SERVE_FROM_CACHE,
00494     SM_ACTION_SERVER_READ,
00495     SM_ACTION_SERVER_PARSE_NEXT_HDR,
00496     SM_ACTION_TRANSFORM_READ,
00497     SM_ACTION_SSL_TUNNEL,
00498     SM_ACTION_CONTINUE,
00499 
00500     SM_ACTION_API_SM_START,
00501     SM_ACTION_API_READ_REQUEST_HDR,
00502     SM_ACTION_API_PRE_REMAP,
00503     SM_ACTION_API_POST_REMAP,
00504     SM_ACTION_API_OS_DNS,
00505     SM_ACTION_API_SEND_REQUEST_HDR,
00506     SM_ACTION_API_READ_CACHE_HDR,
00507     SM_ACTION_API_CACHE_LOOKUP_COMPLETE,
00508     SM_ACTION_API_READ_RESPONSE_HDR,
00509     SM_ACTION_API_SEND_RESPONSE_HDR,
00510     SM_ACTION_API_SM_SHUTDOWN,
00511 
00512     SM_ACTION_REMAP_REQUEST,
00513     SM_ACTION_POST_REMAP_SKIP,
00514     SM_ACTION_REDIRECT_READ
00515   };
00516 
00517   enum TransferEncoding_t
00518   {
00519     NO_TRANSFER_ENCODING = 0,
00520     CHUNKED_ENCODING,
00521     DEFLATE_ENCODING
00522   };
00523 
00524   enum Variability_t
00525   {
00526     VARIABILITY_NONE = 0,
00527     VARIABILITY_SOME,
00528     VARIABILITY_ALL
00529   };
00530 
00531   struct StatRecord_t
00532   {
00533     uint16_t index;
00534     int64_t increment;
00535   };
00536 
00537   enum CacheLookupResult_t
00538   {
00539     CACHE_LOOKUP_NONE,
00540     CACHE_LOOKUP_MISS,
00541     CACHE_LOOKUP_DOC_BUSY,
00542     CACHE_LOOKUP_HIT_STALE,
00543     CACHE_LOOKUP_HIT_WARNING,
00544     CACHE_LOOKUP_HIT_FRESH,
00545     CACHE_LOOKUP_SKIPPED
00546   };
00547 
00548   enum UpdateCachedObject_t
00549   {
00550     UPDATE_CACHED_OBJECT_NONE,
00551     UPDATE_CACHED_OBJECT_PREPARE,
00552     UPDATE_CACHED_OBJECT_CONTINUE,
00553     UPDATE_CACHED_OBJECT_ERROR,
00554     UPDATE_CACHED_OBJECT_SUCCEED,
00555     UPDATE_CACHED_OBJECT_FAIL
00556   };
00557 
00558   enum LockUrl_t
00559   {
00560     LOCK_URL_FIRST = 0,
00561     LOCK_URL_SECOND,
00562     LOCK_URL_ORIGINAL,
00563     LOCK_URL_DONE,
00564     LOCK_URL_QUIT
00565   };
00566 
00567   enum RangeSetup_t
00568   {
00569     RANGE_NONE = 0,
00570     RANGE_REQUESTED,
00571     RANGE_NOT_SATISFIABLE,
00572     RANGE_NOT_HANDLED,
00573     RANGE_NOT_TRANSFORM_REQUESTED
00574   };
00575   
00576   enum CacheAuth_t
00577   {
00578     CACHE_AUTH_NONE = 0,
00579     
00580     CACHE_AUTH_FRESH,
00581     CACHE_AUTH_STALE,
00582     CACHE_AUTH_SERVE
00583   };
00584 
00585 #define StatBlockEntries 28
00586 
00587   struct StatBlock
00588   {
00589     StatBlock()
00590     {
00591       init();
00592       memset(&stats, 0, sizeof(stats));
00593     };
00594 
00595     void init()
00596     {
00597       next = NULL;
00598       next_insert = 0;
00599     };
00600 
00601     StatRecord_t stats[StatBlockEntries];
00602     StatBlock *next;
00603     uint16_t next_insert;
00604   };
00605 
00606   struct State;
00607   typedef void (*TransactFunc_t) (HttpTransact::State *);
00608 
00609   typedef struct _CacheDirectives
00610   {
00611     bool does_client_permit_lookup;
00612     bool does_client_permit_storing;
00613     bool does_client_permit_dns_storing;
00614     bool does_config_permit_lookup;
00615     bool does_config_permit_storing;
00616     bool does_server_permit_lookup;
00617     bool does_server_permit_storing;
00618 
00619     _CacheDirectives()
00620       : does_client_permit_lookup(true),
00621         does_client_permit_storing(true),
00622         does_client_permit_dns_storing(true),
00623         does_config_permit_lookup(true),
00624         does_config_permit_storing(true), does_server_permit_lookup(true), does_server_permit_storing(true)
00625     { }
00626   } CacheDirectives;
00627 
00628   typedef struct _CacheLookupInfo
00629   {
00630     HttpTransact::CacheAction_t action;
00631     HttpTransact::CacheAction_t transform_action;
00632 
00633     HttpTransact::CacheWriteStatus_t write_status;
00634     HttpTransact::CacheWriteStatus_t transform_write_status;
00635 
00636     URL *lookup_url;
00637     URL lookup_url_storage;
00638     URL original_url;
00639     HTTPInfo *object_read;
00640     HTTPInfo *second_object_read;
00641     HTTPInfo object_store;
00642     HTTPInfo transform_store;
00643     CacheLookupHttpConfig config;
00644     CacheDirectives directives;
00645     int open_read_retries;
00646     int open_write_retries;
00647     CacheWriteLock_t write_lock_state;
00648     int lookup_count;
00649     bool is_ram_cache_hit;
00650 
00651     _CacheLookupInfo()
00652       : action(CACHE_DO_UNDEFINED),
00653         transform_action(CACHE_DO_UNDEFINED),
00654         write_status(NO_CACHE_WRITE),
00655         transform_write_status(NO_CACHE_WRITE),
00656         lookup_url(NULL),
00657         lookup_url_storage(),
00658         original_url(),
00659         object_read(NULL),
00660         second_object_read(NULL),
00661         object_store(),
00662         transform_store(),
00663         config(),
00664         directives(),
00665         open_read_retries(0),
00666         open_write_retries(0),
00667       write_lock_state(CACHE_WL_INIT),
00668       lookup_count(0),
00669       is_ram_cache_hit(false)
00670     { }
00671   } CacheLookupInfo;
00672 
00673   typedef struct _RedirectInfo
00674   {
00675     bool redirect_in_process;
00676     URL original_url;
00677     URL redirect_url;
00678 
00679     _RedirectInfo()
00680       : redirect_in_process(false), original_url(), redirect_url()
00681     { }
00682   } RedirectInfo;
00683 
00684   struct ConnectionAttributes
00685   {
00686     HTTPVersion http_version;
00687     HTTPKeepAlive keep_alive;
00688 
00689     
00690     
00691     bool receive_chunked_response;
00692     bool pipeline_possible;
00693     bool proxy_connect_hdr;
00694 
00695 
00696     int connect_result;
00697     char *name;
00698     bool dns_round_robin;
00699     TransferEncoding_t transfer_encoding;
00700 
00701     IpEndpoint addr;    
00702     
00703     
00704     
00705     
00706     
00707     
00708     
00709     
00710     uint16_t port; 
00711     ServerState_t state;
00712     AbortState_t abort;
00713     HttpProxyPort::TransportType port_attribute;
00714 
00715 
00716     bool is_transparent;
00717 
00718     bool had_connect_fail() const { return 0 != connect_result; }
00719     void clear_connect_fail() { connect_result = 0; }
00720     void set_connect_fail(int e) { connect_result = e; }
00721 
00722     ConnectionAttributes()
00723       : http_version(),
00724         keep_alive(HTTP_KEEPALIVE_UNDEFINED),
00725         receive_chunked_response(false),
00726         pipeline_possible(false),
00727         proxy_connect_hdr(false),
00728         connect_result(0),
00729         name(NULL),
00730         dns_round_robin(false),
00731         transfer_encoding(NO_TRANSFER_ENCODING),
00732         port(0),
00733         state(STATE_UNDEFINED),
00734         abort(ABORT_UNDEFINED),
00735         port_attribute(HttpProxyPort::TRANSPORT_DEFAULT),
00736         is_transparent(false)
00737     {
00738       memset(&addr, 0, sizeof(addr));
00739     }
00740 
00741   };
00742 
00743   typedef struct _CurrentInfo
00744   {
00745     ProxyMode_t mode;
00746     LookingUp_t request_to;
00747     ConnectionAttributes *server;
00748     ink_time_t now;
00749     ServerState_t state;
00750     int attempts;
00751 
00752     _CurrentInfo()
00753       : mode(UNDEFINED_MODE),
00754         request_to(UNDEFINED_LOOKUP), server(NULL), now(0), state(STATE_UNDEFINED), attempts(1)
00755     { };
00756   } CurrentInfo;
00757 
00758   typedef struct _DNSLookupInfo
00759   {
00760     int attempts;
00761 
00762 
00763 
00764 
00765 
00766 
00767 
00768 
00769 
00770 
00771  
00772     enum {
00773       OS_ADDR_TRY_DEFAULT, 
00774       OS_ADDR_TRY_HOSTDB, 
00775       OS_ADDR_TRY_CLIENT, 
00776       OS_ADDR_USE_HOSTDB, 
00777       OS_ADDR_USE_CLIENT 
00778     } os_addr_style;
00779 
00780     bool lookup_success;
00781     char *lookup_name;
00782     char srv_hostname[MAXDNAME];
00783     LookingUp_t looking_up;
00784     bool srv_lookup_success;
00785     short srv_port;
00786     HostDBApplicationInfo srv_app;
00787     
00788 
00789 
00790     bool lookup_validated; 
00791 
00792     _DNSLookupInfo()
00793     : attempts(0), os_addr_style(OS_ADDR_TRY_DEFAULT),
00794         lookup_success(false), lookup_name(NULL), looking_up(UNDEFINED_LOOKUP),
00795         srv_lookup_success(false), srv_port(0), lookup_validated(true)
00796     {
00797       srv_hostname[0] = '\0';
00798       srv_app.allotment.application1 = 0;
00799       srv_app.allotment.application2 = 0;
00800     }
00801   } DNSLookupInfo;
00802 
00803   typedef struct _HeaderInfo
00804   {
00805     HTTPHdr client_request;
00806     HTTPHdr client_response;
00807     HTTPHdr server_request;
00808     HTTPHdr server_response;
00809     HTTPHdr transform_response;
00810     HTTPHdr cache_response;
00811    int64_t request_content_length;
00812     int64_t response_content_length;
00813     int64_t transform_request_cl;
00814     int64_t transform_response_cl;
00815     bool client_req_is_server_style;
00816     bool trust_response_cl;
00817     ResponseError_t response_error;
00818     bool extension_method;
00819     bool request_body_start;
00820 
00821     _HeaderInfo()
00822       : client_request(),
00823         client_response(),
00824         server_request(),
00825         server_response(),
00826         transform_response(),
00827         cache_response(),
00828         request_content_length(HTTP_UNDEFINED_CL),
00829         response_content_length(HTTP_UNDEFINED_CL),
00830         transform_request_cl(HTTP_UNDEFINED_CL),
00831         transform_response_cl(HTTP_UNDEFINED_CL),
00832         client_req_is_server_style(false),
00833         trust_response_cl(false),
00834         response_error(NO_RESPONSE_HEADER_ERROR), extension_method(false), request_body_start(false)
00835     { }
00836   } HeaderInfo;
00837 
00838   typedef struct _SquidLogInfo
00839   {
00840     SquidLogCode log_code;
00841     SquidHierarchyCode hier_code;
00842     SquidHitMissCode hit_miss_code;
00843 
00844     _SquidLogInfo()
00845       : log_code(SQUID_LOG_ERR_UNKNOWN), hier_code(SQUID_HIER_EMPTY),
00846         hit_miss_code(SQUID_MISS_NONE)
00847     { }
00848   } SquidLogInfo;
00849 
00850 
00851 #define HTTP_TRANSACT_STATE_MAX_XBUF_SIZE  (1024*2)     
00852 
00853   struct State
00854   {
00855     HttpTransactMagic_t m_magic;
00856 
00857     HttpSM *state_machine;
00858 
00859     Arena arena;
00860 
00861     HttpConfigParams *http_config_param;
00862     CacheLookupInfo cache_info;
00863     bool force_dns;
00864     DNSLookupInfo dns_info;
00865     RedirectInfo redirect_info;
00866     unsigned int updated_server_version;
00867     bool is_revalidation_necessary;     
00868     bool request_will_not_selfloop;     
00869     ConnectionAttributes client_info;
00870     ConnectionAttributes icp_info;
00871     ConnectionAttributes parent_info;
00872     ConnectionAttributes server_info;
00873     
00874 
00875     Source_t source;
00876     Source_t pre_transform_source;
00877     HttpRequestFlavor_t req_flavor;
00878 
00879     CurrentInfo current;
00880     HeaderInfo hdr_info;
00881     SquidLogInfo squid_codes;
00882     HttpApiInfo api_info;
00883     
00884     
00885     TransactFunc_t pending_work;
00886 
00887     
00888     StateMachineAction_t cdn_saved_next_action;
00889     void (*cdn_saved_transact_return_point) (State* s);
00890     bool cdn_remap_complete;
00891     bool first_dns_lookup;
00892 
00893     ParentConfigParams *parent_params;
00894     ParentResult parent_result;
00895     HttpRequestData request_data;
00896     CacheControlResult cache_control;
00897     CacheLookupResult_t cache_lookup_result;
00898     
00899     bool backdoor_request;      
00900     bool cop_test_page;         
00901 
00902     StateMachineAction_t next_action;   
00903     StateMachineAction_t api_next_action;       
00904     void (*transact_return_point) (HttpTransact::State* s);    
00905 
00906     
00907     bool is_upgrade_request;
00908     void (*post_remap_upgrade_return_point) (HttpTransact::State* s);    
00909     const char *upgrade_token_wks;
00910 
00911     
00912     bool is_websocket;
00913     bool did_upgrade_succeed;
00914 
00915     char *internal_msg_buffer;  
00916     char *internal_msg_buffer_type;     
00917     int64_t internal_msg_buffer_size;       
00918     int64_t internal_msg_buffer_fast_allocator_size;
00919     int64_t internal_msg_buffer_index;      
00920 
00921     bool icp_lookup_success;    
00922     struct sockaddr_in icp_ip_result;   
00923 
00924     int scheme;                 
00925     int next_hop_scheme;        
00926     int orig_scheme;            
00927     int method;
00928     HostDBInfo host_db_info;    
00929     int cause_of_death_errno;   
00930 
00931     ink_time_t client_request_time;     
00932     ink_time_t request_sent_time;       
00933     ink_time_t response_received_time;  
00934     ink_time_t plugin_set_expire_time;
00935 
00936     char via_string[MAX_VIA_INDICES + 1];
00937 
00938     int64_t state_machine_id;
00939 
00940     
00941 
00942     StatBlock first_stats;
00943     StatBlock *current_stats;
00944 
00945     
00946     bool negative_caching;
00947     
00948     bool srv_lookup;
00949     
00950     CacheAuth_t www_auth_content;
00951 
00952     
00953     bool client_connection_enabled;
00954     bool acl_filtering_performed;
00955 
00956     
00957     remap_plugin_info::_tsremap_os_response *fp_tsremap_os_response;
00958     void* remap_plugin_instance;
00959     HTTPStatus http_return_code;
00960     void *user_args[HTTP_SSN_TXN_MAX_USER_ARG];
00961 
00962     int api_txn_active_timeout_value;
00963     int api_txn_connect_timeout_value;
00964     int api_txn_dns_timeout_value;
00965     int api_txn_no_activity_timeout_value;
00966 
00967     
00968     
00969     
00970     
00971     HdrHeapSDKHandle *cache_req_hdr_heap_handle;
00972     HdrHeapSDKHandle *cache_resp_hdr_heap_handle;
00973     bool api_release_server_session;
00974     bool api_cleanup_cache_read;
00975     bool api_server_response_no_store;
00976     bool api_server_response_ignore;
00977     bool api_http_sm_shutdown;
00978     bool api_modifiable_cached_resp;
00979     bool api_server_request_body_set;
00980     bool api_req_cacheable;
00981     bool api_resp_cacheable;
00982     bool api_server_addr_set;
00983     UpdateCachedObject_t api_update_cached_object;
00984     LockUrl_t api_lock_url;
00985     StateMachineAction_t saved_update_next_action;
00986     CacheAction_t saved_update_cache_action;
00987     bool stale_icp_lookup;
00988 
00989     
00990     UrlMappingContainer url_map;
00991     host_hdr_info hh_info;
00992 
00993     
00994     CongestionEntry *pCongestionEntry;
00995     StateMachineAction_t congest_saved_next_action;
00996     int congestion_control_crat;        
00997     int congestion_congested_or_failed;
00998     int congestion_connection_opened;
00999 
01000     bool reverse_proxy;
01001     bool url_remap_success;
01002     char *remap_redirect;
01003     unsigned int filter_mask;
01004 
01005     bool already_downgraded;
01006     URL pristine_url;  
01007     
01008     bool api_skip_all_remapping;
01009     
01010     
01011     RangeSetup_t range_setup;
01012     int64_t num_range_fields;
01013     int64_t range_output_cl;
01014     RangeRecord *ranges;
01015     
01016     OverridableHttpConfigParams *txn_conf;
01017     OverridableHttpConfigParams my_txn_conf; 
01018 
01019     bool transparent_passthrough;
01020     
01021     
01022     void
01023     init()
01024     {
01025       parent_params = ParentConfig::acquire();
01026       current_stats = &first_stats;
01027     }
01028 
01029     
01030     State()
01031       : m_magic(HTTP_TRANSACT_MAGIC_ALIVE), state_machine(NULL), http_config_param(NULL), force_dns(false),
01032         updated_server_version(HostDBApplicationInfo::HTTP_VERSION_UNDEFINED), is_revalidation_necessary(false),
01033         request_will_not_selfloop(false),       
01034         source(SOURCE_NONE),
01035         pre_transform_source(SOURCE_NONE),
01036         req_flavor(REQ_FLAVOR_FWDPROXY),
01037         pending_work(NULL),
01038         cdn_saved_next_action(SM_ACTION_UNDEFINED),
01039         cdn_saved_transact_return_point(NULL),
01040         cdn_remap_complete(false),
01041         first_dns_lookup(true),
01042         parent_params(NULL),
01043         cache_lookup_result(CACHE_LOOKUP_NONE),
01044         backdoor_request(false),
01045         cop_test_page(false),
01046         next_action(SM_ACTION_UNDEFINED),
01047         api_next_action(SM_ACTION_UNDEFINED),
01048         transact_return_point(NULL),
01049         is_upgrade_request(false),
01050         post_remap_upgrade_return_point(NULL),
01051         upgrade_token_wks(NULL),
01052         is_websocket(false),
01053         did_upgrade_succeed(false),
01054         internal_msg_buffer(NULL),
01055         internal_msg_buffer_type(NULL),
01056         internal_msg_buffer_size(0),
01057         internal_msg_buffer_fast_allocator_size(-1),
01058         internal_msg_buffer_index(0),
01059         icp_lookup_success(false),
01060         scheme(-1),
01061         next_hop_scheme(scheme),
01062         orig_scheme(scheme),
01063         method(0),
01064         cause_of_death_errno(-UNKNOWN_INTERNAL_ERROR),
01065         client_request_time(UNDEFINED_TIME),
01066         request_sent_time(UNDEFINED_TIME),
01067         response_received_time(UNDEFINED_TIME),
01068         plugin_set_expire_time(UNDEFINED_TIME),
01069         state_machine_id(0),
01070         first_stats(),
01071         current_stats(NULL),
01072         negative_caching(false),
01073         srv_lookup(false),
01074         www_auth_content(CACHE_AUTH_NONE),
01075         client_connection_enabled(true),
01076         acl_filtering_performed(false),
01077         fp_tsremap_os_response(NULL),
01078         remap_plugin_instance(0),
01079         http_return_code(HTTP_STATUS_NONE),
01080         api_txn_active_timeout_value(-1),
01081         api_txn_connect_timeout_value(-1),
01082         api_txn_dns_timeout_value(-1),
01083         api_txn_no_activity_timeout_value(-1),
01084         cache_req_hdr_heap_handle(NULL),
01085         cache_resp_hdr_heap_handle(NULL),
01086         api_release_server_session(false),
01087         api_cleanup_cache_read(false),
01088         api_server_response_no_store(false),
01089         api_server_response_ignore(false),
01090         api_http_sm_shutdown(false),
01091         api_modifiable_cached_resp(false),
01092         api_server_request_body_set(false),
01093         api_req_cacheable(false),
01094         api_resp_cacheable(false),
01095         api_server_addr_set(false),
01096         api_update_cached_object(UPDATE_CACHED_OBJECT_NONE),
01097         api_lock_url(LOCK_URL_FIRST),
01098         saved_update_next_action(SM_ACTION_UNDEFINED),
01099         saved_update_cache_action(CACHE_DO_UNDEFINED),
01100         stale_icp_lookup(false),
01101         url_map(),
01102         pCongestionEntry(NULL),
01103         congest_saved_next_action(SM_ACTION_UNDEFINED),
01104         congestion_control_crat(0),
01105         congestion_congested_or_failed(0),
01106         congestion_connection_opened(0),
01107         reverse_proxy(false), url_remap_success(false), remap_redirect(NULL), filter_mask(0), already_downgraded(false),
01108         pristine_url(),
01109         api_skip_all_remapping(false),
01110         range_setup(RANGE_NONE),
01111         num_range_fields(0),
01112         range_output_cl(0),
01113         ranges(NULL),
01114         txn_conf(NULL),
01115         transparent_passthrough(false)
01116     {
01117       int i;
01118       char *via_ptr = via_string;
01119 
01120       for (i = 0; i < MAX_VIA_INDICES; i++) {
01121         *via_ptr++ = ' ';
01122       }
01123 
01124       via_string[VIA_CLIENT] = VIA_CLIENT_STRING;
01125       via_string[VIA_CACHE] = VIA_CACHE_STRING;
01126       via_string[VIA_SERVER] = VIA_SERVER_STRING;
01127       via_string[VIA_CACHE_FILL] = VIA_CACHE_FILL_STRING;
01128       via_string[VIA_PROXY] = VIA_PROXY_STRING;
01129       via_string[VIA_ERROR] = VIA_ERROR_STRING;
01130       via_string[VIA_ERROR_TYPE] = VIA_ERROR_NO_ERROR;
01131       via_string[VIA_DETAIL_SEPARATOR] = VIA_DETAIL_SEPARATOR_STRING;
01132       via_string[VIA_DETAIL_TUNNEL_DESCRIPTOR] = VIA_DETAIL_TUNNEL_DESCRIPTOR_STRING;
01133       via_string[VIA_DETAIL_CACHE_DESCRIPTOR] = VIA_DETAIL_CACHE_DESCRIPTOR_STRING;
01134       via_string[VIA_DETAIL_ICP_DESCRIPTOR] = VIA_DETAIL_ICP_DESCRIPTOR_STRING;
01135       via_string[VIA_DETAIL_PP_DESCRIPTOR] = VIA_DETAIL_PP_DESCRIPTOR_STRING;
01136       via_string[VIA_DETAIL_SERVER_DESCRIPTOR] = VIA_DETAIL_SERVER_DESCRIPTOR_STRING;
01137       via_string[MAX_VIA_INDICES] = '\0';
01138 
01139       memset(user_args, 0, sizeof(user_args));
01140       memset(&host_db_info, 0, sizeof(host_db_info));
01141     }
01142 
01143     void
01144     record_transaction_stats()
01145     {
01146       if (http_config_param->enable_http_stats) {
01147         
01148         
01149         STAT_LOCK_ACQUIRE(&(global_http_trans_stat_lock));
01150         StatBlock *b = &first_stats;
01151 
01152         while (b != NULL) {
01153           for (int i = 0; i < b->next_insert && i < StatBlockEntries; i++) {
01154             RecIncrRawStat(http_rsb, this_ethread(), b->stats[i].index, b->stats[i].increment);
01155 
01156           }
01157           b = b->next;
01158         }
01159         STAT_LOCK_RELEASE(&(global_http_trans_stat_lock));
01160       }
01161     }
01162 
01163     void
01164     destroy()
01165     {
01166       record_transaction_stats();
01167       m_magic = HTTP_TRANSACT_MAGIC_DEAD;
01168 
01169       free_internal_msg_buffer();
01170       ats_free(internal_msg_buffer_type);
01171 
01172       ParentConfig::release(parent_params);
01173       parent_params = NULL;
01174 
01175       hdr_info.client_request.destroy();
01176       hdr_info.client_response.destroy();
01177       hdr_info.server_request.destroy();
01178       hdr_info.server_response.destroy();
01179       hdr_info.transform_response.destroy();
01180       hdr_info.cache_response.destroy();
01181       cache_info.lookup_url_storage.destroy();
01182       cache_info.original_url.destroy();
01183       cache_info.object_store.destroy();
01184       cache_info.transform_store.destroy();
01185       redirect_info.original_url.destroy();
01186       redirect_info.redirect_url.destroy();
01187 
01188       if (pCongestionEntry) {
01189         if (congestion_connection_opened == 1) {
01190           pCongestionEntry->connection_closed();
01191           congestion_connection_opened = 0;
01192         }
01193         pCongestionEntry->put(), pCongestionEntry = NULL;
01194       }
01195 
01196       url_map.clear();
01197       arena.reset();
01198       pristine_url.clear();
01199 
01200       delete[] ranges;
01201       ranges = NULL;
01202       range_setup = RANGE_NONE;
01203       return;
01204     }
01205 
01206     
01207     void
01208     setup_per_txn_configs()
01209     {
01210       if (txn_conf != &my_txn_conf) {
01211         
01212         memcpy(&my_txn_conf, &http_config_param->oride, sizeof(my_txn_conf));
01213         txn_conf = &my_txn_conf;
01214       }
01215     }
01216 
01217     void
01218     free_internal_msg_buffer()
01219     {
01220       if (internal_msg_buffer) {
01221         if (internal_msg_buffer_fast_allocator_size >= 0) {
01222           ioBufAllocator[internal_msg_buffer_fast_allocator_size].free_void(internal_msg_buffer);
01223         } else {
01224           ats_free(internal_msg_buffer);
01225         }
01226         internal_msg_buffer = NULL;
01227       }
01228       internal_msg_buffer_size = 0;
01229     }
01230    
01231   }; 
01232 
01233   static void HandleBlindTunnel(State* s);
01234   static void StartRemapRequest(State* s);
01235   static void RemapRequest(State* s);
01236   static void EndRemapRequest(State* s);
01237   static void PerformRemap(State* s);
01238   static void ModifyRequest(State* s);
01239   static void HandleRequest(State* s);
01240   static bool handleIfRedirect(State* s);
01241 
01242   static void StartAccessControl(State* s);
01243   static void StartAuth(State* s);
01244   static void HandleRequestAuthorized(State* s);
01245   static void BadRequest(State* s);
01246   static void HandleFiltering(State* s);
01247   static void DecideCacheLookup(State* s);
01248   static void LookupSkipOpenServer(State* s);
01249 
01250   static void CallOSDNSLookup(State* s);
01251   static void OSDNSLookup(State* s);
01252   static void ReDNSRoundRobin(State* s);
01253   static void PPDNSLookup(State* s);
01254   static void HandleAuth(State* s);
01255   static void HandleAuthFailed(State* s);
01256   static void OriginServerRawOpen(State* s);
01257   static void HandleCacheOpenRead(State* s);
01258   static void HandleCacheOpenReadHitFreshness(State* s);
01259   static void HandleCacheOpenReadHit(State* s);
01260   static void HandleCacheOpenReadMiss(State* s);
01261   static void build_response_from_cache(State* s, HTTPWarningCode warning_code);
01262   static void handle_cache_write_lock(State* s);
01263   static void HandleICPLookup(State* s);
01264   static void HandleResponse(State* s);
01265   static void HandleUpdateCachedObject(State* s);
01266   static void HandleUpdateCachedObjectContinue(State* s);
01267   static void HandleStatPage(State* s);
01268   static void handle_100_continue_response(State* s);
01269   static void handle_transform_ready(State* s);
01270   static void handle_transform_cache_write(State* s);
01271   static void handle_response_from_icp_suggested_host(State* s);
01272   static void handle_response_from_parent(State* s);
01273   static void handle_response_from_server(State* s);
01274   static void delete_server_rr_entry(State* s, int max_retries);
01275   static void retry_server_connection_not_open(State* s, ServerState_t conn_state, int max_retries);
01276   static void handle_server_connection_not_open(State* s);
01277   static void handle_forward_server_connection_open(State* s);
01278   static void handle_cache_operation_on_forward_server_response(State* s);
01279   static void handle_no_cache_operation_on_forward_server_response(State* s);
01280   static void merge_and_update_headers_for_cache_update(State* s);
01281   static void set_headers_for_cache_write(State* s, HTTPInfo* cache_info, HTTPHdr* request, HTTPHdr* response);
01282   static void set_header_for_transform(State* s, HTTPHdr* base_header);
01283   static void merge_response_header_with_cached_header(HTTPHdr* cached_header, HTTPHdr* response_header);
01284   static void merge_warning_header(HTTPHdr* cached_header, HTTPHdr* response_header);
01285   static void SetCacheFreshnessLimit(State* s);
01286   static void HandleApiErrorJump(State *);
01287   static void handle_websocket_upgrade_pre_remap(State *s);
01288   static void handle_websocket_upgrade_post_remap(State *s);
01289   static bool handle_upgrade_request(State *s);
01290   static void handle_websocket_connection(State *s);
01291 
01292   static void HandleCacheOpenReadPush(State* s, bool read_successful);
01293   static void HandlePushResponseHdr(State* s);
01294   static void HandlePushCacheWrite(State* s);
01295   static void HandlePushTunnelSuccess(State* s);
01296   static void HandlePushTunnelFailure(State* s);
01297   static void HandlePushError(State *s, const char *reason);
01298   static void HandleBadPushRespHdr(State* s);
01299 
01300   
01301   static void issue_revalidate(State* s);
01302   static void get_ka_info_from_host_db(State* s, ConnectionAttributes* server_info, ConnectionAttributes* client_info,
01303                                        HostDBInfo* host_db_info);
01304   static bool service_transaction_in_proxy_only_mode(State* s);
01305   static void setup_plugin_request_intercept(State* s);
01306   static void add_client_ip_to_outgoing_request(State* s, HTTPHdr* request);
01307   static RequestError_t check_request_validity(State* s, HTTPHdr* incoming_hdr);
01308   static ResponseError_t check_response_validity(State* s, HTTPHdr* incoming_hdr);
01309   static bool delete_all_document_alternates_and_return(State* s, bool cache_hit);
01310   static bool did_forward_server_send_0_9_response(State* s);
01311   static bool does_client_request_permit_cached_response(const OverridableHttpConfigParams *p, CacheControlResult *c,
01312                                                          HTTPHdr *h, char *via_string);
01313   static bool does_client_request_permit_dns_caching(CacheControlResult* c, HTTPHdr* h);
01314   static bool does_client_request_permit_storing(CacheControlResult* c, HTTPHdr* h);
01315   static bool handle_internal_request(State* s, HTTPHdr* incoming_hdr);
01316   static bool handle_trace_and_options_requests(State* s, HTTPHdr* incoming_hdr);
01317   static void bootstrap_state_variables_from_request(State* s, HTTPHdr* incoming_request);
01318   static void initialize_state_variables_for_origin_server(State* s, HTTPHdr* incoming_request, bool second_time);
01319   static void initialize_state_variables_from_request(State* s, HTTPHdr* obsolete_incoming_request);
01320   static void initialize_state_variables_from_response(State* s, HTTPHdr* incoming_response);
01321   static bool is_server_negative_cached(State* s);
01322   static bool is_cache_response_returnable(State* s);
01323   static bool is_stale_cache_response_returnable(State* s);
01324   static bool need_to_revalidate(State* s);
01325   static bool url_looks_dynamic(URL* url);
01326   static bool is_request_cache_lookupable(State* s);
01327   static bool is_request_valid(State* s, HTTPHdr* incoming_request);
01328   static bool is_request_retryable(State* s);
01329 
01330   static bool is_response_cacheable(State* s, HTTPHdr* request, HTTPHdr* response);
01331   static bool is_response_valid(State* s, HTTPHdr* incoming_response);
01332 
01333   static void process_quick_http_filter(State* s, int method);
01334   static bool perform_accept_encoding_filtering(State* s);
01335 
01336   static HostNameExpansionError_t try_to_expand_host_name(State* s);
01337 
01338   static bool setup_auth_lookup(State* s);
01339   static bool will_this_request_self_loop(State* s);
01340   static bool is_request_likely_cacheable(State* s, HTTPHdr* request);
01341 
01342   static void build_request(State* s, HTTPHdr* base_request, HTTPHdr* outgoing_request, HTTPVersion outgoing_version);
01343   static void build_response(State* s, HTTPHdr* base_response, HTTPHdr* outgoing_response, HTTPVersion outgoing_version,
01344                              HTTPStatus status_code, const char *reason_phrase = NULL);
01345   static void build_response(State* s, HTTPHdr* base_response, HTTPHdr* outgoing_response, HTTPVersion outgoing_version);
01346   static void build_response(State* s, HTTPHdr* outgoing_response, HTTPVersion outgoing_version, HTTPStatus status_code,
01347                              const char *reason_phrase = NULL);
01348 
01349   static void build_response_copy(State* s, HTTPHdr* base_response, HTTPHdr* outgoing_response, HTTPVersion outgoing_version);
01350   static void handle_content_length_header(State* s, HTTPHdr* header, HTTPHdr* base);
01351   static void change_response_header_because_of_range_request(State* s, HTTPHdr* header);
01352 
01353   static void handle_request_keep_alive_headers(State *s, HTTPVersion ver, HTTPHdr *heads);
01354   static void handle_response_keep_alive_headers(State *s, HTTPVersion ver, HTTPHdr *heads);
01355   static int calculate_document_freshness_limit(State *s, HTTPHdr *response, time_t response_date, bool *heuristic);
01356   static int calculate_freshness_fuzz(State *s, int fresh_limit);
01357   static Freshness_t what_is_document_freshness(State *s, HTTPHdr *client_request, HTTPHdr *cached_obj_response);
01358   static Authentication_t AuthenticationNeeded(const OverridableHttpConfigParams *p, HTTPHdr *client_request, HTTPHdr *obj_response);
01359   static void handle_parent_died(State* s);
01360   static void handle_server_died(State* s);
01361   static void build_error_response(State *s, HTTPStatus status_code, const char *reason_phrase_or_null, const char *error_body_type,
01362                                    const char *format, ...);
01363   static void build_redirect_response(State* s);
01364   static const char *get_error_string(int erno);
01365 
01366   
01367   static void update_stat(State* s, int stat, ink_statval_t increment);
01368   static void update_size_and_time_stats(State* s, ink_hrtime total_time, ink_hrtime user_agent_write_time,
01369                                          ink_hrtime origin_server_read_time, int user_agent_request_header_size,
01370                                          int64_t user_agent_request_body_size, int user_agent_response_header_size,
01371                                          int64_t user_agent_response_body_size, int origin_server_request_header_size,
01372                                          int64_t origin_server_request_body_size, int origin_server_response_header_size,
01373                                          int64_t origin_server_response_body_size, int pushed_response_header_size,
01374                                          int64_t pushed_response_body_size);
01375   static void histogram_request_document_size(State* s, int64_t size);
01376   static void histogram_response_document_size(State* s, int64_t size);
01377   static void user_agent_connection_speed(State* s, ink_hrtime transfer_time, int64_t nbytes);
01378   static void origin_server_connection_speed(State* s, ink_hrtime transfer_time, int64_t nbytes);
01379   static void client_result_stat(State* s, ink_hrtime total_time, ink_hrtime request_process_time);
01380   static void add_new_stat_block(State* s);
01381   static void delete_warning_value(HTTPHdr* to_warn, HTTPWarningCode warning_code);
01382   static bool is_connection_collapse_checks_success(State* s); 
01383 };
01384 
01385 typedef void (*TransactEntryFunc_t) (HttpTransact::State* s);
01386 
01387 inline bool
01388 is_response_body_precluded(HTTPStatus status_code, int method)
01389 {
01390 
01391 
01392   
01393   
01394   
01395   
01396   
01397   
01398   
01399 
01400 
01401   if (((status_code != HTTP_STATUS_OK) &&
01402        ((status_code == HTTP_STATUS_NOT_MODIFIED) ||
01403         ((status_code<HTTP_STATUS_OK) && (status_code>= HTTP_STATUS_CONTINUE)) ||
01404         (status_code == 204))) || (method == HTTP_WKSIDX_HEAD)) {
01405     return true;
01406   } else {
01407     return false;
01408   }
01409 }
01410 
01411 inkcoreapi extern ink_time_t ink_cluster_time(void);
01412 
01413 inline void
01414 HttpTransact::update_stat(State* s, int stat, ink_statval_t increment)
01415 {
01416   if (s->current_stats->next_insert >= StatBlockEntries) {
01417     
01418     
01419     
01420     add_new_stat_block(s);
01421   }
01422 
01423   uint16_t *next_insert = &s->current_stats->next_insert;
01424   s->current_stats->stats[*next_insert].index = stat;
01425   s->current_stats->stats[*next_insert].increment = increment;
01426   (*next_insert)++;
01427 }
01428 
01429 #endif