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

HttpTransact.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 
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 //#include "HttpAuthParams.h"
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 // #define ink_cluster_time(X) time(X)
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   // General information
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   // State Machine specific details
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   // Total
00148   MAX_VIA_INDICES
00149 };
00150 
00151 enum ViaString_t
00152 {
00153   // client stuff
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   // cache lookup stuff
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   // server stuff
00168   VIA_SERVER_STRING = 's',
00169   VIA_SERVER_ERROR = 'E',
00170   VIA_SERVER_NOT_MODIFIED = 'N',
00171   VIA_SERVER_SERVED = 'S',
00172   // cache fill stuff
00173   VIA_CACHE_FILL_STRING = 'f',
00174   VIA_CACHE_DELETED = 'D',
00175   VIA_CACHE_WRITTEN = 'W',
00176   VIA_CACHE_UPDATED = 'U',
00177   // proxy stuff
00178   VIA_PROXY_STRING = 'p',
00179   VIA_PROXY_NOT_MODIFIED = 'N',
00180   VIA_PROXY_SERVED = 'S',
00181   VIA_PROXY_SERVER_REVALIDATED = 'R',
00182   // errors
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   // Now the detailed stuff
00195   //
00196   VIA_DETAIL_SEPARATOR_STRING = ':',
00197   // tunnelling
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   // cache type
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   // result of cache lookup
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   // result of icp suggested host lookup
00223   VIA_DETAIL_ICP_DESCRIPTOR_STRING = 'i',
00224   VIA_DETAIL_ICP_SUCCESS = 'S',
00225   VIA_DETAIL_ICP_FAILURE = 'F',
00226   // result of pp suggested host lookup
00227   VIA_DETAIL_PP_DESCRIPTOR_STRING = 'p',
00228   VIA_DETAIL_PP_SUCCESS = 'S',
00229   VIA_DETAIL_PP_FAILURE = 'F',
00230   // result of server suggested host lookup
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 //  HttpTransact
00260 //
00261 //  The HttpTransact class is purely used for scoping and should
00262 //  not be instantiated.
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,      // which is the same as URL_REMAP_ALL
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,        // Fresh enough, serve it
00338     FRESHNESS_WARNING,          // Stale, but client says OK
00339     FRESHNESS_STALE             // Stale, don't use
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   // Please do not forget to fix TSServerState (ts/ts.h)
00407   // in case of any modifications in ServerState_t
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   // source //
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             // generated from text buffer
00452   };
00453 
00454   ////////////////////////////////////////////////
00455   // HttpTransact fills a StateMachineAction_t  //
00456   // to tell the state machine what to do next. //
00457   ////////////////////////////////////////////////
00458   enum StateMachineAction_t
00459   {
00460     SM_ACTION_UNDEFINED = 0,
00461 
00462     // SM_ACTION_AUTH_LOOKUP,
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 /* PROXY_DRAIN */
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     //CACHE_AUTH_TRUE,
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     // The following variable is true if the client expects to
00690     // received a chunked response.
00691     bool receive_chunked_response;
00692     bool pipeline_possible;
00693     bool proxy_connect_hdr;
00694     /// @c errno from the most recent attempt to connect.
00695     /// zero means no failure (not attempted, succeeded).
00696     int connect_result;
00697     char *name;
00698     bool dns_round_robin;
00699     TransferEncoding_t transfer_encoding;
00700 
00701     IpEndpoint addr;    // replaces 'ip' field
00702     
00703     // port to connect to, except for client
00704     // connection where it is port on proxy
00705     // that client connected to.
00706     // This field is managed separately from the port
00707     // part of 'addr' above as in various cases the two
00708     // are set/manipulated independently and things are
00709     // clearer this way.
00710     uint16_t port; // host order.
00711     ServerState_t state;
00712     AbortState_t abort;
00713     HttpProxyPort::TransportType port_attribute;
00714 
00715     /// @c true if the connection is transparent.
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     /** Origin server address source selection.
00762 
00763         If config says to use CTA (client target addr) state is
00764         OS_ADDR_TRY_CLIENT, otherwise it remains the default. If the
00765         connect fails then we switch to a USE. We go to USE_HOSTDB if
00766         (1) the HostDB lookup is successful and (2) some address other
00767         than the CTA is available to try. Otherwise we keep retrying
00768         on the CTA (USE_CLIENT) up to the max retry value.  In essence
00769         we try to treat the CTA as if it were another RR value in the
00770         HostDB record.
00771      */ 
00772     enum {
00773       OS_ADDR_TRY_DEFAULT, ///< Initial state, use what config says.
00774       OS_ADDR_TRY_HOSTDB, ///< Try HostDB data.
00775       OS_ADDR_TRY_CLIENT, ///< Try client target addr.
00776       OS_ADDR_USE_HOSTDB, ///< Force use of HostDB target address.
00777       OS_ADDR_USE_CLIENT ///< Use client target addr, no fallback.
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     /*** Set to true by default.  If use_client_target_address is set 
00788      * to 1, this value will be set to false if the client address is 
00789      * not in the DNS pool */
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)     /* max size of plugin exchange buffer */
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;     //Added to check if revalidation is necessary - YTS Team, yamsat
00868     bool request_will_not_selfloop;     // To determine if process done - YTS Team, yamsat
00869     ConnectionAttributes client_info;
00870     ConnectionAttributes icp_info;
00871     ConnectionAttributes parent_info;
00872     ConnectionAttributes server_info;
00873     // ConnectionAttributes     router_info;
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     // To handle parent proxy case, we need to be
00884     //  able to defer some work in building the request
00885     TransactFunc_t pending_work;
00886 
00887     // Sandbox of Variables
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     // FilterResult             content_control;
00899     bool backdoor_request;      // internal
00900     bool cop_test_page;         // internal
00901 
00902     StateMachineAction_t next_action;   // out
00903     StateMachineAction_t api_next_action;       // out
00904     void (*transact_return_point) (HttpTransact::State* s);    // out
00905 
00906     // We keep this so we can jump back to the upgrade handler after remap is complete
00907     bool is_upgrade_request;
00908     void (*post_remap_upgrade_return_point) (HttpTransact::State* s);    // out
00909     const char *upgrade_token_wks;
00910 
00911     // Some WebSocket state
00912     bool is_websocket;
00913     bool did_upgrade_succeed;
00914 
00915     char *internal_msg_buffer;  // out
00916     char *internal_msg_buffer_type;     // out
00917     int64_t internal_msg_buffer_size;       // out
00918     int64_t internal_msg_buffer_fast_allocator_size;
00919     int64_t internal_msg_buffer_index;      // out
00920 
00921     bool icp_lookup_success;    // in
00922     struct sockaddr_in icp_ip_result;   // in
00923 
00924     int scheme;                 // out
00925     int next_hop_scheme;        // out
00926     int orig_scheme;            // pre-mapped scheme
00927     int method;
00928     HostDBInfo host_db_info;    // in
00929     int cause_of_death_errno;   // in
00930 
00931     ink_time_t client_request_time;     // internal
00932     ink_time_t request_sent_time;       // internal
00933     ink_time_t response_received_time;  // internal
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     //HttpAuthParams auth_params;
00941 
00942     StatBlock first_stats;
00943     StatBlock *current_stats;
00944 
00945     // for negative caching
00946     bool negative_caching;
00947     // for srv_lookup
00948     bool srv_lookup;
00949     // for authenticated content caching
00950     CacheAuth_t www_auth_content;
00951 
00952     // new ACL filtering result (calculated immediately after remap)
00953     bool client_connection_enabled;
00954     bool acl_filtering_performed;
00955 
00956     // INK API/Remap API plugin interface
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     // Used by INKHttpTxnCachedReqGet and INKHttpTxnCachedRespGet SDK functions
00968     // to copy part of HdrHeap (only the writable portion) for cached response headers
00969     // and request headers
00970     // These ptrs are deallocate when transaction is over.
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     // Remap plugin processor support
00990     UrlMappingContainer url_map;
00991     host_hdr_info hh_info;
00992 
00993     // congestion control
00994     CongestionEntry *pCongestionEntry;
00995     StateMachineAction_t congest_saved_next_action;
00996     int congestion_control_crat;        // 'client retry after'
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;  // pristine url is the url before remap
01007     
01008     bool api_skip_all_remapping;
01009     
01010     // Http Range: related variables
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; // Storage for plugins, to avoid malloc
01018 
01019     bool transparent_passthrough;
01020     
01021     // Methods
01022     void
01023     init()
01024     {
01025       parent_params = ParentConfig::acquire();
01026       current_stats = &first_stats;
01027     }
01028 
01029     // Constructor
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),       //YTS Team, yamsat
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         // Loop over our transaction stat blocks and record the stats
01148         //  in the global arrays
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     // Little helper function to setup the per-transaction configuration copy
01207     void
01208     setup_per_txn_configs()
01209     {
01210       if (txn_conf != &my_txn_conf) {
01211         // Make sure we copy it first.
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   }; // End of State struct.
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   // Utility Methods
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   // the stat functions
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); //YTS Team, yamsat
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   // the spec says about message body the following:    //
01393   // All responses to the HEAD request method MUST NOT  //
01394   // include a message-body, even though the presence   //
01395   // of entity-header fields might lead one to believe  //
01396   // they do. All 1xx (informational), 204 (no content),//
01397   // and 304 (not modified) responses MUST NOT include  //
01398   // a message-body.                                    //
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     // This a rare operation and we want to avoid the
01418     //   code bloat of inlining it everywhere so
01419     //   it's a function call
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

Generated by  doxygen 1.7.1