Beispiel #1
0
/*
**  Check whether we can cache this object or not.
*/
PUBLIC HTCachable HTResponse_isCachable (HTResponse * me)
{
    if (me) {

        /* We may already have decided that this object is not cachable */
        if (me->cachable == HT_NO_CACHE) return HT_NO_CACHE;

#if 0
        /*  We don't cache negotiated resources for the moment */
        if (me->variants) return HT_NO_CACHE;
#endif

        /*
        **  Check if we should cache this object or not. We are very liberale
        **  in that we cache everything except if we explicit are told not to
        **  cache (no-store, no-cache). In all other cases we can get around
        **  it by forcing revalidation
        */
        if (me->cache_control) {
            char * token;
            if ((token=HTAssocList_findObject(me->cache_control, "no-store")))
                return HT_NO_CACHE;
            if ((token=HTAssocList_findObject(me->cache_control, "no-cache")))
                if (!*token) return HT_NO_CACHE;
        }

        /* Cache everything else */
        return me->cachable;
    }
    return HT_NO_CACHE;
}
Beispiel #2
0
PUBLIC HTStream * HTBoundary   (HTRequest *	request,
				void *		param,
				HTFormat	input_format,
				HTFormat	output_format,
				HTStream *	output_stream)
{
    HTResponse * response = HTRequest_response(request);
    HTParentAnchor * anchor = HTRequest_anchor(request);
    HTAssocList * type_param = response ?
	HTResponse_formatParam(response) :
	HTAnchor_formatParam(anchor);
    char * boundary = HTAssocList_findObject(type_param, "boundary");
    if (boundary) {
	HTStream * me;
	if ((me = (HTStream  *) HT_CALLOC(1, sizeof(HTStream))) == NULL)
	    HT_OUTOFMEM("HTBoundary");
	me->isa = &HTBoundaryClass;
	me->request = request;
	me->format = output_format;
	me->orig_target = output_stream;
	me->debug = HTRequest_debugStream(request);
	me->state = EOL_FLF;
	StrAllocCopy(me->boundary, boundary);		       /* Local copy */
	me->bpos = me->boundary;
	HTTRACE(STREAM_TRACE, "Boundary.... Stream created with boundary '%s\'\n" _ me->boundary);
	return me;
    } else {
	HTTRACE(STREAM_TRACE, "Boundary.... UNKNOWN boundary!\n");
	return HTErrorStream();
    }
}
Beispiel #3
0
/*	Content Base
**	------------
*/
PUBLIC char * HTAnchor_base (HTParentAnchor * me)
{
    if (me) {
	if (me->content_base) return me->content_base;
	if (me->headers) {
	    char * base = HTAssocList_findObject(me->headers, "content-base");
	    /*
	    **  If no base is found then take the content-location if this
	    **  is present and is absolute, else use the Request-URI.
	    */
	    if (base) StrAllocCopy(me->content_base, HTStrip(base));
	}

	/*
	**  Try the content location if any
	*/
	{
	    char * location = HTAnchor_location(me);
	    StrAllocCopy(me->content_base,
			 (location && HTURL_isAbsolute(location)) ?
			 location : me->address);
	}
	return me->content_base;
    }
    return NULL;
}
Beispiel #4
0
/*
**	robots meta tag
*/
PUBLIC char * HTAnchor_robots (HTParentAnchor * me)
{
    if (me && me->meta_tags) {
	char * robots = HTAssocList_findObject(me->meta_tags, "robots");
	return robots;
    }
    return NULL;
}
Beispiel #5
0
/*
**	Level parameter to Content-Type
*/
PUBLIC HTLevel HTAnchor_level (HTParentAnchor * me)
{
    if (me && me->type_parameters) {
	char * level = HTAssocList_findObject(me->type_parameters, "level");
	return HTAtom_for(level);
    }
    return NULL;
}
Beispiel #6
0
PUBLIC time_t HTResponse_maxAge (HTResponse * me)
{
    if (me && me->cache_control) {
        char * token = HTAssocList_findObject(me->cache_control, "max-age");
        if (token) return atol(token);
    }
    return (time_t) -1;
}
Beispiel #7
0
/*
**  Charset parameter to Content-Type
*/
PUBLIC HTCharset HTResponse_charset (HTResponse * me)
{
    if (me && me->type_parameters) {
        char * charset = HTAssocList_findObject(me->type_parameters,"charset");
        return HTAtom_for(charset);
    }
    return NULL;
}
Beispiel #8
0
/*
**  Take the relevant infomration from the response object and cache it
**  in the anchor object. We inherit the information that is already
**  parsed in the response along with the unparsed headers.
*/
PUBLIC BOOL HTAnchor_update (HTParentAnchor * me, HTResponse * response)
{
    if (me && response) {
	HTCachable cachable = HTResponse_isCachable(response);

	if (cachable == HT_CACHE_ETAG) {
	    char * etag = HTResponse_etag(response);
	    HTTRACE(ANCH_TRACE, "HTAnchor.... Updating etag for %p\n" _ me);
	    if (etag) {
		HTAnchor_setEtag(me, etag);
		return YES;
	    }

	} else if (cachable == HT_CACHE_NOT_MODIFIED) {
	    HTTRACE(ANCH_TRACE, "HTAnchor.... Information is up to date for %p\n" _ me);
	    return YES;

	} else if (cachable == HT_CACHE_ALL) {
	    char * etag = HTResponse_etag(response);
	    HTTRACE(ANCH_TRACE, "HTAnchor.... Updating metainformation for %p\n" _ me);

	    /*
	    **  The content length and type is already parsed at this point
	    **  in time. We also check for format parameters like charset etc.
	    **  and copy the contents in the anchor object
	    */
	    me->content_length = HTResponse_length(response);
	    me->content_type = HTResponse_format(response);
	    me->type_parameters = HTResponse_formatParam(response);
	    me->content_encoding = HTResponse_encoding(response);
	
            /* Don't forget the etag as well */
       	    if (etag) HTAnchor_setEtag(me, etag);

	    /*
	    **  Inherit all the unparsed headers - we may need them later!
	    */
	    if (me->headers) HTAssocList_delete(me->headers);
	    me->headers = HTResponse_handOverHeader(response);

	    /*
	    **  Notifify the response object not to delete the lists that we
	    **  have inherited in the anchor object
	    */
	    HTResponse_isCached(response, YES);

	    /*
	    **  Set the datestamp of when the anchor was updated if we didn't
	    **  get any in the response
	    */
	    if (!HTAssocList_findObject(me->headers, "date"))
		HTAnchor_setDate(me, time(NULL));

	    return YES;
	}
    }
    return NO;
}
Beispiel #9
0
PUBLIC char * HTResponse_etag (HTResponse * me)
{
    if (me && me->headers) {
        char * value = HTAssocList_findObject(me->headers, "etag");
        char * etag = HTNextField(&value);
        return etag;
    }
    return NULL;
}
Beispiel #10
0
/*
**	Expires
*/
PUBLIC time_t HTAnchor_expires (HTParentAnchor * me)
{
    if (me) {
	if (me->expires == (time_t) -1 && me->headers) {
	    char * value = HTAssocList_findObject(me->headers, "expires");
	    if (value) me->expires = HTParseTime(value, NULL, YES);
	}
	return me->expires;
    }	
    return (time_t) -1;
}
Beispiel #11
0
/*
**	Date
*/
PUBLIC time_t HTAnchor_date (HTParentAnchor * me)
{
    if (me) {
	if (me->date == (time_t) -1 && me->headers) {
	    char * value = HTAssocList_findObject(me->headers, "date");
	    if (value) me->date = HTParseTime(value, NULL, YES);
	}
	return me->date;
    }	
    return (time_t) -1;
}
Beispiel #12
0
/*
**	Age
*/
PUBLIC time_t HTAnchor_age (HTParentAnchor * me)
{
    if (me) {
	if (me->age == (time_t) -1 && me->headers) {
	    char * value = HTAssocList_findObject(me->headers, "age");
	    if (value) me->age = atol(value);
	}
	return me->age;
    }	
    return (time_t) -1;
}
Beispiel #13
0
/*
**	Last Modified
*/
PUBLIC time_t HTAnchor_lastModified (HTParentAnchor * me)
{
    if (me) {
	if (me->last_modified == (time_t) -1 && me->headers) {
	    char * value = HTAssocList_findObject(me->headers,"last-modified");
	    if (value) me->last_modified = HTParseTime(value, NULL, YES);
	}
	return me->last_modified;
    }	
    return (time_t) -1;
}
Beispiel #14
0
/*	Content Location
**	----------------
*/
PUBLIC char * HTAnchor_location (HTParentAnchor * me)
{
    if (me) {
	if (me->content_location)
	    return *me->content_location ? me->content_location : NULL;
	if (me->headers) {
	    char * location = HTAssocList_findObject(me->headers, "content-location");
	    StrAllocCopy(me->content_location, location ? HTStrip(location) : "");
	    return me->content_location;
	}
    }
    return NULL;
}
Beispiel #15
0
/*
**	Title
*/
PUBLIC const char * HTAnchor_title  (HTParentAnchor * me)
{
    if (me) {
	if (me->title)
	    return *me->title ? me->title : NULL;
	if (me->headers) {
	    char * value = HTAssocList_findObject(me->headers, "title");
	    char * title;
	    if ((title = HTNextField(&value))) StrAllocCopy(me->title, title);
	    return me->title;
	}
    }
    return NULL;
}
Beispiel #16
0
/*
**	Content MD5
*/
PUBLIC char * HTAnchor_md5 (HTParentAnchor * me)
{
    if (me) {
	if (me->content_md5)
	    return *me->content_md5 ? me->content_md5 : NULL;
	if (me->headers) {
	    char * value = HTAssocList_findObject(me->headers, "content-md5");
	    char * md5;
	    if ((md5 = HTNextField(&value))) StrAllocCopy(me->content_md5,md5);
	    return me->content_md5;
	}
    }
    return NULL;
}
Beispiel #17
0
/*
**	Version
*/
PUBLIC char * HTAnchor_version (HTParentAnchor * me)
{
    if (me) {
	if (me->version)
	    return *me->version ? me->version : NULL;
	if (me->headers) {
	    char * value = HTAssocList_findObject(me->headers, "version");
	    char * version;
	    if ((version = HTNextField(&value)))
		StrAllocCopy(me->version, version);
	    return me->version;
	}
    }
    return NULL;
}
Beispiel #18
0
/*
**	Derived from
*/
PUBLIC char * HTAnchor_derived (HTParentAnchor * me)
{
    if (me) {
	if (me->derived_from)
	    return *me->derived_from ? me->derived_from : NULL;
	if (me->headers) {
	    char * value = HTAssocList_findObject(me->headers, "derived-from");
	    char * derived_from;
	    if ((derived_from = HTNextField(&value)))
		StrAllocCopy(me->derived_from, derived_from);
	    return me->derived_from;
	}
    }
    return NULL;
}
Beispiel #19
0
/*
**	Entity Tag
*/
PUBLIC char * HTAnchor_etag (HTParentAnchor * me)
{
    if (me) {
	if (me->etag)
	    return *me->etag ? me->etag : NULL;
	if (me->headers) {
	    char * value = HTAssocList_findObject(me->headers, "etag");
	    char * etag;
	    if ((etag = HTNextField(&value))) StrAllocCopy(me->etag, etag);
	    return me->etag;
	}
    }

    return me ? me->etag : NULL;
}
Beispiel #20
0
/*
**	Content Language
*/
PUBLIC HTList * HTAnchor_language (HTParentAnchor * me)
{
    if (me) {
	if (me->content_language == NULL && me->headers) {
	    char * value = HTAssocList_findObject(me->headers, "content-language");
	    char * field;
	    if (!me->content_language) me->content_language = HTList_new();
	    while ((field = HTNextField(&value)) != NULL) {
		char * lc = field;
		while ((*lc = TOLOWER(*lc))) lc++;
		HTList_addObject(me->content_language, HTAtom_for(field));
	    }
	}
	return me->content_language;
    }
    return NULL;
}
Beispiel #21
0
/*
**	Allowed methods	(Allow)
*/
PUBLIC HTMethod HTAnchor_allow (HTParentAnchor * me)
{
    if (me) {
	if (me->allow == 0 && me->headers) {
	    char * value = HTAssocList_findObject(me->headers, "allow");
	    char * field;

	    /*
	    **  We treat methods allowed on this object as case insensitive
	    **  in case we receive the information over the net - that is -
	    **  in the Allow header.
	    */
	    while ((field = HTNextField(&value)) != NULL) {
		HTMethod new_method;
		if ((new_method = HTMethod_enum(field)) != METHOD_INVALID)
		    me->allow |= new_method;
	    }
	}
	return me->allow;
    }	
    return METHOD_INVALID;
}
Beispiel #22
0
PUBLIC char * HTResponse_noCache (HTResponse * me)
{
    return (me && me->cache_control) ?
           HTAssocList_findObject(me->cache_control,
                                  "no-cache") : NULL;
}
Beispiel #23
0
PUBLIC BOOL HTResponse_mustRevalidate (HTResponse * me)
{
    return me && me->cache_control &&
           (HTAssocList_findObject(me->cache_control,
                                   "must-revalidate") != NULL);
}