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 __INK_API_INTERNAL_H__
00025 #define __INK_API_INTERNAL_H__
00026 
00027 #include "P_EventSystem.h"
00028 #include "URL.h"
00029 #include "StatSystem.h"
00030 #include "P_Net.h"
00031 #include "ts.h"
00032 #include "experimental.h"
00033 #include "InkAPIPrivateIOCore.h"
00034 #include "HTTP.h"
00035 #include "List.h"
00036 #include "ProxyConfig.h"
00037 #include "P_Cache.h"
00038 #include "I_Tasks.h"
00039 
00040 
00041 
00042 #define HTTP_SSN_TXN_MAX_USER_ARG         16   
00043 
00044 typedef enum
00045   {
00046     OVERRIDABLE_TYPE_NULL = 0,
00047     OVERRIDABLE_TYPE_INT,
00048     OVERRIDABLE_TYPE_FLOAT,
00049     OVERRIDABLE_TYPE_STRING,
00050     OVERRIDABLE_TYPE_BYTE
00051   } OverridableDataType;
00052 typedef int8_t TSMgmtByte; 
00053 
00054 
00055 
00056 
00057 enum CacheInfoMagic
00058 {
00059   CACHE_INFO_MAGIC_ALIVE = 0xfeedbabe,
00060   CACHE_INFO_MAGIC_DEAD = 0xdeadbeef
00061 };
00062 
00063 struct CacheInfo
00064 {
00065   INK_MD5 cache_key;
00066   CacheFragType frag_type;
00067   char *hostname;
00068   int len;
00069   time_t pin_in_cache;
00070   CacheInfoMagic magic;
00071 
00072     CacheInfo()
00073   {
00074     frag_type = CACHE_FRAG_TYPE_NONE;
00075     hostname = NULL;
00076     len = 0;
00077     pin_in_cache = 0;
00078     magic = CACHE_INFO_MAGIC_ALIVE;
00079   }
00080 };
00081 
00082 class FileImpl
00083 {
00084   enum
00085   {
00086     CLOSED = 0,
00087     READ = 1,
00088     WRITE = 2
00089   };
00090 
00091 public:
00092     FileImpl();
00093    ~FileImpl();
00094 
00095   int fopen(const char *filename, const char *mode);
00096   void fclose();
00097   int fread(void *buf, int length);
00098   int fwrite(const void *buf, int length);
00099   int fflush();
00100   char *fgets(char *buf, int length);
00101 
00102 public:
00103   int m_fd;
00104   int m_mode;
00105   char *m_buf;
00106   int m_bufsize;
00107   int m_bufpos;
00108 };
00109 
00110 
00111 struct INKConfigImpl:public ConfigInfo
00112 {
00113   void *mdata;
00114   TSConfigDestroyFunc m_destroy_func;
00115 
00116     virtual ~ INKConfigImpl()
00117   {
00118     m_destroy_func(mdata);
00119   }
00120 };
00121 
00122 struct HttpAltInfo
00123 {
00124   HTTPHdr m_client_req;
00125   HTTPHdr m_cached_req;
00126   HTTPHdr m_cached_resp;
00127   float m_qvalue;
00128 };
00129 
00130 enum APIHookScope
00131 {
00132   API_HOOK_SCOPE_NONE,
00133   API_HOOK_SCOPE_GLOBAL,
00134   API_HOOK_SCOPE_LOCAL
00135 };
00136 
00137 
00138 class APIHook
00139 {
00140 public:
00141   INKContInternal * m_cont;
00142   int invoke(int event, void *edata);
00143   APIHook *next() const;
00144   LINK(APIHook, m_link);
00145 };
00146 
00147 
00148 class APIHooks
00149 {
00150 public:
00151   void prepend(INKContInternal * cont);
00152   void append(INKContInternal * cont);
00153   APIHook *get() const;
00154   void clear();
00155   bool is_empty() const;
00156   void invoke(int event, void* data);
00157 
00158 private:
00159   Que(APIHook, m_link) m_hooks;
00160 };
00161 
00162 inline bool
00163 APIHooks::is_empty() const
00164 {
00165   return NULL == m_hooks.head;
00166 }
00167 
00168 inline void
00169 APIHooks::invoke(int event, void* data) {
00170   for ( APIHook* hook = m_hooks.head ; NULL != hook ; hook = hook->next())
00171     hook->invoke(event, data);
00172 }
00173 
00174 
00175 
00176 
00177 
00178 
00179 
00180 
00181 
00182 
00183 template <
00184   typename ID, 
00185   ID N 
00186 >
00187 class FeatureAPIHooks
00188 {
00189 public:
00190   FeatureAPIHooks(); 
00191   ~FeatureAPIHooks(); 
00192 
00193 
00194   void clear();
00195 
00196   void prepend(ID id, INKContInternal * cont);
00197 
00198   void append(ID id, INKContInternal * cont);
00199 
00200   APIHook *get(ID id) const;
00201 
00202   static bool is_valid(ID id);
00203 
00204 
00205   void invoke(ID id, int event, void* data);
00206 
00207 
00208 
00209 
00210 
00211   bool has_hooks() const;
00212 
00213 
00214 
00215   bool has_hooks_for(ID id) const;
00216 
00217 private:
00218   bool hooks_p; 
00219 
00220   APIHooks m_hooks[N];
00221 };
00222 
00223 template < typename ID, ID N >
00224 FeatureAPIHooks<ID,N>::FeatureAPIHooks():
00225 hooks_p(false)
00226 {
00227 }
00228 
00229 template < typename ID, ID N >
00230 FeatureAPIHooks<ID,N>::~FeatureAPIHooks()
00231 {
00232   this->clear();
00233 }
00234 
00235 template < typename ID, ID N >
00236 void
00237 FeatureAPIHooks<ID,N>::clear()
00238 {
00239   for (int i = 0; i < N; ++i) {
00240     m_hooks[i].clear();
00241   }
00242   hooks_p = false;
00243 }
00244 
00245 template < typename ID, ID N >
00246 void
00247 FeatureAPIHooks<ID,N>::prepend(ID id, INKContInternal *cont)
00248 {
00249   hooks_p = true;
00250   m_hooks[id].prepend(cont);
00251 }
00252 
00253 template < typename ID, ID N >
00254 void
00255 FeatureAPIHooks<ID,N>::append(ID id, INKContInternal *cont)
00256 {
00257   hooks_p = true;
00258   m_hooks[id].append(cont);
00259 }
00260 
00261 template < typename ID, ID N >
00262 APIHook *
00263 FeatureAPIHooks<ID,N>::get(ID id) const
00264 {
00265   return m_hooks[id].get();
00266 }
00267 
00268 template < typename ID, ID N >
00269 void
00270 FeatureAPIHooks<ID,N>::invoke(ID id, int event, void* data)
00271 {
00272   m_hooks[id].invoke(event, data);
00273 }
00274 
00275 template < typename ID, ID N >
00276 bool
00277 FeatureAPIHooks<ID,N>::has_hooks() const
00278 {
00279   return hooks_p;
00280 }
00281 
00282 template < typename ID, ID N >
00283 bool
00284 FeatureAPIHooks<ID,N>::is_valid(ID id)
00285 {
00286   return 0 <= id && id < N;
00287 }
00288 
00289 class HttpAPIHooks : public FeatureAPIHooks<TSHttpHookID, TS_HTTP_LAST_HOOK>
00290 {
00291 };
00292 
00293 class LifecycleAPIHooks : public FeatureAPIHooks<TSLifecycleHookID, TS_LIFECYCLE_LAST_HOOK>
00294 {
00295 };
00296 
00297 
00298 class ConfigUpdateCallback:public Continuation
00299 {
00300 public:
00301   ConfigUpdateCallback(INKContInternal * contp)
00302     : Continuation(contp->mutex), m_cont(contp)
00303   {
00304     SET_HANDLER(&ConfigUpdateCallback::event_handler);
00305   }
00306 
00307   int event_handler(int, void *)
00308   {
00309     if (m_cont->mutex != NULL) {
00310       MUTEX_TRY_LOCK(trylock, m_cont->mutex, this_ethread());
00311       if (!trylock) {
00312         eventProcessor.schedule_in(this, HRTIME_MSECONDS(10), ET_TASK);
00313       } else {
00314         m_cont->handleEvent(TS_EVENT_MGMT_UPDATE, NULL);
00315         delete this;
00316       }
00317     } else {
00318       m_cont->handleEvent(TS_EVENT_MGMT_UPDATE, NULL);
00319       delete this;
00320     }
00321 
00322     return 0;
00323   }
00324 
00325 private:
00326   INKContInternal *m_cont;
00327 };
00328 
00329 class ConfigUpdateCbTable
00330 {
00331 public:
00332   ConfigUpdateCbTable();
00333   ~ConfigUpdateCbTable();
00334 
00335   void insert(INKContInternal * contp, const char *name);
00336   void invoke(const char *name);
00337   void invoke(INKContInternal * contp);
00338 
00339 private:
00340     InkHashTable * cb_table;
00341 };
00342 
00343 void api_init();
00344 
00345 extern HttpAPIHooks *http_global_hooks;
00346 extern LifecycleAPIHooks* lifecycle_hooks;
00347 extern ConfigUpdateCbTable *global_config_cbs;
00348 
00349 #endif