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