1 /** @file
2
3 A brief file description
4
5 @section license License
6
7 Licensed to the Apache Software Foundation (ASF) under one
8 or more contributor license agreements. See the NOTICE file
9 distributed with this work for additional information
10 regarding copyright ownership. The ASF licenses this file
11 to you under the Apache License, Version 2.0 (the
12 "License"); you may not use this file except in compliance
13 with the License. You may obtain a copy of the License at
14
15 http://www.apache.org/licenses/LICENSE-2.0
16
17 Unless required by applicable law or agreed to in writing, software
18 distributed under the License is distributed on an "AS IS" BASIS,
19 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 See the License for the specific language governing permissions and
21 limitations under the License.
22 */
23
24 /****************************************************************************
25
26 HttpSM.h
27
28 Description:
29
30
31 ****************************************************************************/
32 #pragma once
33
34 #include <string_view>
35 #include <optional>
36
37 #include "tscore/ink_platform.h"
38 #include "P_EventSystem.h"
39 #include "HttpCacheSM.h"
40 #include "HttpTransact.h"
41 #include "UrlRewrite.h"
42 #include "HttpTunnel.h"
43 #include "InkAPIInternal.h"
44 #include "../ProxyTransaction.h"
45 #include "HdrUtils.h"
46 #include "tscore/History.h"
47
48 #define HTTP_API_CONTINUE (INK_API_EVENT_EVENTS_START + 0)
49 #define HTTP_API_ERROR (INK_API_EVENT_EVENTS_START + 1)
50
51 // The default size for http header buffers when we don't
52 // need to include extra space for the document
53 static size_t const HTTP_HEADER_BUFFER_SIZE_INDEX = CLIENT_CONNECTION_FIRST_READ_BUFFER_SIZE_INDEX;
54
55 // We want to use a larger buffer size when reading response
56 // headers from the origin server since we want to get
57 // as much of the document as possible on the first read
58 // Marco benchmarked about 3% ops/second improvement using
59 // the larger buffer size
60 static size_t const HTTP_SERVER_RESP_HDR_BUFFER_INDEX = BUFFER_SIZE_INDEX_8K;
61
62 class Http1ServerSession;
63 class AuthHttpAdapter;
64
65 class HttpSM;
66 typedef int (HttpSM::*HttpSMHandler)(int event, void *data);
67
68 enum HttpVC_t {
69 HTTP_UNKNOWN = 0,
70 HTTP_UA_VC,
71 HTTP_SERVER_VC,
72 HTTP_TRANSFORM_VC,
73 HTTP_CACHE_READ_VC,
74 HTTP_CACHE_WRITE_VC,
75 HTTP_RAW_SERVER_VC
76 };
77
78 enum BackgroundFill_t {
79 BACKGROUND_FILL_NONE = 0,
80 BACKGROUND_FILL_STARTED,
81 BACKGROUND_FILL_ABORTED,
82 BACKGROUND_FILL_COMPLETED,
83 };
84
85 extern ink_mutex debug_sm_list_mutex;
86
87 struct HttpVCTableEntry {
88 VConnection *vc;
89 MIOBuffer *read_buffer;
90 MIOBuffer *write_buffer;
91 VIO *read_vio;
92 VIO *write_vio;
93 HttpSMHandler vc_handler;
94 HttpVC_t vc_type;
95 HttpSM *sm;
96 bool eos;
97 bool in_tunnel;
98 };
99
100 struct HttpVCTable {
101 static const int vc_table_max_entries = 4;
102 explicit HttpVCTable(HttpSM *);
103
104 HttpVCTableEntry *new_entry();
105 HttpVCTableEntry *find_entry(VConnection *);
106 HttpVCTableEntry *find_entry(VIO *);
107 void remove_entry(HttpVCTableEntry *);
108 void cleanup_entry(HttpVCTableEntry *);
109 void cleanup_all();
110 bool is_table_clear() const;
111
112 private:
113 HttpVCTableEntry vc_table[vc_table_max_entries];
114 HttpSM *sm = nullptr;
115 };
116
117 inline bool
is_table_clear()118 HttpVCTable::is_table_clear() const
119 {
120 for (const auto &i : vc_table) {
121 if (i.vc != nullptr) {
122 return false;
123 }
124 }
125 return true;
126 }
127
128 struct HttpTransformInfo {
129 HttpVCTableEntry *entry = nullptr;
130 VConnection *vc = nullptr;
131
HttpTransformInfoHttpTransformInfo132 HttpTransformInfo() {}
133 };
134
135 enum {
136 HTTP_SM_MAGIC_ALIVE = 0x0000FEED,
137 HTTP_SM_MAGIC_DEAD = 0xDEADFEED,
138 };
139
140 enum {
141 HTTP_SM_POST_UNKNOWN = 0,
142 HTTP_SM_POST_UA_FAIL = 1,
143 HTTP_SM_POST_SERVER_FAIL = 2,
144 HTTP_SM_POST_SUCCESS = 3,
145 };
146
147 enum {
148 HTTP_SM_TRANSFORM_OPEN = 0,
149 HTTP_SM_TRANSFORM_CLOSED = 1,
150 HTTP_SM_TRANSFORM_FAIL = 2,
151 };
152
153 enum HttpApiState_t {
154 HTTP_API_NO_CALLOUT,
155 HTTP_API_IN_CALLOUT,
156 HTTP_API_DEFERED_CLOSE,
157 HTTP_API_DEFERED_SERVER_ERROR,
158 HTTP_API_REWIND_STATE_MACHINE,
159 };
160
161 enum HttpPluginTunnel_t {
162 HTTP_NO_PLUGIN_TUNNEL = 0,
163 HTTP_PLUGIN_AS_SERVER,
164 HTTP_PLUGIN_AS_INTERCEPT,
165 };
166
167 class CoreUtils;
168 class PluginVCCore;
169
170 class PendingAction
171 {
172 public:
173 bool
is_empty()174 is_empty() const
175 {
176 return pending_action == nullptr;
177 }
178 PendingAction &
179 operator=(Action *b)
180 {
181 // Don't do anything if the new action is _DONE
182 if (b != ACTION_RESULT_DONE) {
183 if (b != pending_action && pending_action != nullptr) {
184 pending_action->cancel();
185 }
186 pending_action = b;
187 }
188 return *this;
189 }
190 Continuation *
get_continuation()191 get_continuation() const
192 {
193 return pending_action ? pending_action->continuation : nullptr;
194 }
195 Action *
get()196 get() const
197 {
198 return pending_action;
199 }
200 void
clear_if_action_is(Action * current_action)201 clear_if_action_is(Action *current_action)
202 {
203 if (current_action == pending_action) {
204 pending_action = nullptr;
205 }
206 }
~PendingAction()207 ~PendingAction()
208 {
209 if (pending_action) {
210 pending_action->cancel();
211 }
212 }
213
214 private:
215 Action *pending_action = nullptr;
216 };
217
218 class PostDataBuffers
219 {
220 public:
PostDataBuffers()221 PostDataBuffers() { Debug("http_redirect", "[PostDataBuffers::PostDataBuffers]"); }
222 MIOBuffer *postdata_copy_buffer = nullptr;
223 IOBufferReader *postdata_copy_buffer_start = nullptr;
224 IOBufferReader *ua_buffer_reader = nullptr;
225 bool post_data_buffer_done = false;
226
227 void clear();
228 void init(IOBufferReader *ua_reader);
229 void copy_partial_post_data();
230 IOBufferReader *get_post_data_buffer_clone_reader();
231 void
set_post_data_buffer_done(bool done)232 set_post_data_buffer_done(bool done)
233 {
234 post_data_buffer_done = done;
235 }
236 bool
get_post_data_buffer_done()237 get_post_data_buffer_done()
238 {
239 return post_data_buffer_done;
240 }
241 bool
is_valid()242 is_valid()
243 {
244 return postdata_copy_buffer_start != nullptr;
245 }
246
247 ~PostDataBuffers();
248 };
249
250 class HttpSM : public Continuation, public PluginUserArgs<TS_USER_ARGS_TXN>
251 {
252 friend class HttpPagesHandler;
253 friend class CoreUtils;
254
255 public:
256 HttpSM();
257 void cleanup();
258 virtual void destroy();
259
260 static HttpSM *allocate();
261 HttpCacheSM &get_cache_sm(); // Added to get the object of CacheSM YTS Team, yamsat
262 std::string_view get_outbound_sni() const;
263 std::string_view get_outbound_cert() const;
264
265 void init(bool from_early_data = false);
266
267 void attach_client_session(ProxyTransaction *client_vc_arg, IOBufferReader *buffer_reader);
268
269 // Called by httpSessionManager so that we can reset
270 // the session timeouts and initiate a read while
271 // holding the lock for the server session
272 void attach_server_session(PoolableSession *s);
273
274 // Used to read attributes of
275 // the current active server session
276 PoolableSession *get_server_session() const;
277
278 ProxyTransaction *
get_ua_txn()279 get_ua_txn()
280 {
281 return ua_txn;
282 }
283
284 // Called by transact. Updates are fire and forget
285 // so there are no callbacks and are safe to do
286 // directly from transact
287 void do_hostdb_update_if_necessary();
288
289 // Look at the configured policy and the current server connect_result
290 // to deterine whether this connection attempt should contribute to the
291 // dead server count
292 bool track_connect_fail() const;
293
294 // Called by transact. Decide if cached response supports Range and
295 // setup Range transfomration if so.
296 // return true when the Range is unsatisfiable
297 void do_range_setup_if_necessary();
298
299 void do_range_parse(MIMEField *range_field);
300 void calculate_output_cl(int64_t, int64_t);
301 void parse_range_and_compare(MIMEField *, int64_t);
302
303 // Called by transact to prevent reset problems
304 // failed PUSH requests
305 void set_ua_half_close_flag();
306
307 // Called by either state_hostdb_lookup() or directly
308 // by the HostDB in the case of inline completion
309 // Handles the setting of all state necessary before
310 // calling transact to process the hostdb lookup
311 // A NULL 'r' argument indicates the hostdb lookup failed
312 void process_hostdb_info(HostDBInfo *r);
313 void process_srv_info(HostDBInfo *r);
314
315 // Called by transact. Synchronous.
316 VConnection *do_transform_open();
317 VConnection *do_post_transform_open();
318
319 // Called by transact(HttpTransact::is_request_retryable), temporarily.
320 // This function should be remove after #1994 fixed.
321 bool
is_post_transform_request()322 is_post_transform_request()
323 {
324 return t_state.method == HTTP_WKSIDX_POST && post_transform_info.vc;
325 }
326
327 // Called from InkAPI.cc which acquires the state machine lock
328 // before calling
329 int state_api_callback(int event, void *data);
330 int state_api_callout(int event, void *data);
331
332 // Used for Http Stat Pages
333 HttpTunnel *
get_tunnel()334 get_tunnel()
335 {
336 return &tunnel;
337 }
338
339 // Debugging routines to dump the SM history, hdrs
340 void dump_state_on_assert();
341 void dump_state_hdr(HTTPHdr *h, const char *s);
342
343 // Functions for manipulating api hooks
344 void txn_hook_add(TSHttpHookID id, INKContInternal *cont);
345 APIHook *txn_hook_get(TSHttpHookID id);
346
347 bool is_private();
348 bool is_redirect_required();
349
350 /// Get the protocol stack for the inbound (client, user agent) connection.
351 /// @arg result [out] Array to store the results
352 /// @arg n [in] Size of the array @a result.
353 int populate_client_protocol(std::string_view *result, int n) const;
354 const char *client_protocol_contains(std::string_view tag_prefix) const;
355
356 /// Get the protocol stack for the outbound (origin server) connection.
357 /// @arg result [out] Array to store the results
358 /// @arg n [in] Size of the array @a result.
359 int populate_server_protocol(std::string_view *result, int n) const;
360 const char *server_protocol_contains(std::string_view tag_prefix) const;
361
362 std::string_view find_proto_string(HTTPVersion version) const;
363
364 int64_t sm_id = -1;
365 unsigned int magic = HTTP_SM_MAGIC_DEAD;
366
367 // YTS Team, yamsat Plugin
368 bool enable_redirection = false; // To check if redirection is enabled
369 bool post_failed = false; // Added to identify post failure
370 bool debug_on = false; // Transaction specific debug flag
371 char *redirect_url = nullptr; // url for force redirect (provide users a functionality to redirect to another url when needed)
372 int redirect_url_len = 0;
373 int redirection_tries = 0; // To monitor number of redirections
374 int64_t transfered_bytes = 0; // Added to calculate POST data
375
376 // Tunneling request to plugin
377 HttpPluginTunnel_t plugin_tunnel_type = HTTP_NO_PLUGIN_TUNNEL;
378 PluginVCCore *plugin_tunnel = nullptr;
379
380 HttpTransact::State t_state;
381
382 // This unfortunately can't go into the t_state, because of circular dependencies. We could perhaps refactor
383 // this, with a lot of work, but this is easier for now.
384 UrlRewrite *m_remap = nullptr;
385
386 // _postbuf api
387 int64_t postbuf_reader_avail();
388 int64_t postbuf_buffer_avail();
389 void postbuf_clear();
390 void disable_redirect();
391 void postbuf_copy_partial_data();
392 void postbuf_init(IOBufferReader *ua_reader);
393 void set_postbuf_done(bool done);
394 IOBufferReader *get_postbuf_clone_reader();
395 bool get_postbuf_done();
396 bool is_postbuf_valid();
397
398 // See if we should allow the transaction
399 // based on sni and host name header values
400 void check_sni_host();
401
402 protected:
403 int reentrancy_count = 0;
404
405 HttpTunnel tunnel;
406
407 HttpVCTable vc_table;
408
409 HttpVCTableEntry *ua_entry = nullptr;
410
411 public:
412 ProxyTransaction *ua_txn = nullptr;
413 BackgroundFill_t background_fill = BACKGROUND_FILL_NONE;
414 void set_http_schedule(Continuation *);
415 int get_http_schedule(int event, void *data);
416
417 History<HISTORY_DEFAULT_SIZE> history;
418
419 protected:
420 IOBufferReader *ua_buffer_reader = nullptr;
421 IOBufferReader *ua_raw_buffer_reader = nullptr;
422
423 HttpVCTableEntry *server_entry = nullptr;
424 Http1ServerSession *server_session = nullptr;
425
426 /* Because we don't want to take a session from a shared pool if we know that it will be private,
427 * but we cannot set it to private until we have an attached server session.
428 * So we use this variable to indicate that
429 * we should create a new connection and then once we attach the session we'll mark it as private.
430 */
431 bool will_be_private_ss = false;
432 IOBufferReader *server_buffer_reader = nullptr;
433
434 HttpTransformInfo transform_info;
435 HttpTransformInfo post_transform_info;
436 /// Set if plugin client / user agents are active.
437 /// Need primarily for cleanup.
438 bool has_active_plugin_agents = false;
439
440 HttpCacheSM cache_sm;
441 HttpCacheSM transform_cache_sm;
442
443 HttpSMHandler default_handler = nullptr;
444 PendingAction pending_action;
445 Continuation *schedule_cont = nullptr;
446
447 HTTPParser http_parser;
448 void start_sub_sm();
449
450 int main_handler(int event, void *data);
451 int tunnel_handler(int event, void *data);
452 int tunnel_handler_push(int event, void *data);
453 int tunnel_handler_post(int event, void *data);
454
455 // YTS Team, yamsat Plugin
456 int tunnel_handler_for_partial_post(int event, void *data);
457
458 void tunnel_handler_post_or_put(HttpTunnelProducer *p);
459
460 int tunnel_handler_100_continue(int event, void *data);
461 int tunnel_handler_cache_fill(int event, void *data);
462 int state_read_client_request_header(int event, void *data);
463 int state_watch_for_client_abort(int event, void *data);
464 int state_read_push_response_header(int event, void *data);
465 int state_hostdb_lookup(int event, void *data);
466 int state_hostdb_reverse_lookup(int event, void *data);
467 int state_mark_os_down(int event, void *data);
468 int state_handle_stat_page(int event, void *data);
469 int state_auth_callback(int event, void *data);
470 int state_add_to_list(int event, void *data);
471 int state_remove_from_list(int event, void *data);
472
473 // Y! ebalsa: remap handlers
474 int state_remap_request(int event, void *data);
475 void do_remap_request(bool);
476
477 // Cache Handlers
478 int state_cache_open_read(int event, void *data);
479 int state_cache_open_write(int event, void *data);
480
481 // Http Server Handlers
482 int state_http_server_open(int event, void *data);
483 int state_raw_http_server_open(int event, void *data);
484 int state_send_server_request_header(int event, void *data);
485 int state_acquire_server_read(int event, void *data);
486 int state_read_server_response_header(int event, void *data);
487
488 // API
489 int state_request_wait_for_transform_read(int event, void *data);
490 int state_response_wait_for_transform_read(int event, void *data);
491 int state_common_wait_for_transform_read(HttpTransformInfo *t_info, HttpSMHandler tunnel_handler, int event, void *data);
492
493 // Tunnel event handlers
494 int tunnel_handler_server(int event, HttpTunnelProducer *p);
495 int tunnel_handler_ua(int event, HttpTunnelConsumer *c);
496 int tunnel_handler_ua_push(int event, HttpTunnelProducer *p);
497 int tunnel_handler_100_continue_ua(int event, HttpTunnelConsumer *c);
498 int tunnel_handler_cache_write(int event, HttpTunnelConsumer *c);
499 int tunnel_handler_cache_read(int event, HttpTunnelProducer *p);
500 int tunnel_handler_post_ua(int event, HttpTunnelProducer *c);
501 int tunnel_handler_post_server(int event, HttpTunnelConsumer *c);
502 int tunnel_handler_ssl_producer(int event, HttpTunnelProducer *p);
503 int tunnel_handler_ssl_consumer(int event, HttpTunnelConsumer *p);
504 int tunnel_handler_transform_write(int event, HttpTunnelConsumer *c);
505 int tunnel_handler_transform_read(int event, HttpTunnelProducer *p);
506 int tunnel_handler_plugin_agent(int event, HttpTunnelConsumer *c);
507
508 void do_hostdb_lookup();
509 void do_hostdb_reverse_lookup();
510 void do_cache_lookup_and_read();
511 void do_http_server_open(bool raw = false);
512 void send_origin_throttled_response();
513 void do_setup_post_tunnel(HttpVC_t to_vc_type);
514 void do_cache_prepare_write();
515 void do_cache_prepare_write_transform();
516 void do_cache_prepare_update();
517 void do_cache_prepare_action(HttpCacheSM *c_sm, CacheHTTPInfo *object_read_info, bool retry, bool allow_multiple = false);
518 void do_cache_delete_all_alts(Continuation *cont);
519 void do_auth_callout();
520 int do_api_callout();
521 int do_api_callout_internal();
522 void do_redirect();
523 void redirect_request(const char *redirect_url, const int redirect_len);
524 void do_drain_request_body(HTTPHdr &response);
525
526 void wait_for_full_body();
527
528 virtual void handle_api_return();
529 void handle_server_setup_error(int event, void *data);
530 void handle_http_server_open();
531 void handle_post_failure();
532 void mark_host_failure(HostDBInfo *info, time_t time_down);
533 void release_server_session(bool serve_from_cache = false);
534 void set_ua_abort(HttpTransact::AbortState_t ua_abort, int event);
535 int write_header_into_buffer(HTTPHdr *h, MIOBuffer *b);
536 int write_response_header_into_buffer(HTTPHdr *h, MIOBuffer *b);
537 void setup_blind_tunnel_port();
538 void setup_client_header_nca();
539 void setup_client_read_request_header();
540 void setup_push_read_response_header();
541 void setup_server_read_response_header();
542 void setup_cache_lookup_complete_api();
543 void setup_server_send_request();
544 void setup_server_send_request_api();
545 HttpTunnelProducer *setup_server_transfer();
546 void setup_server_transfer_to_cache_only();
547 HttpTunnelProducer *setup_cache_read_transfer();
548 void setup_internal_transfer(HttpSMHandler handler);
549 void setup_error_transfer();
550 void setup_100_continue_transfer();
551 HttpTunnelProducer *setup_push_transfer_to_cache();
552 void setup_transform_to_server_transfer();
553 void setup_cache_write_transfer(HttpCacheSM *c_sm, VConnection *source_vc, HTTPInfo *store_info, int64_t skip_bytes,
554 const char *name);
555 void issue_cache_update();
556 void perform_cache_write_action();
557 void perform_transform_cache_write_action();
558 void perform_nca_cache_action();
559 void setup_blind_tunnel(bool send_response_hdr, IOBufferReader *initial = nullptr);
560 HttpTunnelProducer *setup_server_transfer_to_transform();
561 HttpTunnelProducer *setup_transfer_from_transform();
562 HttpTunnelProducer *setup_cache_transfer_to_transform();
563 HttpTunnelProducer *setup_transfer_from_transform_to_cache_only();
564 void setup_plugin_agents(HttpTunnelProducer *p);
565
566 HttpTransact::StateMachineAction_t last_action = HttpTransact::SM_ACTION_UNDEFINED;
567 int (HttpSM::*m_last_state)(int event, void *data) = nullptr;
568 virtual void set_next_state();
569 void call_transact_and_set_next_state(TransactEntryFunc_t f);
570
571 bool is_http_server_eos_truncation(HttpTunnelProducer *);
572 bool is_bg_fill_necessary(HttpTunnelConsumer *c);
573 int find_server_buffer_size();
574 int find_http_resp_buffer_size(int64_t cl);
575 int64_t server_transfer_init(MIOBuffer *buf, int hdr_size);
576
577 public:
578 // TODO: Now that bodies can be empty, should the body counters be set to -1 ? TS-2213
579 // Stats & Logging Info
580 int client_request_hdr_bytes = 0;
581 int64_t client_request_body_bytes = 0;
582 int server_request_hdr_bytes = 0;
583 int64_t server_request_body_bytes = 0;
584 int server_response_hdr_bytes = 0;
585 int64_t server_response_body_bytes = 0;
586 int client_response_hdr_bytes = 0;
587 int64_t client_response_body_bytes = 0;
588 int cache_response_hdr_bytes = 0;
589 int64_t cache_response_body_bytes = 0;
590 int pushed_response_hdr_bytes = 0;
591 int64_t pushed_response_body_bytes = 0;
592 int server_connection_provided_cert = 0;
593 bool client_tcp_reused = false;
594 bool client_ssl_reused = false;
595 bool client_connection_is_ssl = false;
596 bool is_internal = false;
597 bool server_connection_is_ssl = false;
598 bool is_waiting_for_full_body = false;
599 bool is_using_post_buffer = false;
600 std::optional<bool> mptcp_state; // Don't initialize, that marks it as "not defined".
601 const char *client_protocol = "-";
602 const char *server_protocol = "-";
603 const char *client_sec_protocol = "-";
604 const char *client_cipher_suite = "-";
605 const char *client_curve = "-";
606 int client_alpn_id = SessionProtocolNameRegistry::INVALID;
607 int server_transact_count = 0;
608
609 TransactionMilestones milestones;
610 ink_hrtime api_timer = 0;
611 // The next two enable plugins to tag the state machine for
612 // the purposes of logging so the instances can be correlated
613 // with the source plugin.
614 const char *plugin_tag = nullptr;
615 int64_t plugin_id = 0;
616
617 // hooks_set records whether there are any hooks relevant
618 // to this transaction. Used to avoid costly calls
619 // do_api_callout_internal()
620 bool hooks_set = false;
621
622 protected:
623 TSHttpHookID cur_hook_id = TS_HTTP_LAST_HOOK;
624 APIHook const *cur_hook = nullptr;
625 HttpHookState hook_state;
626
627 //
628 // Continuation time keeper
629 int64_t prev_hook_start_time = 0;
630
631 int cur_hooks = 0;
632 HttpApiState_t callout_state = HTTP_API_NO_CALLOUT;
633
634 // api_hooks must not be changed directly
635 // Use txn_hook_{ap,pre}pend so hooks_set is
636 // updated
637 HttpAPIHooks api_hooks;
638
639 // The terminate flag is set by handlers and checked by the
640 // main handler who will terminate the state machine
641 // when the flag is set
642 bool terminate_sm = false;
643 bool kill_this_async_done = false;
644 bool parse_range_done = false;
645 void kill_this();
646 void update_stats();
647 void transform_cleanup(TSHttpHookID hook, HttpTransformInfo *info);
648 bool is_transparent_passthrough_allowed();
649 void plugin_agents_cleanup();
650
651 public:
652 LINK(HttpSM, debug_link);
653
654 public:
655 bool set_server_session_private(bool private_session);
656 bool
is_dying()657 is_dying() const
658 {
659 return terminate_sm;
660 }
661
662 int
client_connection_id()663 client_connection_id() const
664 {
665 return _client_connection_id;
666 }
667
668 int
client_transaction_id()669 client_transaction_id() const
670 {
671 return _client_transaction_id;
672 }
673
674 int
client_transaction_priority_weight()675 client_transaction_priority_weight() const
676 {
677 return _client_transaction_priority_weight;
678 }
679
680 int
client_transaction_priority_dependence()681 client_transaction_priority_dependence() const
682 {
683 return _client_transaction_priority_dependence;
684 }
685
686 ink_hrtime get_server_inactivity_timeout();
687 ink_hrtime get_server_active_timeout();
688 ink_hrtime get_server_connect_timeout();
689 void rewind_state_machine();
690
691 private:
692 PostDataBuffers _postbuf;
693 int _client_connection_id = -1, _client_transaction_id = -1;
694 int _client_transaction_priority_weight = -1, _client_transaction_priority_dependence = -1;
695 bool _from_early_data = false;
696 };
697
698 // Function to get the cache_sm object - YTS Team, yamsat
699 inline HttpCacheSM &
get_cache_sm()700 HttpSM::get_cache_sm()
701 {
702 return cache_sm;
703 }
704
705 inline int
write_response_header_into_buffer(HTTPHdr * h,MIOBuffer * b)706 HttpSM::write_response_header_into_buffer(HTTPHdr *h, MIOBuffer *b)
707 {
708 if (t_state.client_info.http_version == HTTPVersion(0, 9)) {
709 return 0;
710 } else {
711 return write_header_into_buffer(h, b);
712 }
713 }
714
715 inline int
find_server_buffer_size()716 HttpSM::find_server_buffer_size()
717 {
718 return find_http_resp_buffer_size(t_state.hdr_info.response_content_length);
719 }
720
721 inline void
txn_hook_add(TSHttpHookID id,INKContInternal * cont)722 HttpSM::txn_hook_add(TSHttpHookID id, INKContInternal *cont)
723 {
724 api_hooks.append(id, cont);
725 hooks_set = true;
726 }
727
728 inline APIHook *
txn_hook_get(TSHttpHookID id)729 HttpSM::txn_hook_get(TSHttpHookID id)
730 {
731 return api_hooks.get(id);
732 }
733
734 inline bool
is_transparent_passthrough_allowed()735 HttpSM::is_transparent_passthrough_allowed()
736 {
737 return (t_state.client_info.is_transparent && ua_txn->is_transparent_passthrough_allowed() && ua_txn->is_first_transaction());
738 }
739
740 inline int64_t
postbuf_reader_avail()741 HttpSM::postbuf_reader_avail()
742 {
743 return this->_postbuf.ua_buffer_reader->read_avail();
744 }
745
746 inline int64_t
postbuf_buffer_avail()747 HttpSM::postbuf_buffer_avail()
748 {
749 return this->_postbuf.postdata_copy_buffer_start->read_avail();
750 }
751
752 inline void
postbuf_clear()753 HttpSM::postbuf_clear()
754 {
755 this->_postbuf.clear();
756 }
757
758 inline void
disable_redirect()759 HttpSM::disable_redirect()
760 {
761 this->enable_redirection = false;
762 this->_postbuf.clear();
763 }
764
765 inline void
postbuf_copy_partial_data()766 HttpSM::postbuf_copy_partial_data()
767 {
768 this->_postbuf.copy_partial_post_data();
769 }
770
771 inline void
postbuf_init(IOBufferReader * ua_reader)772 HttpSM::postbuf_init(IOBufferReader *ua_reader)
773 {
774 this->_postbuf.init(ua_reader);
775 }
776
777 inline void
set_postbuf_done(bool done)778 HttpSM::set_postbuf_done(bool done)
779 {
780 this->_postbuf.set_post_data_buffer_done(done);
781 }
782
783 inline bool
get_postbuf_done()784 HttpSM::get_postbuf_done()
785 {
786 return this->_postbuf.get_post_data_buffer_done();
787 }
788
789 inline bool
is_postbuf_valid()790 HttpSM::is_postbuf_valid()
791 {
792 return this->_postbuf.is_valid();
793 }
794
795 inline IOBufferReader *
get_postbuf_clone_reader()796 HttpSM::get_postbuf_clone_reader()
797 {
798 return this->_postbuf.get_post_data_buffer_clone_reader();
799 }
800