static void initChunksCommon() { #define ROUND_CHUNKS(a) a = (((a) + CHUNK_SIZE - 1) / CHUNK_SIZE) * CHUNK_SIZE; int q; if (CHUNK_SIZE != 1 << log2_ceil(CHUNK_SIZE)) { do_log(L_ERROR, "CHUNK SIZE %d is not a power of two.\n", CHUNK_SIZE); exit(1); } ROUND_CHUNKS(chunkHighMark); ROUND_CHUNKS(chunkCriticalMark); ROUND_CHUNKS(chunkLowMark); if (chunkHighMark < 8 * CHUNK_SIZE) { int mem = physicalMemory(); if (mem > 0) chunkHighMark = mem / 4; else chunkHighMark = 24 * MB; chunkHighMark = MIN(chunkHighMark, 24 * MB); chunkHighMark = MAX(chunkHighMark, 8 * CHUNK_SIZE); } if (chunkHighMark < MB / 2) fprintf(stderr, "Warning: little chunk memory (%d bytes)\n", chunkHighMark); q = 0; if (chunkLowMark <= 0) q = 1; if (chunkLowMark < 4 * CHUNK_SIZE || chunkLowMark > chunkHighMark - 4 * CHUNK_SIZE) { chunkLowMark = MIN(chunkHighMark - 4 * CHUNK_SIZE, chunkHighMark * 3 / 4); ROUND_CHUNKS(chunkLowMark); if (!q) do_log(L_WARN, "Inconsistent chunkLowMark -- setting to %d.\n", chunkLowMark); } q = 0; if (chunkCriticalMark <= 0) q = 1; if (chunkCriticalMark >= chunkHighMark - 2 * CHUNK_SIZE || chunkCriticalMark <= chunkLowMark + 2 * CHUNK_SIZE) { chunkCriticalMark = MIN(chunkHighMark - 2 * CHUNK_SIZE, chunkLowMark + (chunkHighMark - chunkLowMark) * 15 / 16); ROUND_CHUNKS(chunkCriticalMark); if (!q) do_log(L_WARN, "Inconsistent chunkCriticalMark -- " "setting to %d.\n", chunkCriticalMark); } #undef ROUND_CHUNKS }
int check_server_headers(struct server_answ *a, struct mem_obj *obj, const char *b,int len, struct request *rq) { char *start, *beg, *end, *p; char holder, its_here = 0, off = 2; char *p1 = NULL; a->http_result=0; assert(a); assert(obj); assert(b); assert(rq); sscanf(b,"%*s %d",&a->http_result); // if ( !b || !b->data ) return(0); beg =(char *) b; end = (char *)b + len; if ( end - beg > MAX_DOC_HDR_SIZE ) { /* Header is too large */ return(1); } go: if ( a->state & GOT_HDR ) return(0); start = beg + a->checked; if ( !a->checked ) { p = (char *)memchr(beg, '\n', end-beg); holder = '\n'; if ( !p ) { p = (char *)memchr(beg, '\r', end-beg); holder = '\r'; } if ( !p ) return(0); if ( *p == '\n' ) { if ( *(p-1) == '\r' ) { p1 = p-1; *p1 = 0; } } *p = 0; a->checked = strlen(start); /* this is HTTP XXX yyy "header", which we will never rewrite */ analyze_header(start, a); if ( add_header_av(start, obj) ) { *p = holder; if ( p1 ) { *p1 = '\r'; p1=NULL; } return(-1); } *p = holder; if ( p1 ) { *p1 = '\r'; p1=NULL; } goto go; } if ( (end - start >= 2) && !memcmp(start, "\n\n", 2) ) { its_here = 1; off = 2; } if ( (end - start >= 3) && !memcmp(start, "\r\n\n", 3) ) { its_here = 1; off = 3; } if ( (end - start >= 3) && !memcmp(start, "\n\r\n", 3) ) { its_here = 1; off = 3; } if ( (end - start >= 4) && !memcmp(start, "\r\n\r\n", 4) ) { its_here = 1; off = 4; } if ( its_here ) { struct buff *body; int all_siz; obj->insertion_point = start-beg; obj->tail_length = off; a->state |= GOT_HDR ; obj->httpv_major = a->httpv_major; obj->httpv_minor = a->httpv_minor; obj->content_length = a->content_len; // b->used = ( start + off ) - beg; /* trunc first buf to header siz */ /* if requested don't cache documents without "Last-Modified" */ /* allocate data storage */ if ( a->content_len ) { if ( a->content_len > maxresident ) { /* - This object will not be stored, we will receive it in - small parts, in syncronous mode - allocate as much as we need now... */ all_siz = ROUND_CHUNKS(end-start-off); /* - mark object as 'not for store' and 'don't expand container' */ a->flags |= (ANSW_NO_STORE | ANSW_SHORT_CONTAINER); } else {/* obj is not too large */ all_siz = MIN(a->content_len, 8192); } } else { /* no Content-Len: */ char *transfer_encoding = NULL; all_siz = ROUND_CHUNKS(end-start-off); transfer_encoding = attr_value(obj->headers, "Transfer-Encoding"); if ((transfer_encoding && !strncasecmp("chunked", transfer_encoding, 7)) ) { a->flags |= (ANSW_NO_STORE | ANSW_SHORT_CONTAINER); } } body = alloc_buff(all_siz); if ( !body ) { return(-1); } // b->next = body; obj->container=obj->hot_buff = body; attach_data(start+off, end-start-off, obj->hot_buff); return(0); } p = start; while( (p < end) && ( *p == '\r' || *p == '\n' ) ) p++; if ( p < end && *p ) { char *t = (char *)memchr(p, '\n', end-p); char *tmp, *saved_tmp; holder = '\n'; if ( !t ) { t = (char *)memchr(p, '\r', end-p); holder = '\r'; } if ( !t ) return(0); if ( *t == '\n' ) { if ( *(t-1) == '\r' ) { p1 = t-1; *p1 = 0; } } *t = 0; saved_tmp = tmp = strdup(p); if ( !tmp ) return(-1); // do_redir_rewrite_header(&tmp, rq, NULL); analyze_header(tmp, a); if ( add_header_av(tmp, obj) ) { free(tmp); return(-1); } if ( saved_tmp != tmp ) { /* header was changed */ if ( obj ) SET(obj->flags, ANSW_HDR_CHANGED); } free(tmp); *t = holder; if ( p1 ) { *p1 = '\r'; t=p1; p1 = NULL; } a->checked = t - beg; goto go; } return(0); }