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 #ifndef __P_SPDY_SM_H__
00025 #define __P_SPDY_SM_H__
00026 
00027 #include "SpdyDefs.h"
00028 #include "SpdyCommon.h"
00029 #include "SpdyCallbacks.h"
00030 #include <openssl/md5.h>
00031 #include "Plugin.h"
00032 
00033 class SpdyClientSession;
00034 typedef int (*SpdyClientSessionHandler) (TSCont contp, TSEvent event, void *data);
00035 
00036 class SpdyRequest
00037 {
00038 public:
00039   SpdyRequest():
00040     spdy_sm(NULL), stream_id(-1), fetch_sm(NULL),
00041     has_submitted_data(false), need_resume_data(false),
00042     fetch_data_len(0), delta_window_size(0),
00043     fetch_body_completed(false)
00044   {
00045   }
00046 
00047   SpdyRequest(SpdyClientSession *sm, int id):
00048     spdy_sm(NULL), stream_id(-1), fetch_sm(NULL),
00049     has_submitted_data(false), need_resume_data(false),
00050     fetch_data_len(0), delta_window_size(0),
00051     fetch_body_completed(false)
00052   {
00053     init(sm, id);
00054   }
00055 
00056   ~SpdyRequest()
00057   {
00058     clear();
00059   }
00060 
00061   void init(SpdyClientSession *sm, int id);
00062   void clear();
00063 
00064   void append_nv(char **nv)
00065   {
00066     for(int i = 0; nv[i]; i += 2) {
00067       headers.push_back(make_pair(nv[i], nv[i+1]));
00068     }
00069   }
00070 
00071 public:
00072   int event;
00073   SpdyClientSession *spdy_sm;
00074   int stream_id;
00075   TSHRTime start_time;
00076   TSFetchSM fetch_sm;
00077   bool has_submitted_data;
00078   bool need_resume_data;
00079   int fetch_data_len;
00080   unsigned delta_window_size;
00081   bool fetch_body_completed;
00082   vector<pair<string, string> > headers;
00083 
00084   string url;
00085   string host;
00086   string path;
00087   string scheme;
00088   string method;
00089   string version;
00090 
00091   MD5_CTX recv_md5;
00092 };
00093 
00094 extern ClassAllocator<SpdyRequest> spdyRequestAllocator;
00095 
00096 class SpdyClientSession : public Continuation, public PluginIdentity
00097 {
00098 
00099 public:
00100 
00101   SpdyClientSession() : Continuation(NULL) {
00102   }
00103 
00104   ~SpdyClientSession() {
00105     clear();
00106   }
00107 
00108   void init(NetVConnection * netvc, spdy::SessionVersion vers);
00109   void clear();
00110 
00111   int64_t sm_id;
00112   spdy::SessionVersion version;
00113   uint64_t total_size;
00114   TSHRTime start_time;
00115 
00116   NetVConnection * vc;
00117 
00118   TSIOBuffer req_buffer;
00119   TSIOBufferReader req_reader;
00120 
00121   TSIOBuffer resp_buffer;
00122   TSIOBufferReader resp_reader;
00123 
00124   TSVIO   read_vio;
00125   TSVIO   write_vio;
00126 
00127   int event;
00128   spdylay_session *session;
00129 
00130   map<int32_t, SpdyRequest*> req_map;
00131 
00132   virtual char const* getPluginTag() const;
00133   virtual int64_t getPluginId() const;
00134 
00135   SpdyRequest *
00136   find_request(int streamId) {
00137     map<int32_t, SpdyRequest*>::iterator iter = this->req_map.find(streamId);
00138     return ((iter == this->req_map.end()) ? NULL : iter->second);
00139   }
00140 
00141   void
00142   cleanup_request(int streamId) {
00143     SpdyRequest* req = this->find_request(streamId);
00144     if (req) {
00145       req->clear();
00146       spdyRequestAllocator.free(req);
00147       this->req_map.erase(streamId);
00148     }
00149   }
00150 
00151 private:
00152   int state_session_start(int event, void * edata);
00153   int state_session_readwrite(int event, void * edata);
00154 };
00155 
00156 void spdy_cs_create(NetVConnection * netvc, spdy::SessionVersion vers, MIOBuffer * iobuf, IOBufferReader * reader);
00157 
00158 #endif