00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #include "SpdyCommon.h"
00025 #include "SpdyCallbacks.h"
00026 
00027 
00028 spdylay_session_callbacks spdy_callbacks;
00029 
00030 
00031 RecRawStatBlock* spdy_rsb; 
00032 
00033 static char const * const SPDY_STAT_CURRENT_CLIENT_SESSION_NAME = "proxy.process.spdy.current_client_sessions";
00034 static char const * const SPDY_STAT_CURRENT_CLIENT_STREAM_NAME = "proxy.process.spdy.current_client_streams";
00035 static char const * const SPDY_STAT_TOTAL_CLIENT_STREAM_NAME = "proxy.process.spdy.total_client_streams";
00036 static char const * const SPDY_STAT_TOTAL_TRANSACTIONS_TIME_NAME = "proxy.process.spdy.total_transactions_time";
00037 static char const * const SPDY_STAT_TOTAL_CLIENT_CONNECTION_NAME = "proxy.process.spdy.total_client_connections";
00038 
00039 
00040 uint32_t spdy_max_concurrent_streams = 100;
00041 uint32_t spdy_initial_window_size = 65536;
00042 int32_t spdy_accept_no_activity_timeout = 120;
00043 int32_t spdy_no_activity_timeout_in = 115;
00044 
00045 string
00046 http_date(time_t t)
00047 {
00048   char buf[32];
00049   tm* tms = gmtime(&t); 
00050   size_t r = strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S GMT", tms);
00051   return std::string(&buf[0], &buf[r]);
00052 }
00053 
00054 int
00055 spdy_config_load()
00056 {
00057   REC_EstablishStaticConfigInt32U(spdy_max_concurrent_streams, "proxy.config.spdy.max_concurrent_streams_in");
00058   REC_EstablishStaticConfigInt32U(spdy_initial_window_size, "proxy.config.spdy.initial_window_size_in");
00059   REC_EstablishStaticConfigInt32(spdy_no_activity_timeout_in, "proxy.config.spdy.no_activity_timeout_in");
00060   REC_EstablishStaticConfigInt32(spdy_accept_no_activity_timeout, "proxy.config.spdy.accept_no_activity_timeout");
00061 
00062   spdy_callbacks_init(&spdy_callbacks);
00063 
00064   
00065   spdy_rsb = RecAllocateRawStatBlock(static_cast<int>(SPDY_N_STATS));
00066   RecRegisterRawStat(spdy_rsb, RECT_PROCESS, SPDY_STAT_CURRENT_CLIENT_SESSION_NAME, RECD_INT, RECP_NON_PERSISTENT,
00067                      static_cast<int>(SPDY_STAT_CURRENT_CLIENT_SESSION_COUNT), RecRawStatSyncSum);
00068   RecRegisterRawStat(spdy_rsb, RECT_PROCESS, SPDY_STAT_CURRENT_CLIENT_STREAM_NAME, RECD_INT, RECP_NON_PERSISTENT,
00069                      static_cast<int>(SPDY_STAT_CURRENT_CLIENT_STREAM_COUNT), RecRawStatSyncSum);
00070   RecRegisterRawStat(spdy_rsb, RECT_PROCESS, SPDY_STAT_TOTAL_CLIENT_STREAM_NAME, RECD_INT, RECP_PERSISTENT,
00071                      static_cast<int>(SPDY_STAT_TOTAL_TRANSACTIONS_TIME), RecRawStatSyncCount);
00072   RecRegisterRawStat(spdy_rsb, RECT_PROCESS, SPDY_STAT_TOTAL_TRANSACTIONS_TIME_NAME, RECD_INT, RECP_PERSISTENT,
00073                      static_cast<int>(SPDY_STAT_TOTAL_TRANSACTIONS_TIME), RecRawStatSyncSum);
00074   RecRegisterRawStat(spdy_rsb, RECT_PROCESS, SPDY_STAT_TOTAL_CLIENT_CONNECTION_NAME, RECD_INT, RECP_PERSISTENT,
00075                      static_cast<int>(SPDY_STAT_TOTAL_CLIENT_CONNECTION_COUNT), RecRawStatSyncSum);
00076 
00077   return 0;
00078 }
00079 
00080 SpdyNV::SpdyNV(TSFetchSM fetch_sm)
00081 {
00082   int i, len;
00083   char *p;
00084   const char *name, *value;
00085   int name_len, value_len, hdr_len, nr_fields;
00086   TSMLoc loc, field_loc, next_loc;
00087   TSMBuffer bufp;
00088 
00089   bufp = TSFetchRespHdrMBufGet(fetch_sm);
00090   loc = TSFetchRespHdrMLocGet(fetch_sm);
00091 
00092   hdr_len = TSMimeHdrLengthGet(bufp, loc);
00093   mime_hdr = malloc(hdr_len);
00094   TSReleaseAssert(mime_hdr);
00095 
00096   nr_fields = TSMimeHdrFieldsCount(bufp, loc);
00097 
00098   if (nr_fields <= 0) {
00099     Debug("spdy_error", "invalid fetchsm %p, nr_fields %d, hdr_len %d", fetch_sm, nr_fields, hdr_len);
00100   }
00101 
00102   nv = (const char **)malloc((2*nr_fields + 5) * sizeof(char *));
00103   TSReleaseAssert(nv);
00104 
00105   
00106   
00107   
00108   i = TSHttpHdrVersionGet(bufp, loc);
00109   snprintf(version, sizeof(version), "HTTP/%d.%d", TS_HTTP_MAJOR(i), TS_HTTP_MINOR(i));
00110 
00111   i = TSHttpHdrStatusGet(bufp, loc);
00112   value = (char *)TSHttpHdrReasonGet(bufp, loc, &value_len);
00113   snprintf(status, sizeof(version), "%d ", i);
00114   i = strlen(status);
00115   len = sizeof(status) - i;
00116   len = value_len > len ? len : value_len;
00117   strncpy(&status[i], value, len);
00118   status[len + i] = '\0';;
00119 
00120   i = 0;
00121   nv[i++] = ":version";
00122   nv[i++] = version;
00123   nv[i++] = ":status";
00124   nv[i++] = status;
00125 
00126   
00127   
00128   
00129   p = (char *)mime_hdr;
00130   field_loc = TSMimeHdrFieldGet(bufp, loc, 0);
00131   while (field_loc) {
00132     name = TSMimeHdrFieldNameGet(bufp, loc, field_loc, &name_len);
00133     TSReleaseAssert(name && name_len);
00134 
00135     
00136     
00137     
00138     
00139     
00140     if (!strncasecmp(name, "Connection", name_len))
00141       goto next;
00142 
00143     if (!strncasecmp(name, "Keep-Alive", name_len))
00144       goto next;
00145 
00146     if (!strncasecmp(name, "Proxy-Connection", name_len))
00147       goto next;
00148 
00149     if (!strncasecmp(name, "Transfer-Encoding", name_len))
00150       goto next;
00151 
00152     value = TSMimeHdrFieldValueStringGet(bufp, loc, field_loc, -1, &value_len);
00153 
00154     
00155     
00156     
00157     
00158     if (!value || !value_len)
00159       goto next;
00160 
00161     strncpy(p, name, name_len);
00162     nv[i++] = p;
00163     p += name_len;
00164     *p++ = '\0';
00165 
00166     strncpy(p, value, value_len);
00167     nv[i++] = p;
00168     p += value_len;
00169     *p++ = '\0';
00170 
00171 next:
00172     next_loc = TSMimeHdrFieldNext(bufp, loc, field_loc);
00173     TSHandleMLocRelease(bufp, loc, field_loc);
00174     field_loc = next_loc;
00175   }
00176   nv[i] = NULL;
00177 
00178   if (field_loc)
00179     TSHandleMLocRelease(bufp, loc, field_loc);
00180 }
00181 
00182 SpdyNV::~SpdyNV()
00183 {
00184   if (nv)
00185     free(nv);
00186 
00187   if (mime_hdr)
00188     free(mime_hdr);
00189 }