为squid增加视频拖动功能
最近公司要上CDN网络,做一些视频的缓存,为了用squid进行视频缓存,必须要让它实现拖动功能。squid并不是为视频专门设计的缓存软件,所以当缓存视频文件时,并不具有视频拖动功能。
首先简单了解一下视频为什么能拖动,使用yamdi等视频加帧软件将视频加帧生成metadata信息,里面记录着每一帧对应的文件的以字节为单位的偏移量(offset),播放器获取metadata信息,如果用户拖动了视频的播放进度条,播放器会根据所在帧生成一个url请求,这个请求中包含start=XXX,这个XXX就是这个偏移量,服务器接受到这个请求会从用户指定的偏移量开始读取视频文件,并在前面加上"FLV\x1\x1\0\0\0\x9\0\0\0\x9" 13个字节的一个标记,这样用户在得到服务器的返回值之后能正确的播放视频,完成拖动。
lighttpd 处理视频文件的核心文件是mod_flv_streaming.c
[*]URIHANDLER_FUNC(mod_flv_streaming_path_handler) {
[*] plugin_data *p = p_d;
[*] int s_len;
[*] size_t k;
[*]
[*] UNUSED(srv);
[*]
[*] if (con->mode != DIRECT) return HANDLER_GO_ON;
[*]
[*] if (buffer_is_empty(con->physical.path)) return HANDLER_GO_ON;
[*]
[*] mod_flv_streaming_patch_connection(srv, con, p);
[*]
[*] s_len = con->physical.path->used - 1;
[*]
[*] for (k = 0; k < p->conf.extensions->used; k++) {
[*] data_string *ds = (data_string *)p->conf.extensions->data;
[*] int ct_len = ds->value->used - 1;
[*]
[*] if (ct_len > s_len) continue;
[*] if (ds->value->used == 0) continue;
[*]
[*] if (0 == strncmp(con->physical.path->ptr + s_len - ct_len, ds->value->ptr, ct_len)) {
[*] data_string *get_param;
[*] stat_cache_entry *sce = NULL;
[*] buffer *b;
[*] int start;
[*] char *err = NULL;
[*] /* if there is a start=+ in the header use it as start,
[*] * otherwise send the full file */
[*]
[*] array_reset(p->get_params);
[*] buffer_copy_string_buffer(p->query_str, con->uri.query);
[*] split_get_params(p->get_params, p->query_str);
[*]
[*] if (NULL == (get_param = (data_string *)array_get_element(p->get_params, "start"))) {
[*] return HANDLER_GO_ON;
[*] }
[*]
[*] /* too short */
[*] if (get_param->value->used < 2) return HANDLER_GO_ON;
[*]
[*] /* check if it is a number */
[*] start = strtol(get_param->value->ptr, &err, 10);
[*] if (*err != '\0') {
[*] return HANDLER_GO_ON;
[*] }
[*]
[*] if (startfilesize */
[*] if (HANDLER_GO_ON != stat_cache_get_entry(srv, con, con->physical.path, &sce)) {
[*] return HANDLER_GO_ON;
[*] }
[*]
[*] if (start > sce->st.st_size) {
[*] return HANDLER_GO_ON;
[*] }
[*]
[*] /* we are safe now, let's build a flv header */
[*] b = chunkqueue_get_append_buffer(con->write_queue);
[*] buffer_copy_string_len(b, CONST_STR_LEN("FLV\x1\x1\0\0\0\x9\0\0\0\x9"));
[*]
[*] http_chunk_append_file(srv, con, con->physical.path, start, sce->st.st_size - start);
[*]
[*] response_header_overwrite(srv, con, CONST_STR_LEN("Content-Type"), CONST_STR_LEN("video/x-flv"));
[*]
[*] con->file_finished = 1;
[*]
[*] return HANDLER_FINISHED;
[*] }
[*] }
[*]
[*] /* not found */
[*] return HANDLER_GO_ON;
[*]}
上面是lighttpd处理视频拖动的函数,首先lighttpd获取start的数值,然后发送13个字节的"FLV\x1\x1\0\0\0\x9\0\0\0\x9",然后seek到指定帧的开始处读取文件,生成正确的返回头部content length信息。
回头来看squid,如果要让squid能实现视频的拖动,同样的我们也要完成这项工作,首先我们要让squid能识别用户的包含url中包含的start信息,然后同样的读取指定offset的缓存文件信息,并且加上"FLV\x1\x1\0\0\0\x9\0\0\0\x9"的公共信息,再生成正确的content length信息。但是毕竟squid和lighttpd是不相同的,lighttpd读取的文件都是本地磁盘上的,如果squid本地磁盘上有缓存的话,情况是相似的,但在cache miss的情况下,如何让用户获得更好的体验就不尽相同了,而且squid 要保证对于同一个视频文件磁盘上只出现一个缓存文件,而且这个文件必须是完整的视频文件,不是从某个帧开始的文件。
首先我的设计思路是这样的
http://blog.运维网.com/attachment/201301/173625556.png
简单的说明一下上面的处理流程,因为我们的视频是要加密的在每个返回内容的最前面都会有加密信息(这个加密是开发人员修改lighttpd加上去的),这个工作一开始是又lighttpd处理的,加上这样的信息之后squid在设置读取offset的时候会发生问题(因为加密信息是多出来的而且长度是随机的),所以我关闭了lighttpd的加密,然后在hit和miss的情况下都要和"FLV\x1\x1\0\0\0\x9\0\0\0\x9"一起加上加密信息,这个处理对其他人是不适用的。
storeurl rewrite的处理是肯定要有的,因为同一个视频文件因为start值的不同还有一些其他的因素导致url是不相同的,这样请求同一个文件的url也不尽相同,所以我使用了jesred做storeurl rewrite,但是这就会出现一个问题,在cache miss的情况下,一个start不等于0的url请求会记录到磁盘上,但这并不是我们想要的。所以解决方法我想到两个,一个是使用url rewrite (注意这不是storeurl rewrite),将所有start不等于0的url改写成start等于0,这样缓存的肯定是完整的视频文件,但是这会出现一个问题,当服务器端squid并没有将完整的视频抓取到本地的时候,你是不能拖动视频的;所以我想到了另一个办法,当请求的url是miss的时候而且start不等于0的情况下,这个请求不缓存,这样用户在观看视频的时候即使squid的缓存中没有这个文件,他依然可以拖动,但这会牺牲一部分的带宽,当squid将视频抓取到本地之后就是cache hit了,视频访问就会开始快起来。
下面是实现squid拖动的补丁,这个补丁是去掉了加密信息内容的,因为我的测试环境下视频必须加密才能观看,所以我并没有测试下面这个补丁,这是个beta版的补丁,依然有很多需要改进的地方从而进一步完善它的功能。
[*]--- src/client_side.c 2010-02-14 08:46:25.000000000 +0800
[*]+++ src/client_side.c 2013-01-15 17:58:18.000000000 +0800
[*]@@ -106,7 +106,11 @@
[*] #define FAILURE_MODE_TIME 300
[*]
[*] /* Local functions */
[*]-
[*]+static int url_get_start(char *,const char *);
[*]+static int url_get_startvalue(char *, const char *, int, int);
[*]+static int firstBodyresponse(log_type , squid_off_t ,size_t);
[*]+static int isTcpMiss(log_type code);
[*] static CWCB clientWriteComplete;
[*] static CWCB clientWriteBodyComplete;
[*] static PF clientReadRequest;
[*]@@ -168,6 +172,112 @@
[*] static StoreEntry *clientCreateStoreEntry(clientHttpRequest *, method_t, request_flags);
[*] static inline int clientNatLookup(ConnStateData * conn);
[*]
[*]+static int
[*]+url_get_startvalue(char *uri,const char *key,int end,int urlen){
[*]+
[*]+ char *tmp;
[*]+ size_t offset=0;
[*]+ if(uri != '='){
[*]+ debug(33, 2) ("url_get_startvalue: it is invalid\n");
[*]+ return 0;
[*]+ }
[*]+ else{
[*]+ offset = (size_t)strtol(uri+end+2,&tmp,10);
[*]+ debug(33, 1) ("url_get_startvalue: start value is %d\n",(int)offset);
[*]+ return offset;
[*]+ }
[*]+}
[*]+
[*]+static int
[*]+url_get_start(char *url, const char *key) {
[*]+
[*]+ int find=0;
[*]+ size_t offset=0;
[*]+ int a=0;
[*]+ int b=0;
[*]+ int urlen=strlen(url);
[*]+ int keylen=strlen(key);
[*]+ LOCAL_ARRAY(char, uri, 2048);
[*]+ strcpy(uri,url);
[*]+ LOCAL_ARRAY(char, keyword, 40);
[*]+ strcpy(keyword,key);
[*]+
[*]+ while (aout.offset - size;
[*]+ if (isTcpMiss(http->log_type) == 1 && temp > 0 && temp < 1000){
[*]+ debug(33, 1) ("clientWriteBodyComplete: http->out.offset is %d, temp is %d, size is %d\n",(int)http->out.offset,(int)temp, (int)size);
[*]+ if (http->flvstart == 9)
[*]+ memFree(buf-9, MEM_STORE_CLIENT_BUF);
[*]+ else
[*]+ memFree(buf-13, MEM_STORE_CLIENT_BUF);
[*]+ }
[*]+ else
[*] memFree(buf, MEM_STORE_CLIENT_BUF);
[*] clientWriteComplete(fd, NULL, size, errflag, data);
[*] }
[*]
[*]@@ -3233,6 +3373,7 @@
[*] StoreEntry *entry = http->entry;
[*] int done;
[*] http->out.size += size;
[*]+ squid_off_t firstresponse = http->out.size;
[*] debug(33, 5) ("clientWriteComplete: FD %d, sz %d, err %d, off %" PRINTF_OFF_T ", len %" PRINTF_OFF_T "\n",
[*] fd, (int) size, errflag, http->out.offset, entry ? objectLen(entry) : (squid_off_t) 0);
[*] if (size > 0) {
[*]@@ -3303,6 +3444,17 @@
[*] } else if (clientReplyBodyTooLarge(http, http->out.offset - 4096)) {
[*] /* 4096 is a margin for the HTTP headers included in out.offset */
[*] comm_close(fd);
[*]+ } else if (firstBodyresponse(http->log_type,firstresponse,size) == 1) {
[*]+ debug(33, 1) ("clientWriteComplete:firstresponse is %d, size is %d\n",(int)firstresponse,(int)size);
[*]+ int response_prefix_len = 13 //13 is the string len of"FLV\x1\x1\0\0\0\x9\0\0\0\x9"
[*]+ LOCAL_ARRAY(char, response_prefix, 2048);
[*]+ memset(response_prefix,0,response_prefix_len);
[*]+ xmemcpy(response_prefix,"FLV\x1\x1\0\0\0\x9\0\0\0\x9",13);
[*]+ comm_write(fd, response_prefix, response_prefix_len, clientWriteComplete, http, NULL);
[*] } else {
[*] /* More data will be coming from primary server; register with
[*] * storage manager. */
[*]@@ -3870,6 +4022,8 @@
[*] goto invalid_request;
[*] }
[*] }
[*]+ http->flvstart = url_get_start(url,"start");/*get the start value, shunter add this*/
[*]+ http->flvstart = http->flvstart ? http->flvstart : 9;//13 is the length of"FLV\x1\x1\0\0\0\x9\0\0\0\x9";9=13-4
[*] if (!http->uri) {
[*] /* No special rewrites have been applied above, use the
[*] * requested url. may be rewritten later, so make extra room */
[*]@@ -4834,7 +4988,8 @@
[*] * objectLen(entry) will be set proprely.
[*] */
[*] if (entry->store_status == STORE_OK) {
[*]- if (http->out.offset >= objectLen(entry))
[*]+ if (http->out.offset + http->flvstart >= objectLen(entry))//modified by shunter
[*] return 1;
[*] else
[*] return 0;
[*]@@ -5204,3 +5359,6 @@
[*] }
[*] }
[*] #endif
[*]+
[*]+
[*]+
[*]--- src/ssl.c 2008-05-05 07:23:13.000000000 +0800
[*]+++ src/ssl.c 2012-12-27 18:25:09.000000000 +0800
[*]@@ -600,7 +600,7 @@
[*] &hdr_out,
[*] flags); /* flags */
[*] packerToMemInit(&p, &mb);
[*]- httpHeaderPackInto(&hdr_out, &p);
[*]+ httpHeaderPackInto(&hdr_out, &p,0);
[*] httpHeaderClean(&hdr_out);
[*] packerClean(&p);
[*] memBufAppend(&mb, "\r\n", 2);
[*]--- src/HttpReply.c 2008-01-23 23:31:51.000000000 +0800
[*]+++ src/HttpReply.c 2012-12-29 17:15:47.000000000 +0800
[*]@@ -140,19 +140,24 @@
[*] return (httpReplyParseStep(rep, buf, end) == 1);
[*] }
[*]
[*]+
[*] void
[*]-httpReplyPackInto(const HttpReply * rep, Packer * p)
[*]+httpReplyPackInto(const HttpReply * rep, Packer * p,size_t flvstart)
[*] {
[*] assert(rep);
[*] httpStatusLinePackInto(&rep->sline, p);
[*]- httpHeaderPackInto(&rep->header, p);
[*]+ httpHeaderPackInto(&rep->header, p,flvstart);
[*] packerAppend(p, "\r\n", 2);
[*] httpBodyPackInto(&rep->body, p);
[*] }
[*]-
[*] MemBuf
[*]-httpReplyPack(const HttpReply * rep)
[*]+httpReplyPack(const HttpReply * rep,size_t flvstart)//shunter
[*] {
[*] MemBuf mb;
[*] Packer p;
[*]@@ -160,7 +165,7 @@
[*]
[*] memBufDefInit(&mb);
[*] packerToMemInit(&p, &mb);
[*]- httpReplyPackInto(rep, &p);
[*]+ httpReplyPackInto(rep, &p,flvstart);
[*] packerClean(&p);
[*] return mb;
[*] }
[*]@@ -181,7 +186,7 @@
[*] rep = e->mem_obj->reply;
[*] }
[*] packerToStoreInit(&p, e);
[*]- httpReplyPackInto(e->mem_obj->reply, &p);
[*]+ httpReplyPackInto(e->mem_obj->reply, &p,0);//shunter
[*] packerClean(&p);
[*] rep->hdr_sz = e->mem_obj->inmem_hi - rep->body.mb.size;
[*] }
[*]@@ -216,7 +221,7 @@
[*] memBufPrintf(&mb, "HTTP/1.%d 304 Not Modified\r\n", http11);
[*] for (t = 0; ImsEntries != HDR_OTHER; ++t)
[*] if ((e = httpHeaderFindEntry(&rep->header, ImsEntries)))
[*]- httpHeaderEntryPackInto(e, &p);
[*]+ httpHeaderEntryPackInto(e, &p,0);//shunter
[*] memBufAppend(&mb, "\r\n", 2);
[*] packerClean(&p);
[*] return mb;
[*]--- src/HttpHeader.c 2008-09-25 10:33:37.000000000 +0800
[*]+++ src/HttpHeader.c 2013-01-15 10:28:03.000000000 +0800
[*]@@ -43,7 +43,7 @@
[*]* message-header = field-name ":" [ field-value ] CRLF
[*]* field-name = token
[*]* field-value = *( field-content | LWS )
[*]- *
[*]+ * +
[*]* HTTP/1.1 does not give a name name a group of all message-headers in a message.
[*]* Squid 1.1 seems to refer to that group _plus_ start-line as "headers".
[*]*
[*]@@ -572,9 +572,10 @@
[*] return 1; /* even if no fields where found, it is a valid header */
[*] }
[*]
[*]-/* packs all the entries using supplied packer */
[*]+
[*]+
[*] void
[*]-httpHeaderPackInto(const HttpHeader * hdr, Packer * p)
[*]+httpHeaderPackInto(const HttpHeader * hdr, Packer * p,size_t flvstart)
[*] {
[*] HttpHeaderPos pos = HttpHeaderInitPos;
[*] const HttpHeaderEntry *e;
[*]@@ -582,7 +583,7 @@
[*] debug(55, 7) ("packing hdr: (%p)\n", hdr);
[*] /* pack all entries one by one */
[*] while ((e = httpHeaderGetEntry(hdr, &pos)))
[*]- httpHeaderEntryPackInto(e, p);
[*]+ httpHeaderEntryPackInto(e, p,flvstart);//shunter
[*] }
[*]
[*] /* returns next valid entry */
[*]@@ -597,7 +598,6 @@
[*] }
[*] return NULL;
[*] }
[*]-
[*] /*
[*]* returns a pointer to a specified entry if any
[*]* note that we return one entry so it does not make much sense to ask for
[*]@@ -1331,12 +1331,19 @@
[*] httpHeaderAddEntry(hdr, httpHeaderEntryClone(e));
[*] }
[*]
[*]+
[*] void
[*]-httpHeaderEntryPackInto(const HttpHeaderEntry * e, Packer * p)
[*]+httpHeaderEntryPackInto(const HttpHeaderEntry * e, Packer * p,size_t flvstart)
[*] {
[*]- assert(e && p);
[*]+ char *tmp;
[*]+ assert(e && p);
[*] packerAppend(p, strBuf(e->name), strLen(e->name));
[*] packerAppend(p, ": ", 2);
[*]+ if(strcmp(e->name.buf,"Content-Length") == 0){
[*]+ size_t length=(size_t)strtol(e->value.buf,&tmp,10)-flvstart;
[*]+ snprintf(e->value.buf,20,"%ld",length);
[*]+ }
[*] packerAppend(p, strBuf(e->value), strLen(e->value));
[*] packerAppend(p, "\r\n", 2);
[*] }
[*]--- src/protos.h 2010-03-08 00:00:07.000000000 +0800
[*]+++ src/protos.h 2012-12-27 18:23:52.000000000 +0800
[*]@@ -448,7 +448,7 @@
[*] extern void httpHeaderUpdate(HttpHeader * old, const HttpHeader * fresh, const HttpHeaderMask * denied_mask);
[*] /* parse/pack */
[*] extern int httpHeaderParse(HttpHeader * hdr, const char *header_start, const char *header_end);
[*]-extern void httpHeaderPackInto(const HttpHeader * hdr, Packer * p);
[*]+extern void httpHeaderPackInto(const HttpHeader * hdr, Packer * p,size_t flvstart);
[*] /* field manipulation */
[*] extern int httpHeaderHas(const HttpHeader * hdr, http_hdr_type type);
[*] extern void httpHeaderPutInt(HttpHeader * hdr, http_hdr_type type, int number);
[*]@@ -486,7 +486,7 @@
[*] extern void httpHeaderAddEntry(HttpHeader * hdr, HttpHeaderEntry * e);
[*] extern void httpHeaderInsertEntry(HttpHeader * hdr, HttpHeaderEntry * e, int pos);
[*] extern HttpHeaderEntry *httpHeaderEntryClone(const HttpHeaderEntry * e);
[*]-extern void httpHeaderEntryPackInto(const HttpHeaderEntry * e, Packer * p);
[*]+extern void httpHeaderEntryPackInto(const HttpHeaderEntry * e, Packer * p,size_t flvstart);
[*] /* store report about current header usage and other stats */
[*] extern void httpHeaderStoreReport(StoreEntry * e);
[*] extern void httpHdrMangleList(HttpHeader *, request_t *);
[*]@@ -504,10 +504,10 @@
[*] extern void httpReplyReset(HttpReply * rep);
[*] /* parse returns -1,0,+1 on error,need-more-data,success */
[*] extern int httpReplyParse(HttpReply * rep, const char *buf, size_t);
[*]-extern void httpReplyPackInto(const HttpReply * rep, Packer * p);
[*]+extern void httpReplyPackInto(const HttpReply * rep, Packer * p,size_t flvstart);
[*] /* ez-routines */
[*] /* mem-pack: returns a ready to use mem buffer with a packed reply */
[*]-extern MemBuf httpReplyPack(const HttpReply * rep);
[*]+extern MemBuf httpReplyPack(const HttpReply * rep,size_t flvstart);
[*] /* swap: create swap-based packer, pack, destroy packer and absorbs the reply if not the same as the object reply */
[*] extern void httpReplySwapOut(HttpReply * rep, StoreEntry * e);
[*] /* set commonly used info with one call */
[*]--- src/store.c 2010-02-14 08:45:52.000000000 +0800
[*]+++ src/store.c 2013-01-15 17:17:31.000000000 +0800
[*]@@ -1233,7 +1233,10 @@
[*] store_check_cachable_hist.no.non_get++;
[*] } else
[*] #endif
[*]- if (e->store_status == STORE_OK && EBIT_TEST(e->flags, ENTRY_BAD_LENGTH)) {
[*]+ if (e->flvstart != 9){//shunter
[*]+ debug(20, 1) ("storeCheckCachable: start value is not 0,so squid neednot to create entry on disk\n");
[*]+ } else if (e->store_status == STORE_OK && EBIT_TEST(e->flags, ENTRY_BAD_LENGTH)) {
[*] debug(20, 2) ("storeCheckCachable: NO: wrong content-length\n");
[*] store_check_cachable_hist.no.wrong_content_length++;
[*] } else if (EBIT_TEST(e->flags, RELEASE_REQUEST)) {
[*]--- src/store_client.c2009-09-17 04:55:26.000000000 +0800
[*]+++ src/store_client.c2013-01-05 15:24:39.000000000 +0800
[*]@@ -180,6 +180,7 @@
[*] #if STORE_CLIENT_LIST_DEBUG
[*] assert(sc == storeClientListSearch(e->mem_obj, data));
[*] #endif
[*]+ clientHttpRequest *http = data;/*added by shunter*/
[*] assert(sc->callback == NULL);
[*] assert(sc->entry == e);
[*] sc->seen_offset = seen_offset;
[*]@@ -189,6 +190,7 @@
[*] sc->copy_buf = buf;
[*] sc->copy_size = size;
[*] sc->copy_offset = copy_offset;
[*]+ sc->flvstart = http->flvstart;/*added by shunter*/
[*] /* If the read is being deferred, run swapout in case this client has the
[*] * lowest seen_offset. storeSwapOut() frees the memory and clears the
[*] * ENTRY_DEFER_READ bit if necessary */
[*]@@ -347,7 +349,8 @@
[*] storeRead(sc->swapin_sio,
[*] sc->copy_buf,
[*] sc->copy_size,
[*]- sc->copy_offset + mem->swap_hdr_sz,
[*]+ sc->copy_offset + mem->swap_hdr_sz + sc->flvstart,/*added by shunter*/
[*] storeClientReadBody,
[*] sc);
[*] }
[*]--- src/HttpRequest.c 2009-08-17 05:43:51.000000000 +0800
[*]+++ src/HttpRequest.c 2012-12-27 18:24:37.000000000 +0800
[*]@@ -116,7 +116,7 @@
[*] packerPrintf(p, "%s %s HTTP/%d.%d\r\n",
[*] RequestMethods.str, strBuf(req->urlpath), req->http_ver.major, req->http_ver.minor);
[*] /* headers */
[*]- httpHeaderPackInto(&req->header, p);
[*]+ httpHeaderPackInto(&req->header, p,0);
[*] /* trailer */
[*] packerAppend(p, "\r\n", 2);
[*] }
[*]@@ -136,7 +136,7 @@
[*] packerPrintf(p, "%s %s HTTP/%d.%d\r\n",
[*] RequestMethods.str, urlCanonical(req), req->http_ver.major, req->http_ver.minor);
[*] /* headers */
[*]- httpHeaderPackInto(&req->header, p);
[*]+ httpHeaderPackInto(&req->header, p,0);
[*] /* trailer */
[*] packerAppend(p, "\r\n", 2);
[*] }
[*]--- src/http.c2009-06-26 06:54:13.000000000 +0800
[*]+++ src/http.c2012-12-27 18:22:58.000000000 +0800
[*]@@ -987,7 +987,7 @@
[*] httpBuildVersion(&reply->sline.version, 0, 9);
[*] reply->sline.status = HTTP_OK;
[*] httpHeaderPutTime(&reply->header, HDR_DATE, squid_curtime);
[*]- mb = httpReplyPack(reply);
[*]+ mb = httpReplyPack(reply,0);
[*] storeAppend(entry, mb.buf, mb.size);
[*] storeAppend(entry, httpState->reply_hdr.buf, httpState->reply_hdr.size);
[*] memBufClean(&httpState->reply_hdr);
[*]@@ -1411,7 +1411,7 @@
[*] else
[*] request->flags.auth_sent = httpHeaderHas(&hdr, HDR_AUTHORIZATION);
[*] packerToMemInit(&p, mb);
[*]- httpHeaderPackInto(&hdr, &p);
[*]+ httpHeaderPackInto(&hdr, &p,0);
[*] httpHeaderClean(&hdr);
[*] packerClean(&p);
[*] }
[*]--- src/structs.h 2008-09-25 10:33:37.000000000 +0800
[*]+++ src/structs.h 2013-01-15 17:07:38.000000000 +0800
[*]@@ -1275,6 +1275,7 @@
[*] STHCB *header_callback; /* Temporarily here for storeClientCopyHeaders */
[*] StoreEntry *header_entry;/* Temporarily here for storeClientCopyHeaders */
[*] int is_modified;
[*]+ size_t flvstart; /*shunter add this to store the start value of url*/
[*] };
[*]
[*] struct _ConnStateData {
[*]@@ -1695,6 +1696,7 @@
[*] #if STORE_CLIENT_LIST_DEBUG
[*] void *owner;
[*] #endif
[*]+ size_t flvstart; /*the flv start value added by shunter*/
[*] };
[*]
[*]
[*]@@ -1794,6 +1796,7 @@
[*] ping_status_t ping_status:3;
[*] store_status_t store_status:3;
[*] swap_status_t swap_status:3;
[*]+ size_t flvstart;//shunter
[*] };
[*]
[*] struct _SwapDir {
[*]--- src/comm.c2008-06-28 04:56:56.000000000 +0800
[*]+++ src/comm.c2013-01-11 17:03:17.000000000 +0800
[*]@@ -61,6 +61,7 @@
[*] } ConnectStateData;
[*]
[*] /* STATIC */
[*]+static int isTcpMiss(log_type code);//shunter
[*] static int commBind(int s, struct in_addr, u_short port);
[*] static void commSetReuseAddr(int);
[*] static void commSetNoLinger(int);
[*]@@ -81,6 +82,23 @@
[*] static MemPool *comm_write_pool = NULL;
[*] static MemPool *conn_close_pool = NULL;
[*]
[*]+static int
[*]+isTcpMiss(log_type code)
[*]+{
[*]+ /* this should be a bitmap for better optimization */
[*]+ if (code == LOG_TCP_MISS)
[*]+ return 1;
[*]+ if (code == LOG_TCP_REFRESH_MISS)
[*]+ return 1;
[*]+ if (code == LOG_TCP_CLIENT_REFRESH_MISS)
[*]+ return 1;
[*]+ if (code == LOG_TCP_SWAPFAIL_MISS)
[*]+ return 1;
[*]+ if (code == LOG_TCP_ASYNC_MISS)
[*]+ return 1;
[*]+ return 0;
[*]+}
[*]+
[*] static void
[*] CommWriteStateCallbackAndFree(int fd, int code)
[*] {
[*]@@ -876,7 +894,7 @@
[*] need_read = 1;
[*] break;
[*] case COMM_PENDING_NOW:
[*]- need_read = 1;/* Not really I/O dependent, but this shuld get comm_select to wake up */
[*]+ need_read = 1;/* Not really I/O dependent, but this should get comm_select to wake up */
[*] need_write = 1;
[*] break;
[*] }
页:
[1]