示例#1
0
FskErr KprMessageSetResponseHeader(KprMessage self, char* name, char* value)
{
	FskErr err = kFskErrNone;
	if (!self->response.headers)
		self->response.headers = FskAssociativeArrayNew();
	if (self->response.headers)
		FskAssociativeArrayElementSet(self->response.headers, (const char*)name, (const char*)value, 0, kFskStringType);
	return err;
}
示例#2
0
void FskEnvironmentSet(const char *name, const char *value)
{
	FskThread thread = FskThreadGetCurrent();
	FskAssociativeArray vars = gEnvironment;

	if (!(kFskThreadFlagsIsMain & thread->flags)) {
		if (NULL == thread->environmentVariables)
			thread->environmentVariables = FskAssociativeArrayNew();
		vars = thread->environmentVariables;
	}
	FskAssociativeArrayElementSetString(vars, name, (char *)value);
}
示例#3
0
// ------------------------------------------------------------------------
FskErr FskHeaderStructNew(FskHeaders **headers) {
	FskErr		err;
	FskHeaders	*ret;

	*headers = NULL;
	err = FskMemPtrNewClear(sizeof(FskHeaders), &ret);
	if (err != kFskErrNone)
		return err;
	
	ret->theHeaders = FskAssociativeArrayNew();

	*headers = ret;
	return kFskErrNone;
}
示例#4
0
void KprZeroconfServiceShare(KprService self, char* authority, Boolean shareIt, Boolean useEnvironment)
{
	FskErr err = kFskErrNone;
	char* type = NULL;
	KprZeroconfAdvertisement advertisement = NULL;
	KprHTTPServer server = KprHTTPServerGet(authority);
	bailIfError(KprZeroconfServiceNewType(authority, &type));
	advertisement = KprZeroconfAdvertisementFind(gKprZeroconfAdvertisements, type, 0);
	if (shareIt && useEnvironment)
		shareIt = KprEnvironmentGetUInt32("useZeroconf", 0);
	if (shareIt && server) {
		if (!advertisement) {
			UInt32 port = server ? KprHTTPServerGetPort(server) : 0;
			Boolean secure = server ? KprHTTPServerIsSecure(server) : false;
			char* uuid = FskUUIDGetForKey(authority);
			FskAssociativeArray txt = NULL;
			if (secure) {
				txt = FskAssociativeArrayNew();
				FskAssociativeArrayElementSetString(txt, "secure", "true");
			}
			bailIfError(KprZeroconfAdvertisementNew(&advertisement, type, uuid, port, txt));
			bailIfError(KprZeroconfPlatformAdvertisementStart(advertisement));
			FskListAppend(&gKprZeroconfAdvertisements, advertisement);
		}
	}
	else {
		if (advertisement) {
			FskListRemove(&gKprZeroconfAdvertisements, advertisement);
			bailIfError(KprZeroconfPlatformAdvertisementStop(advertisement));
			KprZeroconfAdvertisementDispose(advertisement);
		}
	}
bail:
	if (err)
		KprZeroconfAdvertisementDispose(advertisement);
	FskMemPtrDispose(type);
	FskMemPtrDispose(authority);
	return;
}
示例#5
0
void Zeroconf_Advertisement(xsMachine *the)
{
	KprZeroconfAdvertisement self = NULL;
	char* serviceType = xsToString(xsArg(0));
	char* servicName = xsToString(xsArg(1));
	int servicPort = xsToInteger(xsArg(2));
	xsIntegerValue c = xsToInteger(xsArgc);
	FskAssociativeArray txt = NULL;
	if ((c > 3) && xsIsInstanceOf(xsArg(3), xsObjectPrototype)) {
		xsVars(2);
		xsEnterSandbox();
		fxPush(xsArg(3));
		fxRunForIn(the);
		txt = FskAssociativeArrayNew();
		for (xsVar(0) = fxPop(); xsTypeOf(xsVar(0)) != xsNullType; xsVar(0) = fxPop()) {
			if (xsTypeOf(xsVar(0)) == xsStringType) {
				xsVar(1) = xsGetAt(xsArg(3), xsVar(0));
				if (!xsIsInstanceOf(xsVar(1), xsObjectPrototype)) {
					char* name = xsToString(xsVar(0));
					char* value = xsToString(xsVar(1));
					FskAssociativeArrayElementSetString(txt, name, value);
				}
			}
		}
		xsLeaveSandbox();
	}
	xsThrowIfFskErr(KprZeroconfAdvertisementNew(&self, serviceType, servicName, servicPort, txt));
	xsSetHostData(xsResult, self);
	self->registeredCallback = Zeroconf_advertisement_registeredCallback;
	self->unregisteredCallback = Zeroconf_advertisement_unregisteredCallback;
	self->the = the;
	self->slot = xsResult;
	self->code = the->code;
	self->behavior = xsUndefined;
	xsRemember(self->slot);
}
示例#6
0
FskErr KprQueryParse(char* query, FskAssociativeArray* it)
{
	FskErr err = kFskErrNone;
	FskAssociativeArray array;
	char *name, *decodedName;
	char *value, *decodedValue;
	char c;

	array = FskAssociativeArrayNew();
	bailIfNULL(array);
	name = query;
	value = NULL;
	while ((c = *query++)) {
		if (c == '=') {
			value = query;
		}
		else if (c == '&') {
			if (value)
				*(value - 1) = 0;
			*(query - 1) = 0;
			if (kFskErrNone == KprQueryDecode(name, &decodedName)) {
				if (value) {
					if (kFskErrNone == KprQueryDecode(value, &decodedValue)) {
						FskAssociativeArrayElementSet(array, (const char*)decodedName, (const char*)decodedValue, 0, kFskStringType);
						if (decodedValue != value)
							FskMemPtrDispose(decodedValue);
					}
				}
				else
					FskAssociativeArrayElementSet(array, (const char*)decodedName, "", 0, kFskStringType);
				if (decodedName != name)
					FskMemPtrDispose(decodedName);
			}
			*(query - 1) = '&';
			if (value)
				*(value - 1) = '=';
			name = query;
			value = NULL;
		}
	}
	if (value)
		*(value - 1) = 0;
	if (kFskErrNone == KprQueryDecode(name, &decodedName)) {
		if (value) {
			if (kFskErrNone == KprQueryDecode(value, &decodedValue)) {
				FskAssociativeArrayElementSet(array, (const char*)decodedName, (const char*)decodedValue, 0, kFskStringType);
				if (decodedValue != value)
					FskMemPtrDispose(decodedValue);
			}
		}
		else
			FskAssociativeArrayElementSet(array, (const char*)decodedName, "", 0, kFskStringType);
		if (decodedName != name)
			FskMemPtrDispose(decodedName);
	}
	if (value)
		*(value - 1) = '=';
	*it = array;
bail:
	return err;
}
示例#7
0
char *FskUUIDGetForKey(const char *key)
{
	char *uuidStr;
	FskUUIDRecord uuid;
	char *uuidCachePath = NULL, *prefFolder;
	FskFile fref;

	if (kFskErrNone == FskDirectoryGetSpecialPath(kFskDirectorySpecialTypeApplicationPreference, true, NULL, &prefFolder)) {
		uuidCachePath = FskStrDoCat(prefFolder, "fskuuidcache.txt");
		FskMemPtrDispose(prefFolder);
	}

	// load the cache
	if (NULL == gUUIDCache) {
		char *uuidCache;
		FskInt64 cacheSize;

		gUUIDCache = FskAssociativeArrayNew();

		if ((NULL != uuidCachePath) && (kFskErrNone == FskFileLoad(uuidCachePath, (unsigned char **)(void *)&uuidCache, &cacheSize))) {
			char *p = uuidCache;
			while (true) {
				char *uuid = p;
				char *mykey = FskStrChr(p, '\t');
				char *cr;

				if (NULL == mykey)
					break;
				cr = FskStrChr(mykey, '\n');
				if (NULL == cr)
					break;
				*mykey++ = 0;
				*cr = 0;

				FskAssociativeArrayElementSetString(gUUIDCache, mykey, uuid);

				p = cr + 1;
			}
			FskMemPtrDispose(uuidCache);
		}
	}

	// check the cache
	uuidStr = FskAssociativeArrayElementGetString(gUUIDCache, key);
	if (uuidStr) {
		FskMemPtrDispose(uuidCachePath);
		return uuidStr;
	}

	// not in cache
	FskUUIDCreate(&uuid);
	uuidStr = FskUUIDtoString_844412(&uuid);

	FskAssociativeArrayElementSetString(gUUIDCache, key, uuidStr);

	FskMemPtrDispose(uuidStr);

	// flush cache
	FskFileDelete(uuidCachePath);
	FskFileCreate(uuidCachePath);
	if (kFskErrNone == FskFileOpen(uuidCachePath, kFskFilePermissionReadWrite, &fref)) {
		FskAssociativeArrayIterator iterate = FskAssociativeArrayIteratorNew(gUUIDCache);
		char tab = '\t', cr = '\n';

		while (iterate) {
			FskFileWrite(fref, FskStrLen(iterate->value), iterate->value, NULL);
			FskFileWrite(fref, 1, &tab, NULL);
			FskFileWrite(fref, FskStrLen(iterate->name), iterate->name, NULL);
			FskFileWrite(fref, 1, &cr, NULL);

			iterate = FskAssociativeArrayIteratorNext(iterate);
		}
		FskFileClose(fref);
	}

	FskMemPtrDispose(uuidCachePath);

	return FskAssociativeArrayElementGetString(gUUIDCache, key);	// caller doesn't have to dispose
}
示例#8
0
// ------------------------------------------------------------------------
static int sParseStartLine(char *startLine, UInt16 headerType, FskHeaders *headers)
{
	FskErr	err;
	int		l;
	const char *p;
	char *c = startLine;
	char *firstPart;

	// Get method or protocol
	p = c;
	c = FskStrChr(c, ' ');
	if (!c) return -1;
	
	l = (c++) - p;
	err = FskMemPtrNew(l+1, &firstPart);
	if (err != kFskErrNone)
		return -1;
	FskStrNCopy(firstPart, p, l);
	firstPart[l] = '\0';
	if (kFskHeaderTypeResponse == headerType)
		headers->protocol = firstPart;
	else 
		headers->method = firstPart;

	c = FskStrStripHeadSpace(c);	// skip over space

	headers->headerType = headerType;
	if (kFskHeaderTypeResponse == headerType) {
		// Get response code and message (if message not in HTTP_Responses)
		headers->responseCode = FskStrToNum(c);
		if (headers->flags & kFskHeadersNonStandardResponseReasonPhrase) {
			c = FskStrChr(c, ' ');
			if (c) {
				char *r, *s;
				s = FskStrStripHeadSpace(c);
				r = FskFindResponse(headers->responseCode);
				if (!r || (0 != FskStrCompareCaseInsensitiveWithLength(s, r, FskStrLen(r)))) {
					headers->responseReasonPhrase = FskStrDoCopy(s);
					if (NULL != headers->responseReasonPhrase)
						FskStrStripTailSpace(headers->responseReasonPhrase);
				}
			}
		}
	}
	else {
		char 	*s, *t = NULL;
		char	*uri = NULL;

		// Get URI
		if ((*c == '/') && !(headers->flags & kFskHeadersDoNotStripURILeadingSlash))
			c++;
		s = FskStrChr(c, ' ');
		if (!s) {
			headers->responseCode = 400;
			return -1;
		}
		headers->protocol = FskStrDoCopy(s + 1);
		if (NULL != headers->protocol)
			FskStrStripTailSpace(headers->protocol);

		BAIL_IF_ERR(FskMemPtrNew((s-c)+1, &uri));
		BAIL_IF_ERR(FskMemPtrNew((s-c)+1, &t));
		FskMemCopy(uri, c, s-c);
		uri[s-c] = '\0';
		s = FskStrChr(uri, '?');
        if (s) *s = 0;
        FskStrDecodeEscapedChars(uri, t);
        if (s) {
            *s = '?';
            FskStrCat(t, s);
        }
		headers->URI = FskStrDoCopy(t);

		// Break URI into filename and parameters
		s = FskStrChr(t, '?');
		if (!s) {
			headers->filename = FskStrDoCopy(t);
		}
		else {		// URI has parameters
			*s++ = '\0';	// cap off the filename
			headers->filename = FskStrDoCopy(t);
			
			headers->parameters = FskAssociativeArrayNew();
			while (s) {
				char *name = s;		
				char *value = FskStrChr(name, '=');
				if (!value)
					break;
				s = FskStrChr(value, '&');
				*value++ = '\0';		// cap off the name
				if (s)
					*s++ = '\0';		// cap off the value
				FskAssociativeArrayElementSetString(headers->parameters, name, value);
			}
		}		

bail:
		FskMemPtrDispose(uri);
		FskMemPtrDispose(t);

	}

	return headers->headerType;
}
示例#9
0
FskErr FskEnvironmentInitialize(void)
{
	char *appPath;

	gEnvironment = FskAssociativeArrayNew();

	appPath = FskGetApplicationPath();
	FskEnvironmentSet("applicationPath", appPath);
	FskMemPtrDispose(appPath);

#if TARGET_OS_KPL
	KplEnvironmentInitialize(gEnvironment);
#elif TARGET_OS_ANDROID
	FskEnvironmentSet("application", "PLAY");
#elif TARGET_OS_WIN32 || TARGET_OS_MAC || TARGET_OS_LINUX
	FskEnvironmentSet("application", FSK_APPLICATION);
#else
	FskEnvironmentSet("application", "PLAY");
#endif

#if TARGET_OS_WIN32
	{
	char name[256], *nameTemp = NULL;
	UInt16 nameW[256];
	char num[32];
	DWORD nameSize = sizeof(nameW) / sizeof(UInt16);
	EXTENDED_NAME_FORMAT exNameFormat = NameSamCompatible;

	if (GetUserNameExW(exNameFormat, (LPWSTR)nameW, &nameSize)) {
		FskTextUnicode16LEToUTF8(nameW, nameSize * 2, &nameTemp, NULL);
		FskStrCopy(name, nameTemp);
		FskEnvironmentSet("loginName", name);
		FskMemPtrDispose(nameTemp);
	}

	FskEnvironmentSet("OS", "Windows");
	FskStrNumToStr(gWindowsVersionInfo.dwMajorVersion, name, sizeof(name));
	FskStrCat(name, ".");
	FskStrNumToStr(gWindowsVersionInfo.dwMinorVersion, num, sizeof(num));
	FskStrCat(name, num);
	FskEnvironmentSet("OSVersion", name);
	}
#elif TARGET_OS_MAC
	{
		struct utsname un;
		char name[256], *model;
		SInt32 gen;
	#if TARGET_OS_IPHONE
		FskEnvironmentSet("OS", "iPhone");
	#else
		FskEnvironmentSet("OS", "Mac");
	#endif
		FskCocoaSystemGetVersion(name);
		FskEnvironmentSet("OSVersion", name);
		if (uname(&un) == 0) {
			model = un.machine;
			if (FskStrCompareWithLength(model, "iPhone", 6) == 0)
				gen = FskStrToNum(model + 6);
			else if (FskStrCompareWithLength(model, "iPad", 4) == 0) {
				gen = FskStrToNum(model + 4);
				if (gen == 3) {
					SInt32 minor = FskStrToNum(model + 6);
					if (minor == 4)	/* 4th gen */
						gen = 5;
					else
						gen = 4;	/* Only the 3rd gen iPad doesn't follow the numbering system */
				}
				else
					gen += 2;
			}
			else if (FskStrCompareWithLength(model, "iPod", 4) == 0) {
				gen = FskStrToNum(model + 4);
				if (gen > 1)
					--gen;
			}
			else
				gen = 99;
		}
		else {
			model = "unknown";
			gen = 99;
		}
		FskEnvironmentSet("Model", model);
		FskStrNumToStr(gen, name, sizeof(name));
		FskEnvironmentSet("Generation", name);
	}
		
#elif TARGET_OS_LINUX
	{
	struct utsname name;
	uname(&name);

	if (getlogin())
		FskEnvironmentSet("loginName", getlogin());
	else
		FskEnvironmentSet("loginName", "User");
	FskEnvironmentSet("OS", name.sysname);
	FskEnvironmentSet("OSVersion", name.release);		//@@
	}
#endif

	return kFskErrNone;
}
示例#10
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;
}