Esempio n. 1
0
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);
}