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