Exemple #1
0
FskErr KprQuerySerialize(FskAssociativeArray array, char** it)
{
	FskErr err = kFskErrNone;
	FskAssociativeArrayIterator iterate = FskAssociativeArrayIteratorNew(array);
	SInt32 length = 0;
	char* p;
	while (iterate) {
		if (length)
			length++;
		length += FskStrLen(iterate->name);
		length++;
		length += FskStrLen(iterate->value);
	}
	length++;
	FskAssociativeArrayIteratorDispose(iterate);
	iterate = NULL;
	bailIfError(FskMemPtrNew(length, it));
	iterate = FskAssociativeArrayIteratorNew(array);
	p = *it;
	*p = 0;
	while (iterate) {
		if (*p)
			*p++ = '&';
		FskStrCopy(p, iterate->name);
		p += FskStrLen(iterate->name);
		*p++ = '=';
		FskStrCopy(p, iterate->value);
		p += FskStrLen(iterate->value);
	}
	*p = 0;
	FskAssociativeArrayIteratorDispose(iterate);
bail:
	return err;
}
FskErr KprZeroconfPlatformAdvertisementStart(KprZeroconfAdvertisement self)
{
	FskErr err = kFskErrNone;
	char* txt = NULL;
	UInt32 size = 0, offset = 0, length;
	KprZeroconfPlatformAdvertisement advertisement = self->platform;
	if (!advertisement->service) {
		DNSServiceErrorType error;
		DNSServiceRef serviceRef;
		FskAssociativeArrayIterator iterator = FskAssociativeArrayIteratorNew(self->txt);

		FskInstrumentedItemPrintfDebug(advertisement, "DNSServiceRegister %s %s %d\n", self->serviceName, self->serviceType, self->port);
		while (iterator) {
			UInt32 nameLength = FskStrLen(iterator->name);
			UInt32 valueLength = FskStrLen(iterator->value);
			length = nameLength + 1 + valueLength;
			if (length <= 255) {
				size += length + 1;
				err = txt ? FskMemPtrRealloc(size + 1, &txt) : FskMemPtrNew(size + 1, &txt);
				if (err)
					size -= length + 1;
				else {
					txt[offset++] = (char)length;
					FskStrCopy(txt + offset, iterator->name); offset += nameLength;
					txt[offset++] = '=';
					FskStrCopy(txt + offset, iterator->value); offset += valueLength;
					txt[offset] = 0;
				}
			}
			iterator = FskAssociativeArrayIteratorNext(iterator);
		}
		FskAssociativeArrayIteratorDispose(iterator);

		error = DNSServiceRegister(&serviceRef, 0, 0, self->serviceName, self->serviceType, "", NULL, // use default host name
					htons(self->port), txt ? FskStrLen(txt) : 0, txt, KprZeroconfPlatformAdvertisementProcess, self);
		if (error != kDNSServiceErr_NoError) {
			FskInstrumentedItemPrintfDebug(advertisement, "DNSServiceRegister error %d\n", error);
			bailIfError(kFskErrNetworkErr);
		}
		bailIfError(KprZeroconfPlatformServiceNew(&advertisement->service, NULL, serviceRef, NULL, 0));
	}
bail:
	FskMemPtrDispose(txt);
	return err;
}
Exemple #3
0
FskErr KprHTTPClientReadCache(KprMessage message, KprHTTPCacheValue cached)
{
	FskErr err = kFskErrNone;
	FskAssociativeArrayIterator iterate = NULL;
	
	bailIfError(KprHTTPCacheValueReadData(cached));
	iterate = FskAssociativeArrayIteratorNew(cached->headers);
	while (iterate) {
		bailIfError(KprMessageSetResponseHeader(message, iterate->name, iterate->value));
		iterate = FskAssociativeArrayIteratorNext(iterate);
	}
	message->response.body = cached->body;
	cached->body = NULL;
	message->response.size = cached->size;
	message->status = cached->status;
bail:
	FskAssociativeArrayIteratorDispose(iterate);
	if (err)
		KprMemPtrDisposeAt(&cached->body);
	return err;
}
Exemple #4
0
// ------------------------------------------------------------------------
void FskHeaderIteratorDispose(FskHeaderIterator iter) {
	FskAssociativeArrayIteratorDispose(iter);
}
Exemple #5
0
Boolean KprHTTPClientPutTargetCache(KprHTTPTarget target)
{
	FskErr err = kFskErrNone;
	char* control = NULL;
	KprHTTPClient self = gKprHTTPClient;
	KprMessage message = target->message;
	
	UInt32 date = 0;
	UInt32 maxAge = 0;
	UInt32 lifetime = 0;
	char* start;
	char* next;
	char* end;
	Boolean foundAge = false;
	Boolean revalidate = false;
	KprHTTPCacheValue cached = NULL;
	
	bailIfError(message->error
				|| !FskStrCompareCaseInsensitiveWithLength(message->url, "https://", 8)
				|| ((message->status != 200) && (message->status != 203))
				|| (message->method && FskStrCompare(message->method, "GET")) // only caching GET method
				|| (message->user != NULL) // do not cache request with credentials
				|| (message->password != NULL) // do not cache request with credentials
				|| (message->response.size == 0) // only caching something
				|| (message->response.size > 384000)); // not caching big files

	if ((control = KprMessageGetResponseHeader(message, kFskStrCacheControl))) {
		start = control;
		end = control + FskStrLen(control);
		// split
		while (start < end) {
			if (*start == ',') *start = 0;
			start++;
		}
		start = control;
		while (start <= end) {
			next = start + FskStrLen(start) + 1;
			start = FskStrStripHeadSpace(start);
			if (!FskStrCompareCaseInsensitiveWithLength(start, "max-age", 7)) {
				bailIfError(!(start = FskStrStripHeadSpace(start + 7)));
				bailIfError(*start != '=');
				bailIfError(!(start = FskStrStripHeadSpace(start + 1)));
				maxAge = FskStrToNum(start);
				foundAge = true;
			}
			else if (!FskStrCompareCaseInsensitiveWithLength(start, "no-cache", 8)) {
				revalidate = true;
			}
			else if (!FskStrCompareCaseInsensitiveWithLength(start, "no-store", 8)) {
				BAIL(kFskErrInvalidParameter);
			}
			else if (!FskStrCompareCaseInsensitiveWithLength(start, "must-revalidate", 15)) {
				revalidate = true;
			}
			start = next;
		}
	}
	KprDateFromHTTP(KprMessageGetResponseHeader(message, kprHTTPHeaderDate), &date);
	if (foundAge)
		lifetime = maxAge;
	else {
		UInt32 expire = 0;
		KprDateFromHTTP(KprMessageGetResponseHeader(message, kFskStrExpires), &expire);
		if (date && expire)
			lifetime = (expire > date) ? expire - date : 0;
		else if (!KprMessageGetResponseHeader(message, kprHTTPHeaderETag)
			&& !KprMessageGetResponseHeader(message, kprHTTPHeaderLastModified))
			BAIL(kFskErrInvalidParameter); // not cached
	}
	if (KprMessageGetResponseHeader(message, kprHTTPHeaderVary))
		revalidate = true;
	if (!revalidate)
		lifetime += 180; // guess 3 minutes
//	put in cache
//	fprintf(stderr, "%p: CACHE %s for %d (%d)\n", message, message->url, lifetime, revalidate);
	bailIfError(KprHTTPCacheValueNew(&cached));
	KprDateFromHTTP(KprMessageGetResponseHeader(message, kprHTTPHeaderAge), &cached->age);
	cached->date = date;
	cached->lifetime = lifetime;
	cached->requestDate = target->requestDate;
	cached->responseDate = target->responseDate;
	cached->status = message->status;
	
	cached->headers = FskAssociativeArrayNew();
	{
		FskAssociativeArrayIterator iterate = FskAssociativeArrayIteratorNew(message->response.headers);
		while (iterate) {
			FskAssociativeArrayElementSet(cached->headers, iterate->name, iterate->value, 0, kFskStringType);
			iterate = FskAssociativeArrayIteratorNext(iterate);
		}
		FskAssociativeArrayIteratorDispose(iterate);
	}
	KprHTTPCacheValueCleanupHeaders(cached);
	
	cached->size = message->response.size;
	cached->body = message->response.body;
	target->cached = cached;
	bailIfError(KprHTTPCachePut(self->cache, message->url, cached));
	
bail:
	if (control) {
		// unsplit
		start = control;
		while (start < end) {
			if (*start == 0) *start = ',';
			start++;
		}
	}
	if (err == kFskErrNone) return true;
	target->cached = NULL;
	if (cached)
		KprMemPtrDispose(cached);
	return false;
}