Esempio n. 1
0
MemBuf
httpPackedReply(http_version_t ver, http_status status, const char *ctype,
    squid_off_t clen, time_t lmt, time_t expires)
{
    HttpReply *rep = httpReplyCreate();
    MemBuf mb;
    httpReplySetHeaders(rep, ver, status, ctype, NULL, clen, lmt, expires);
    mb = httpReplyPack(rep);
    httpReplyDestroy(rep);
    return mb;
}
Esempio n. 2
0
/*
 * Function:  errorSend
 *
 * Arguments: err - This object is destroyed after use in this function.
 *
 * Abstract:  This function generates a error page from the info contained
 *            by 'err' and then sends it to the client.
 *            The callback function errorSendComplete() is called after
 *            the page has been written to the client socket (fd).
 *            errorSendComplete() deallocates 'err'.  We need to add
 *            'err' to the cbdata because comm_write() requires it
 *            for all callback data pointers.
 *
 *            Note, normally errorSend() should only be called from
 *            routines in ssl.c and pass.c, where we don't have any
 *            StoreEntry's.  In client_side.c we must allocate a StoreEntry
 *            for errors and use errorAppendEntry() to account for
 *            persistent/pipeline connections.
 */
void
errorSend(int fd, ErrorState * err)
{
    HttpReply *rep;
    debug(4, 3) ("errorSend: FD %d, err=%p\n", fd, err);
    assert(fd >= 0);
    /*
     * ugh, this is how we make sure error codes get back to
     * the client side for logging and error tracking.
     */
    if (err->request)
	err->request->err_type = err->type;
    /* moved in front of errorBuildBuf @?@ */
    err->flags.flag_cbdata = 1;
    rep = errorBuildReply(err);
    comm_write_mbuf(fd, httpReplyPack(rep), errorSendComplete, err);
    httpReplyDestroy(rep);
}
Esempio n. 3
0
/*
 * The helper program receives queries on stdin, one
 * per line, and must return the result on on stdout
 */
static void
refreshCheckHandleReply(void *data, char *reply)
{
    refreshCheckState *state = data;
    refreshCheckState *next;
    int freshness = -1;
    char *log = NULL;
    MemBuf hdrs = MemBufNULL;


    debug(84, 2) ("refreshCheckHandleReply: reply=\"%s\"\n", reply);

    if (reply) {
	char *t = NULL;
	char *token = strwordtok(reply, &t);
	if (token && strcmp(token, "FRESH") == 0)
	    freshness = 0;
	else if (token && strcmp(token, "OK") == 0)
	    freshness = 0;

	while ((token = strwordtok(NULL, &t))) {
	    char *value = strchr(token, '=');
	    if (value) {
		*value++ = '\0';	/* terminate the token, and move up to the value */
		rfc1738_unescape(value);
		if (strcmp(token, "freshness") == 0)
		    freshness = atoi(value);
		else if (strcmp(token, "log") == 0)
		    log = value;
		else if (strncmp(token, "res{", 4) == 0) {
		    char *header, *t;
		    header = token + 4;
		    t = strrchr(header, '}');
		    if (!t)
			continue;
		    *t = '\0';
		    if (!hdrs.buf)
			memBufDefInit(&hdrs);
		    memBufPrintf(&hdrs, "%s: %s\r\n", header, value);
		}
	    }
	}
    }
    if (freshness >= 0) {
	if (hdrs.size) {
	    HttpReply *rep = httpReplyCreate();
	    httpHeaderParse(&rep->header, hdrs.buf, hdrs.buf + hdrs.size);
	    httpReplyUpdateOnNotModified(state->entry->mem_obj->reply, rep);
	    storeTimestampsSet(state->entry);
	    if (!httpHeaderHas(&rep->header, HDR_DATE)) {
		state->entry->timestamp = squid_curtime;
		state->entry->expires = squid_curtime + freshness;
	    } else if (freshness) {
		state->entry->expires = squid_curtime + freshness;
	    }
	    httpReplyDestroy(rep);
	    storeUpdate(state->entry, NULL);
	} else {
	    state->entry->timestamp = squid_curtime;
	    state->entry->expires = squid_curtime + freshness;
	}
    }
    if (hdrs.buf)
	memBufClean(&hdrs);
    dlinkDelete(&state->list, &state->def->queue);
    do {
	cbdataUnlock(state->def);
	state->def = NULL;

	if (state->callback && cbdataValid(state->callback_data))
	    state->callback(state->callback_data, freshness >= 0, log);
	cbdataUnlock(state->callback_data);
	state->callback_data = NULL;

	next = state->queue;
	cbdataFree(state);
	state = next;
    } while (state);
}
Esempio n. 4
0
static int
buildRespModHeader(MemBuf * mb, IcapStateData * icap, char *buf,
    ssize_t len, int theEnd)
{
    MemBuf mb_hdr;
    char *client_addr;
    int o2=0;
    int o3=0;
    int hlen;
    int consumed;
    icap_service *service;
    HttpReply *r;

    if (memBufIsNull(&icap->respmod.req_hdr_copy))
	memBufDefInit(&icap->respmod.req_hdr_copy);

    memBufAppend(&icap->respmod.req_hdr_copy, buf, len);

    if (icap->respmod.req_hdr_copy.size > 4 && strncmp(icap->respmod.req_hdr_copy.buf, "HTTP/", 5)) {
	debug(81, 3) ("buildRespModHeader: Non-HTTP-compliant header: '%s'\n", buf);
	/*
	 *Possible we can consider that we did not have http responce headers 
	 *(maybe HTTP 0.9 protocol), lets returning -1...
	 */
	consumed=-1;
	o2=-1;
	memBufDefInit(&mb_hdr);
    }
    else{

        hlen = headersEnd(icap->respmod.req_hdr_copy.buf,
			   icap->respmod.req_hdr_copy.size);
        debug(81, 3) ("buildRespModHeader: headersEnd = %d(%s)\n", hlen,buf);
        if (0 == hlen)
            return 0;

	/*
	 * calc how many bytes from this 'buf' went towards the
	 * reply header.
	 */
	consumed = hlen - (icap->respmod.req_hdr_copy.size - len);
	debug(81, 3) ("buildRespModHeader: consumed = %d\n", consumed);


	/*
	 * now, truncate our req_hdr_copy at the header end.
	 * this 'if' statement might be unncessary?
	 */
	if (hlen < icap->respmod.req_hdr_copy.size)
	     icap->respmod.req_hdr_copy.size = hlen;
	
	/* Copy request header */
	memBufDefInit(&mb_hdr);
	httpBuildRequestPrefix(icap->request, icap->request,
			       icap->respmod.entry, &mb_hdr, icap->http_flags);
	o2 = mb_hdr.size;
    }

    /* Copy response header - Append to request header mbuffer */
    memBufAppend(&mb_hdr,
	icap->respmod.req_hdr_copy.buf, icap->respmod.req_hdr_copy.size);
    o3 = mb_hdr.size;

    service = icap->current_service;
    assert(service);
    client_addr = inet_ntoa(icap->request->client_addr);

    r = httpReplyCreate();
    httpReplyParse(r, icap->respmod.req_hdr_copy.buf,
	icap->respmod.req_hdr_copy.size);
    icap->respmod.res_body_sz = httpReplyBodySize(icap->request->method, r);
    httpReplyDestroy(r);
    if (icap->respmod.res_body_sz)
	getICAPRespModString(mb, 0, o2, o3, client_addr, icap, service);
    else
	getICAPRespModString(mb, 0, o2, -o3, client_addr, icap, service);
    if (Config.icapcfg.preview_enable)
	if (icap->preview_size >= 0) {
	    memBufPrintf(mb, "Preview: %d\r\n", icap->preview_size);
	    icap->flags.preview_done = 0;
	}
    if(service->keep_alive){
	icap->flags.keep_alive = 1;
	memBufAppend(mb, "Connection: keep-alive\r\n", 24);
    }
    else{
	icap->flags.keep_alive = 0;
	memBufAppend(mb, "Connection: close\r\n", 19);
    }
    memBufAppend(mb, crlf, 2);
    memBufAppend(mb, mb_hdr.buf, mb_hdr.size);
    memBufClean(&mb_hdr);


    return consumed;
}