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 }