Go to the documentation of this file.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 
00026 
00027 
00028 
00029 
00030 #ifndef _FETCH_SM_H
00031 #define _FETCH_SM_H
00032 
00033 #include "P_Net.h"
00034 #include "ts.h"
00035 #include "HttpSM.h"
00036 #include "HttpTunnel.h"
00037 
00038 class PluginVC;
00039 
00040 class FetchSM: public Continuation
00041 {
00042 public:
00043   FetchSM()
00044   { }
00045 
00046   void init_comm()
00047   {
00048     is_internal_request = true;
00049     recursion = 0;
00050     req_finished = 0;
00051     resp_finished = 0;
00052     header_done = 0;
00053     user_data = NULL;
00054     has_sent_header = false;
00055     req_content_length = 0;
00056     resp_is_chunked = -1;
00057     resp_content_length = -1;
00058     resp_recived_body_len = 0;
00059     cont_mutex.clear();
00060     req_buffer = new_MIOBuffer(HTTP_HEADER_BUFFER_SIZE_INDEX);
00061     req_reader = req_buffer->alloc_reader();
00062     resp_buffer = new_MIOBuffer(BUFFER_SIZE_INDEX_32K);
00063     resp_reader = resp_buffer->alloc_reader();
00064     http_parser_init(&http_parser);
00065     client_response_hdr.create(HTTP_TYPE_RESPONSE);
00066     client_response  = NULL;
00067     SET_HANDLER(&FetchSM::fetch_handler);
00068   }
00069 
00070   void init(Continuation* cont, TSFetchWakeUpOptions options,
00071             TSFetchEvent events, const char* headers, int length,
00072             sockaddr const *addr)
00073   {
00074     Debug("FetchSM", "[%s] FetchSM initialized for request with headers\n--\n%.*s\n--",
00075           __FUNCTION__, length, headers);
00076     init_comm();
00077     contp = cont;
00078     callback_events = events;
00079     callback_options = options;
00080     _addr.assign(addr);
00081     fetch_flags = TS_FETCH_FLAGS_DECHUNK;
00082     writeRequest(headers,length);
00083     mutex = new_ProxyMutex();
00084 
00085     
00086     
00087     
00088     
00089     
00090     
00091     
00092     
00093     resp_buffer->water_mark = INT64_MAX;
00094   }
00095 
00096   int fetch_handler(int event, void *data);
00097   void process_fetch_read(int event);
00098   void process_fetch_write(int event);
00099   void httpConnect();
00100   void cleanUp();
00101   void get_info_from_buffer(IOBufferReader *reader);
00102   char* resp_get(int* length);
00103 
00104   TSMBuffer resp_hdr_bufp();
00105   TSMLoc resp_hdr_mloc();
00106 
00107   
00108   
00109   
00110   
00111   
00112   void ext_init(Continuation *cont, const char *method,
00113                 const char *url, const char *version,
00114                 const sockaddr *client_addr, int flags);
00115   void ext_add_header(const char *name, int name_len,
00116                       const char *value, int value_len);
00117   void ext_lanuch();
00118   void ext_destroy();
00119   ssize_t ext_read_data(char *buf, size_t len);
00120   void ext_write_data(const void *data, size_t len);
00121   void ext_set_user_data(void *data);
00122   void* ext_get_user_data();
00123   bool get_internal_request() { return is_internal_request; }
00124   void set_internal_request(bool val) { is_internal_request = val; }
00125 
00126 private:
00127   int InvokePlugin(int event, void*data);
00128   void InvokePluginExt(int error_event = 0);
00129 
00130   void writeRequest(const char *headers,int length)
00131   {
00132     if(length == -1)
00133     req_buffer->write(headers, strlen(headers));
00134     else
00135     req_buffer->write(headers,length);
00136   }
00137 
00138   int64_t getReqLen() const { return req_reader->read_avail(); }
00139 
00140   bool has_body();
00141   bool check_body_done();
00142   bool check_chunked();
00143   int dechunk_body();
00144 
00145   int recursion;
00146   PluginVC* http_vc;
00147   VIO *read_vio;
00148   VIO *write_vio;
00149   MIOBuffer *req_buffer;
00150   IOBufferReader *req_reader;
00151   char *client_response;
00152   int  client_bytes;
00153   MIOBuffer *resp_buffer;       
00154   IOBufferReader *resp_reader;
00155   Continuation *contp;
00156   Ptr<ProxyMutex> cont_mutex;
00157   HTTPParser http_parser;
00158   HTTPHdr client_response_hdr;
00159   ChunkedHandler chunked_handler;
00160   TSFetchEvent callback_events;
00161   TSFetchWakeUpOptions callback_options;
00162   bool req_finished;
00163   bool header_done;
00164   bool resp_finished;
00165   bool is_internal_request;
00166   IpEndpoint _addr;
00167   int resp_is_chunked;
00168   int fetch_flags;
00169   void *user_data;
00170   bool has_sent_header;
00171   int64_t req_content_length;
00172   int64_t resp_content_length;
00173   int64_t resp_recived_body_len;
00174 };
00175 
00176 #endif