コード例 #1
0
ファイル: gpio.c プロジェクト: kouis3940/kinomajs
void xs_gpio_repeat(xsMachine* the)
{
    FskGPIO gpio = xsGetHostData(xsThis);

    if (gpio) {
        if (in != gpio->direction)
            xsThrowDiagnosticIfFskErr(kFskErrUnimplemented, "Digital pin %d cannot repeat on output pin", (int)gpio->pinNum);

        if (gpio->poller)
            FskListRemove(&gGPIOPollers, gpio);
        
        gpio->poller = (xsTest(xsArg(0))) ? xsGetHostData(xsArg(0)) : NULL;

        if (gpio->poller) {
            FskListAppend(&gGPIOPollers, gpio);
            gpio->pollerValue = -1;     // won't match
            if (NULL == gGPIOPoller) {
                FskTimeCallbackNew(&gGPIOPoller);
                FskTimeCallbackScheduleNextRun(gGPIOPoller, gpioPoller, NULL);
            }
        }
        else if ((NULL == gGPIOPollers) && (NULL != gGPIOPoller)) {
            FskTimeCallbackDispose(gGPIOPoller);
            gGPIOPoller = NULL;
        }
    }
}
コード例 #2
0
void DNSSD_API KprZeroconfPlatformGetAddrInfoCallBack(DNSServiceRef serviceRef, DNSServiceFlags flags, uint32_t interfaceIndex, DNSServiceErrorType errorCode, const char *hostname, const struct sockaddr *address, uint32_t ttl, void *context)
{
	KprZeroconfBrowser self = context;
	KprZeroconfPlatformBrowser browser = self->platform;
	KprZeroconfPlatformService service = KprZeroconfPlatformServiceFind(browser->services, serviceRef);
	char* serviceType = self->serviceType;
	if (!self->serviceType) {
		serviceType = service->owner->name;
	}
	if (!service || (errorCode != kDNSServiceErr_NoError)) {
		FskInstrumentedItemPrintfDebug(browser, "KprZeroconfPlatformResolveCallBack returned %d\n", errorCode);
	}
	else {
		KprZeroconfServiceInfo serviceInfo = NULL;
#if TARGET_OS_WIN32
		char ip[256];
		if (address && address->sa_family == AF_INET) {
			const unsigned char *b = (const unsigned char *) &((struct sockaddr_in *)address)->sin_addr;
			snprintf(ip, sizeof(ip), "%d.%d.%d.%d", b[0], b[1], b[2], b[3]);
		}
#else
		char ip[INET_ADDRSTRLEN];
		inet_ntop(AF_INET, &(((struct sockaddr_in *)address)->sin_addr), ip, INET_ADDRSTRLEN);
#endif
		FskInstrumentedItemPrintfDebug(browser, "GETADDRINFO: %s %s is at %s -> %s:%d", self->serviceType, service->name, hostname, ip, service->port);
		KprZeroconfServiceInfoNew(&serviceInfo, serviceType, service->name, hostname, ip, service->port, service->txt);
		KprZeroconfBrowserServiceUp(self, serviceInfo);
		FskListRemove(&browser->services, service);
		KprZeroconfPlatformServiceDispose(service);
	}
}
コード例 #3
0
ファイル: kprMQTTCommon.c プロジェクト: dadongdong/kinomajs
static void KprMQTTQueueResendMessage(KprMQTTQueue self, KprMQTTMessage message)
{
	FskListRemove(&self->outbox, message);

	self->callback(self, &message, self->refcon);

	KprMQTTMessageDispose(message);
}
コード例 #4
0
ファイル: kprSSDPClient.c プロジェクト: Kazu-zamasu/kinomajs
FskErr KprSSDPClientStop(KprSSDPClient self)
{
	FskErr err = kFskErrNone;
	FskListRemove(&gKprSSDPClients, self);
	FskThreadPostCallback(KprHTTPGetThread(), (FskThreadCallback)KprSSDPForget, self, NULL, NULL, NULL);
//bail:
	return err;
}
コード例 #5
0
ファイル: kprMQTTCommon.c プロジェクト: dadongdong/kinomajs
KprMQTTMessage KprMQTTQueueInboxGet(KprMQTTQueue self, UInt16 messageId)
{
	KprMQTTMessage message = KprMQTTQueueInboxFind(self, messageId);
	if (!message) return NULL;

	FskListRemove(&self->inbox, message);

	return message;
}
コード例 #6
0
FskErr KprZeroconfBrowserStop(KprZeroconfBrowser self)
{
	FskErr err = kFskErrNone;
	if (FskListRemove(&gZeroconfBrowsers, self)) {
		bailIfError(KprZeroconfPlatformBrowserStop(self));
	}
bail:
	return err;
}
コード例 #7
0
ファイル: kprMQTTCommon.c プロジェクト: dadongdong/kinomajs
KprMQTTMessage KprMQTTQueueOutboxGet(KprMQTTQueue self, UInt16 messageId)
{
	KprMQTTMessage message = KprMQTTQueueOutboxFind(self, messageId);
	if (!message) return NULL;

	FskListRemove(&self->outbox, message);

	KprMQTTQueueReschedule(self);

	return message;
}
コード例 #8
0
void KplTimeCallbackCancel(KplTimeCallback callback)
{
	Boolean reschedule;
	KplThread thread;
	
	if (NULL == callback)
		return;

	thread = callback->owner;
 	if ((NULL == thread) || ((NULL == thread->timerCallbacks) && (NULL == thread->suspendedTimerCallbacks)))
		return;

	reschedule = (callback == thread->timerCallbacks);

	if (!FskListRemove((FskList *)&thread->timerCallbacks, callback))
		FskListRemove((FskList *)&thread->suspendedTimerCallbacks, callback);

	if (reschedule)
		rescheduleTimer(thread);
}
コード例 #9
0
ファイル: kprDebug.c プロジェクト: dadongdong/kinomajs
void KprDebugClose(KprDebug self)
{
	KprDebugMachine machine = NULL;
	FskListRemove(&gKprDebugList, self);
	while ((machine = self->machine))
		KprDebugMachineDispose(machine);
	if (self->server) {
		KprSocketServerDispose(self->server);
		self->server = NULL;
	}
}
コード例 #10
0
FskErr FskFSVolumeNotifierDispose(FskFSVolumeNotifier volNtf) {
	FskAndroidFilesPrintfDebug("VolumeNotifierDispose\n");
	FskMutexAcquire(gVolNotifiersMutex);

	FskListRemove((FskList *)&gVolNotifiers, &volNtf->next);

	FskMemPtrDispose(volNtf);

	FskMutexRelease(gVolNotifiersMutex);

	return kFskErrNone;
}
コード例 #11
0
ファイル: kprHTTPClient.c プロジェクト: Kazu-zamasu/kinomajs
void KprHTTPClientStop(KprService service)
{
	KprHTTPClient self = gKprHTTPClient;
	KprHTTPConnection connection;	
	KprHTTPTarget target;	

	/* CONNECTIONS */
	while ((connection = self->connections)) {
		FskListRemove(&self->connections, connection);
		KprHTTPConnectionDispose(connection);
	}
	while ((target = self->targets)) {
		FskListRemove(&self->targets, target);
		// @@ cancel message?
	}
	
	/* KEYCHAIN */
	if (self->keychain) {
		KprHTTPKeychainWrite(self->keychain);
		KprHTTPKeychainDispose(self->keychain);
		self->keychain = NULL;
	}

	/* COOKIES */
	if (self->cookies) {
		KprHTTPCookiesCleanup(self->cookies, true);
		KprHTTPCookiesWrite(self->cookies);
		KprHTTPCookiesDispose(self->cookies);
		self->cookies = NULL;
	}

	/* HTTP CACHE */
	if (self->cache) {
		KprHTTPCacheWrite(self->cache);
		KprHTTPCacheDispose(self->cache);
		self->cache = NULL;
	}
	FskInstrumentedItemDispose(self);
	FskMemPtrDisposeAt(&gKprHTTPClient);
}
コード例 #12
0
ファイル: gpio.c プロジェクト: kouis3940/kinomajs
void xs_gpio(void *gpio)
{
    if (gpio) {
        FskListRemove(&gGPIOPollers, gpio);
        if ((NULL == gGPIOPollers) && (NULL != gGPIOPoller)) {
            FskTimeCallbackDispose(gGPIOPoller);
            gGPIOPoller = NULL;
        }

        FskGPIOPlatformDispose(gpio);
        FskMemPtrDispose(gpio);
    }
}
コード例 #13
0
static void KprWebSocketServerRequestDispose(KprWebSocketServerRequest request) {
	if (request) {
		FskListRemove((FskList*)&request->server->activeRequests, request);
		FskThreadRemoveDataHandler(&request->dataHandler);

		FskNetSocketClose(request->skt);
		FskHeaderStructDispose(request->requestHeaders);
		FskHeaderStructDispose(request->responseHeaders);
		FskStrParsedUrlDispose(request->parts);
		FskMemPtrDispose(request->out.buffer);
		FskMemPtrDispose(request);
	}
}
コード例 #14
0
ファイル: kprSocket.c プロジェクト: basuke/kinomajs
static FskErr KprSocketListenerDispose(KprSocketListener self)
{
	if (self) {
		FskThreadRemoveDataHandler(&self->dataHandler);
		FskNetSocketClose(self->socket);

		if (self->owner) {
			FskListRemove(&self->owner->listeners, self);
		}

		KprMemPtrDispose(self);
	}
	return kFskErrNone;
}
コード例 #15
0
ファイル: FskMuxer.c プロジェクト: Kazu-zamasu/kinomajs
FskErr FskMuxerTrackDispose(FskMuxerTrack track)
{
	if (NULL == track)
		goto bail;

	if (track->dispatch && track->dispatch->doDispose)
		(track->dispatch->doDispose)(track, track->state);

	FskListRemove((FskList*)(void*)&track->muxer->tracks, track);

	FskMemPtrDispose(track);

bail:
	return kFskErrNone;
}
コード例 #16
0
ファイル: FskHTTPServer.c プロジェクト: archite/kinomajs
void FskHTTPServerRequestDispose(FskHTTPServerRequest request) {
	FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "FskHTTPServerRequestDispose %p  - useCount: %d\n", request, request ? request->useCount : 0);
	if (request) {
		FskTimeCallbackDispose(request->timer);
		FskListRemove((FskList*)&request->http->activeRequests, request);
		FskThreadRemoveDataHandler(&request->dataHandler);
		FskTimeCallbackDispose(request->cycleCallback);
		request->cycleCallback = NULL;
		FskTimeCallbackDispose(request->keepAliveKillCallback);
		request->keepAliveKillCallback = NULL;
		request->keepAliveTimeout = 0;
		request->http->stats.connectionsCompleted++;
		sFskHTTPServerRequestDownUse(request);
	}
}
コード例 #17
0
ファイル: FskGtkWindow.c プロジェクト: VzqzAc/kinomajs
void on_drag_data_received(GtkWidget* widget, GdkDragContext* context, gint x, gint y, GtkSelectionData *data, guint info, guint time, gpointer user_data)
{
	FskGtkWindow gtkWin = user_data;
	gboolean dnd_success = FALSE;
	FskDragDropFile dropFileList = NULL;
	FskDragDropFile droppedFile = NULL;
	char* path = NULL;
	if (gdk_drag_context_get_suggested_action(context) == GDK_ACTION_COPY) {
		char* string = (char*)gtk_selection_data_get_data(data);
		char* end;
		FskFileInfo itemInfo;
		for (end = FskStrStr(string, "\r\n"); end; end = FskStrStr(string, "\r\n")) {
			BAIL_IF_ERR(FskMemPtrNewClear(sizeof(FskDragDropFileRecord), (FskMemPtr*)&droppedFile));
			FskListAppend((FskList *)&dropFileList, droppedFile);
			*end = 0;
			BAIL_IF_ERR(KprURLToPath(string, &path));
			BAIL_IF_ERR(FskFileGetFileInfo(path, &itemInfo));
			if (itemInfo.filetype == kFskDirectoryItemIsDirectory) {
				int length = FskStrLen(path);
				BAIL_IF_ERR(FskMemPtrNew(length + 2, &droppedFile->fullPathName));
				FskMemCopy(droppedFile->fullPathName, path, length);
				droppedFile->fullPathName[length] = '/';
				droppedFile->fullPathName[length + 1] = 0;
				FskMemPtrDispose(path);
			}
			else {
				droppedFile->fullPathName = path;
			}
			path = NULL;
			string = end + 2;
			*end = '\r';
		}
		(*gDropTargetProc)(kFskDragDropTargetEnterWindow, x, y, dropFileList, gtkWin->owner);
		(*gDropTargetProc)(kFskDragDropTargetDropInWindow, x, y, dropFileList, gtkWin->owner);
		dnd_success = TRUE;
	}
bail:
	gtk_drag_finish(context, dnd_success, TRUE, time);
	FskMemPtrDispose(path);
	while (NULL != dropFileList) {
		droppedFile = dropFileList;
		FskListRemove((FskList *)&dropFileList, droppedFile);
		FskMemPtrDispose(droppedFile->fullPathName);
		FskMemPtrDispose(droppedFile);
	}
}
コード例 #18
0
ファイル: kprMessage.c プロジェクト: basuke/kinomajs
void KprXKPRServiceCancel(KprService self UNUSED, KprMessage message)
{
	message->usage--; // event queue
	if (gShell && FskListRemove(&gShell->messages, message)) {
		message->usage--; // message queue
		if (message->response.callback)
			(*message->response.callback)(message, message->response.target);
		if (message->response.dispose)
			(*message->response.dispose)(message->response.target);
		message->response.callback = NULL;
		message->response.dispose = NULL;
		message->response.target = NULL;
		message->usage--; // response
	}
	if (!message->usage)
		KprMessageDispose(message);
}
コード例 #19
0
ファイル: kprMQTTCommon.c プロジェクト: dadongdong/kinomajs
static void KprMQTTQueueReschedule(KprMQTTQueue self)
{
	KprMQTTMessage message;

	if (self->pause) return;

	message = KprMQTTQueueNextMessageToResend(self);
	if (message) {
		if (self->outbox != message) {
			FskListRemove(&self->outbox, message);
			FskListPrepend(&self->outbox, message);
		}

		FskTimeCallbackSet(self->resendCallback, &message->nextTime, KprMQTTQueueTimeToResendMessage, self);
	} else {
		FskTimeCallbackRemove(self->resendCallback);
	}
}
コード例 #20
0
ファイル: FskHTTPServer.c プロジェクト: archite/kinomajs
FskErr FskHTTPServerListenerDispose(FskHTTPServerListener listener) {
	FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerListenerDispose - listener: %p\n", listener);
	if (listener) {
		if (listener->http && listener->http->listeners)
			FskListRemove((FskList*)&listener->http->listeners, listener);
		if (listener->handshaking) {
			FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpServerListenerDispose - listener: %p - wait for handshaking\n", listener);
			listener->http = NULL;
		}
		else {
			FskThreadRemoveDataHandler(&listener->dataHandler);
			FskNetSocketClose(listener->skt);
			FskMemPtrDispose(listener->ifcName);
			FskMemPtrDispose(listener);
		}
	}
	return kFskErrNone;
}
コード例 #21
0
ファイル: kprZeroconf.c プロジェクト: kouis3940/kinomajs
void KprZeroconfServiceForget(KprService self, char* authority, char* id)
{
	FskErr err = kFskErrNone;
	char* type = NULL;
	KprZeroconfBrowser browser = NULL;
	bailIfError(KprZeroconfServiceNewType(id, &type));
	browser = KprZeroconfBrowserFind(gKprZeroconfBrowsers, type);
	if (browser) {
		FskListRemove(&gKprZeroconfBrowsers, browser);
		bailIfError(KprZeroconfBrowserStop(browser));
		KprZeroconfBrowserDispose(browser);
	}
bail:
	FskMemPtrDispose(type);
	FskMemPtrDispose(authority);
	FskMemPtrDispose(id);
	return;
}
コード例 #22
0
ファイル: kprSocket.c プロジェクト: basuke/kinomajs
FskErr KprSocketDispose(KprSocket self)
{
	FskErr err = kFskErrNone;

	if (self) {
		memset(&self->callbacks, 0, sizeof(KprSocketCallbaks));

		if (self->preventDispose > 0) {
			self->disposeRequested = true;
		} else {
			FskListRemove(&gSockets, self);

			KprSocketCleanup(self);
			FskMemPtrDispose(self);
		}
	}
	return err;
}
コード例 #23
0
ファイル: kprMessage.c プロジェクト: basuke/kinomajs
void KprMessageComplete(KprMessage self)
{
	char* url;
	FskThread thread = KprShellGetThread(gShell);
	if (!thread) return; // @@ happens on exit
	if (thread != FskThreadGetCurrent()) {
		FskThreadPostCallback(thread, (FskThreadCallback)KprMessageComplete, self, NULL, NULL, NULL);
        return;
    }
	FskInstrumentedItemSendMessageDebug(self, kprInstrumentedMessageComplete, self);
	if (FskListRemove(&gShell->messages, self)) {
		self->usage--; // message queue
		self->waiting = false;
		url = KprMessageGetResponseHeader(self, "location");
		if (url && (!FskStrCompareWithLength(self->url, "xkpr", 4)) && ((!self->sniffing) || (!FskStrCompareWithLength(url, "xkpr", 4)))) {
			FskMemPtrDispose(self->url);
			self->url = FskStrDoCopy(url);
			//bailIfNULL(self->url);
			KprURLSplit(self->url, &self->parts);
			FskAssociativeArrayDispose(self->response.headers);
			self->response.headers = NULL;
			FskMemPtrDispose(self->response.body);
			self->response.body = NULL;
			self->response.size = 0;
            if (self->request.target)
                self->usage--; // @@ request
			if (kFskErrNone == KprMessageInvoke(self, self->request.callback, self->request.dispose, self->request.target))
				return;
		}
		if (self->request.target) {
			if (self->request.callback)
				(*self->request.callback)(self, self->request.target);
			if (self->request.dispose)
				(*self->request.dispose)(self->request.target);
			self->request.callback = NULL;
			self->request.dispose = NULL;
			self->request.target = NULL;
			self->usage--; // request
		}
        if (!self->usage)
            KprMessageDispose(self);
	}
}
コード例 #24
0
ファイル: kprDebug.c プロジェクト: dadongdong/kinomajs
void KprDebugMachineDispose(KprDebugMachine self)
{
	if (self) {
		KprDebug debug = self->debug;
		xsBeginHostSandboxCode(debug->the, debug->code);
		xsVars(1);
		KprDebugMachineCallbackText(self, "onMachineUnregistered", mxNoCommand, NULL);
		xsEndHostSandboxCode();
		FskListRemove(&self->debug->machine, self);
		KprSocketWriterDispose(self->writer);
		self->writer = NULL;
		FskThreadRemoveDataHandler(&self->reader);
		FskNetSocketClose(self->socket);
		self->socket = NULL;
		FskMemPtrDisposeAt(&self->title);
		FskInstrumentedItemDispose(self);
		FskMemPtrDispose(self);
	}
}
コード例 #25
0
ファイル: kprCoAPClient.c プロジェクト: Kazu-zamasu/kinomajs
FskErr KprCoAPClientEndRequest(KprCoAPClient self, KprCoAPClientRequest request, const char *reason)
{
	FskErr err = kFskErrNone;

	if (self->callbacks.requestEndCallback) {
		bailIfError(self->callbacks.requestEndCallback(request->message, reason, self->refcon));
	}

	FskListRemove(&self->requests, request);

	if (request->message->token) {
		FskListAppend(&self->recycleTokens, KprRetain(request->message->token));
	}

	bailIfError(KprCoAPClientRequestDispose(request));

bail:
	return err;
}
コード例 #26
0
ファイル: kprMessage.c プロジェクト: basuke/kinomajs
void KprMessageDispose(KprMessage self)
{
	if (self) {
		FskListRemove(&gShell->messages, self);
		if (self->stream && self->stream->dispatch->dispose)
			(*self->stream->dispatch->dispose)(self->stream);
		if (self->response.dispose)
			(*self->response.dispose)(self->response.target);
		FskMemPtrDispose(self->response.body);
		FskAssociativeArrayDispose(self->response.headers);
		if (self->request.dispose)
			(*self->request.dispose)(self->request.target);
		FskMemPtrDispose(self->request.body);
		if (self->request.certs != NULL)
			FskNetUtilDisposeCertificate(self->request.certs);
		FskAssociativeArrayDispose(self->request.headers);
		FskMemPtrDispose(self->url);
		FskMemPtrDispose(self->method);
		FskInstrumentedItemDispose(self);
		FskMemPtrDispose(self);
	}
}
コード例 #27
0
ファイル: kprZeroconf.c プロジェクト: kouis3940/kinomajs
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;
}
コード例 #28
0
ファイル: kprHTTPClient.c プロジェクト: Kazu-zamasu/kinomajs
void KprHTTPClientIterate()
{
	KprHTTPClient self = gKprHTTPClient;
	KprHTTPConnection connection, candidate, available;
	KprHTTPTarget target, next, other;
	KprMessage message;
	
	for (connection = FskListGetNext(self->connections, NULL); connection; connection = FskListGetNext(self->connections, connection)) {
		target = connection->target;
		if (target) {
			message = connection->target->message;
			if (!KprMessageContinue(message)) {
				KprHTTPConnectionClose(connection);
				KprHTTPClientResumeTarget(target);
			}
		}
	}
	target = FskListGetNext(self->targets, NULL);
	while (target) {
		next = FskListGetNext(self->targets, target);
		message = target->message;
		if (!KprMessageContinue(message)) {
			FskListRemove(&self->targets, target);
			KprHTTPClientResumeTarget(target);
		}
		target = next;
	}
	target = FskListGetNext(self->targets, NULL);
	while (target) {
		next = FskListGetNext(self->targets, target);
		message = target->message;
		candidate = NULL;
		available = NULL;
		for (connection = FskListGetNext(self->connections, NULL); connection; connection = FskListGetNext(self->connections, connection)) {
			if (KprHTTPConnectionCandidate(connection, message)) {
				candidate = connection;
				break;
			}
			else if (KprHTTPConnectionAvailable(connection)) {
				if (!available || (FskTimeCompare(&connection->time, &available->time) > 0)) // make the older connection the candidate for re-use
					available = connection;
			}
		}
		if (candidate) {
			if (KprHTTPConnectionAvailable(candidate)) {
				FskInstrumentedItemSendMessageDebug(candidate, kprInstrumentedHTTPConnectionCandidate, candidate->client);
			}
			else {
				candidate = NULL;
			}
		}
		else if (available) {
			// before closing the available connection, try to find a message that can use it
			for (other = FskListGetNext(self->targets, target); other; other = FskListGetNext(self->targets, other)) {
				if (abs(other->message->priority) < abs(message->priority)) {
					other = NULL;
					break;		// do not let a lower priority request get in ahead of a higher priority one
				}
				if (KprHTTPConnectionCandidate(available, other->message)) {
					break;
				}
			}
			if (other) {
				FskInstrumentedItemSendMessageDebug(available, kprInstrumentedHTTPConnectionCandidate, available->client);
				next = target;
				target = other;
			}
			else
				KprHTTPConnectionClose(available);
			candidate = available;
		}
		else
			break;
		if (candidate) {
			FskListRemove(&self->targets, target);
			if (KprHTTPConnectionProcess(candidate, target)) {
				// put back the message in the queue
				KprHTTPClientAddTarget(target);
			}
		}
		target = next;
	}
}
コード例 #29
0
ファイル: kprHTTPClient.c プロジェクト: Kazu-zamasu/kinomajs
void KprHTTPClientRemoveTarget(KprHTTPTarget target)
{
 	KprHTTPClient self = gKprHTTPClient;
 	FskListRemove(&self->targets, target);
 	KprHTTPClientIterate();
}
コード例 #30
0
ファイル: FskHTTPServer.c プロジェクト: archite/kinomajs
static void httpServerEngineCycle(void *param) {
	FskErr err = kFskErrNone, retVal = kFskErrNeedMoreTime;
	FskHTTPServerRequest request = (FskHTTPServerRequest)param;
	int amt, ret, chunkSize = 0;
	UInt32 chunkSizeL;
	char *s, *p;
	Boolean readSomeMore, needsDispose = false;

	FskThreadRemoveDataHandler(&request->dataHandler);
	
	switch (request->state) {
		case kHTTPNewSession:
			FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestState, request);
			FskTimeGetNow(&request->stats.requestStarted);
			request->state = kHTTPReadRequestHeaders;
			
		case kHTTPReadRequestHeaders:
			FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestState, request);
			shoveBuffer(request->in);
			amt = request->in.bufferSize - request->in.max;
			if (amt) {
				err = FskNetSocketRecvTCP(request->skt, &request->in.buf[request->in.max], amt, &ret);
				switch (err) {
					case kFskErrNone:
#if SUPPORT_INSTRUMENTATION
						if (FskInstrumentedItemHasListeners(request)) {
							FskHTTPInstrMsgDataRecord msg;
							msg.buffer = &request->in.buf[request->in.max];
							msg.amt = ret;
							FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestRecvData, &msg);
						}
#endif
						request->http->stats.requestsStarted += 1;
						request->in.max += ret;
						request->state = kHTTPProcessRequestHeaders;
						request->stats.bytesReceived += ret;
						request->http->stats.bytesReceived += ret;
						break;
					case kFskErrNoData:
						retVal = kFskErrNoData;
						break;
					case kFskErrConnectionClosed:
						if (request->stats.bytesReceived) {
							request->state = kHTTPSocketError;
						}
						else {
							request->state = kHTTPDone;
						}
						break;
					default:
						FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgErrString, "kHTTPReadRequestHeaders: RecvTCP - error");
						request->state = kHTTPSocketError;
						break;
				}
			}
			else
				request->state = kHTTPProcessRequestHeaders;

			if (request->state != kHTTPProcessRequestHeaders)
				break;

		case kHTTPProcessRequestHeaders:
			FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestState, request);
			amt = request->in.max - request->in.pos;
			if (amt) {
				ret = FskHeadersParseChunk(&request->in.buf[request->in.pos], amt, kFskHeaderTypeRequest, request->requestHeaders);
				if (ret < 0) {
					err = kFskErrBadData;
					request->state = kHTTPSocketError;
					break;
				}
				request->in.pos += ret;
				
				if (request->requestHeaders->headersParsed) {
					httpProcessRequestHeaders(request);
				}
				else if (ret != amt) {
					// odd case - we didn't consume all the data, but
					// the header parsing isn't complete.
					request->state = kHTTPServerError;
				}
			}
			else 
				request->state = kHTTPReadRequestHeaders;

			if (request->state != kHTTPReadRequestBody)
				break;

		case kHTTPReadRequestBody:
			FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestState, request);
			readSomeMore = false;
			amt = request->in.max - request->in.pos;
			if (request->requestBodyContentLength > 0) {
				if (amt) {
					request->state = kHTTPProcessRequestBody;
				}
				else {
					request->in.max = 0;
					request->in.pos = 0;
					readSomeMore = true;
				}
			}
			else if (request->requestBodyChunked) {		// chunked
				if (amt == 0) {
					readSomeMore = true;
				}
				else {
					p = &request->in.buf[request->in.pos];
					while ((amt > 1) && lineEnd(p)) {
						// consume line-ends
						amt -= 2;
						request->in.pos += 2;
						p += 2;
					}
					while ((amt > 1) && !lineEnd(p)) {
						// scan for chunk size
						amt--;
						p++;
					}
					if ((amt > 1) && lineEnd(p)) {
						// convert the chunksize
						s = &request->in.buf[request->in.pos];
						chunkSize = FskStrHexToNum(s, p-s);
						p += 2;		//lineend
						request->requestBodyContentLength = chunkSize;
						request->in.pos += (p-s);
						request->state = kHTTPReadRequestBody;
						if (0 == chunkSize)	{
							// we've read the end indicator (0)
							if ((amt > 1) && lineEnd(p))
								request->in.pos += 2;			// consume last cr/lf							}
							request->requestBodyChunked = false;
						}
					}
					else {
						readSomeMore = true;
					}
				}
			}
			else {
				// we're done reading chunks
				// we're done reading the request
				request->state = kHTTPPrepareResponse;
				doCallCondition(request->http->callbacks->requestCondition, request, kFskHTTPConditionRequestRequestFinished, request->refCon);
			}

			if (readSomeMore) {
				shoveBuffer(request->in);
				err = FskNetSocketRecvTCP(request->skt, &request->in.buf[request->in.max], request->in.bufferSize - request->in.max, &ret);
				switch (err) {
					case kFskErrNone:
#if SUPPORT_INSTRUMENTATION
						if (FskInstrumentedItemHasListeners(request)) {
							FskHTTPInstrMsgDataRecord msg;
							msg.buffer = &request->in.buf[request->in.max];
							msg.amt = ret;
							FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestRecvData, &msg);
						}
#endif
						request->in.max += ret;
						if (request->requestBodyChunked) 		// chunked?
							request->state = kHTTPReadRequestBody;
						else
							request->state = kHTTPProcessRequestBody;

						request->stats.bytesReceived += ret;
						request->http->stats.bytesReceived += ret;
						break;
					case kFskErrNoData:
						retVal = kFskErrNoData;
						break;
					default:
						FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgErrString, "kHTTPReadRequestBody: RecvTCP - error");
						request->http->stats.requestsFailed += 1;
						request->state = kHTTPSocketError;
						break;
				}
			}

			if (request->state != kHTTPProcessRequestBody)
				break;

		case kHTTPProcessRequestBody:
			FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestState, request);
			amt = request->in.max - request->in.pos;
			if (amt > request->requestBodyContentLength) {
				if (false == request->requestBodyChunked)
					request->requestBodyContentLength = amt;
				else
					amt = request->requestBodyContentLength;
			}
			chunkSizeL = (UInt32)chunkSize;
			err = doDataCallback(request->http->callbacks->requestReceiveRequest, request, &request->in.buf[request->in.pos], amt, &chunkSizeL, request->refCon);
			chunkSize = (int)chunkSizeL;
			if (kFskErrNone == err) {
				if (chunkSize) {
					request->in.pos += chunkSize;
					request->requestBodyContentLength -= chunkSize;
					request->stats.requestBodyReceived += chunkSize;
					if (false == request->requestBodyChunked) {
						if (0 == request->requestBodyContentLength)
							request->state = kHTTPPrepareResponse;
						else
							request->state = kHTTPReadRequestBody;
					}
					else
						request->state = kHTTPReadRequestBody;
				}
				else {
					// data callback wants to suspend the session and not
					// consume the chunk, it can do so
					if (request->state != kHTTPSessionSuspend)
						request->state = kHTTPServerError;
				}
			}
			else {
				// the data callback returned an error.
				if (request->state != kHTTPSessionSuspend)
					request->state = kHTTPServerError;
			}

			if (request->state != kHTTPPrepareResponse)
				break;
			doCallCondition(request->http->callbacks->requestCondition, request, kFskHTTPConditionRequestRequestFinished, request->refCon);
			if (request->state != kHTTPPrepareResponse)
				break;

		case kHTTPPrepareResponse:
			FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestState, request);
			request->state = kHTTPProcessResponse;
			err = doCallCondition(request->http->callbacks->requestCondition, request, kFskHTTPConditionRequestGenerateResponseHeaders, request->refCon);
			if (err == kFskErrNeedMoreTime)
				request->state = kHTTPSessionSuspend;
			else if (err)
				request->responseHeaders->responseCode = 500;
				
			if (request->state != kHTTPProcessResponse)
				break;
				
		case kHTTPProcessResponse:
			request->state = kHTTPGetDataChunk;
			httpPrepareResponseHeaders(request);
			if (request->state != kHTTPGetDataChunk)
				break;

		case kHTTPGetDataChunk:
			FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestState, request);
			if (0 == FskStrCompare(kFskStrHEAD, FskHeaderMethod(request->requestHeaders))) {
				request->state = kHTTPSendDataChunk;
				request->nextState = kHTTPSetupNextRequest;
				break;
			}
			p = &request->out.buf[request->out.max];
			if (request->transferEncoding == kFskTransferEncodingChunked) {
				request->out.max += 6;
			}
			chunkSize = 0;
			amt = (request->out.bufferSize - request->out.max) - 2;
			// fetch response data from callback
			chunkSizeL = (UInt32)chunkSize;
			err = doDataCallback(request->http->callbacks->requestGenerateResponseBody, request, &request->out.buf[request->out.max], amt, &chunkSizeL, request->refCon);
			chunkSize = (int)chunkSizeL;
			FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "doDataCallback returns err: %d, chunkSize: %d\n", err, chunkSize);
			if ((kFskErrNone != err) && (kFskErrEndOfFile != err)) {
				FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "about to doCallCondition -requestResponseFinished - FAIL\n");
				doCallCondition(request->http->callbacks->requestCondition, request, kFskHTTPConditionRequestResponseFinished, request->refCon);
				request->http->stats.requestsFailed += 1;
				request->state = kHTTPServerError;
				break;
			}
			request->out.max += chunkSize;
			if ((0 == chunkSize) && (request->state == kHTTPSessionSuspend)) {
                if (kFskTransferEncodingChunked == request->transferEncoding)
                    request->out.max -= 6;
				break;
            }

			request->state = kHTTPSendDataChunk;
			if ((chunkSize == 0) || (kFskErrEndOfFile == err)) {
				request->nextState = kHTTPSetupNextRequest;
			}
			else
				request->nextState = kHTTPGetDataChunk;
			if (request->transferEncoding == kFskTransferEncodingChunked) {
				FskStrNumToHex(chunkSize, p, 4);
				p += 4;
				*p++ = kFskCR;
				*p++ = kFskLF;
				if (chunkSize)
					p += chunkSize;
				*p++ = kFskCR;
				*p++ = kFskLF;
				request->out.max += 2;
			}
			request->stats.bodyBytesSent += chunkSize;

			if (request->state != kHTTPSendDataChunk)
				break;

		case kHTTPSendDataChunk:
			FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestState, request);
			FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, " - request->out.max %d - request->out.pos %d\n", request->out.max, request->out.pos);
			amt = request->out.max - request->out.pos;
			if (0 == amt) {
				FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "amt is zero now - transition to next state.\n");
				request->state = request->nextState;
				break;
			}
			err = FskNetSocketSendTCP(request->skt, &request->out.buf[request->out.pos], amt, &ret);
			switch (err) {
				case kFskErrNone:
#if SUPPORT_INSTRUMENTATION
					if (FskInstrumentedItemHasListeners(request)) {
						FskHTTPInstrMsgDataRecord msg;
						msg.buffer = &request->out.buf[request->out.pos];
						msg.amt = ret;
						FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestSendData, &msg);
					}
#endif
					request->out.pos += ret;
					request->stats.bytesSent += ret;
					request->http->stats.bytesSent += ret;
					if (request->transferEncoding == kFskTransferEncodingChunked) {
						request->stats.bytesSent -= 8;
					}
					if (request->out.pos == request->out.max) {
						request->out.pos = 0;
						request->out.max = 0;
						request->state = request->nextState;
					}
					break;
				case kFskErrNoData:
					retVal = kFskErrSocketFull;
					break;
				default:
					FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgErrString, "kHTTPSendDataChunk: SendTCP - error");
					request->state = kHTTPSocketError;
					request->http->stats.requestsFailed += 1;
					break;
			}			

			if (request->state != kHTTPSetupNextRequest)
				break;

		case kHTTPSetupNextRequest:
			FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestState, request);
			FskTimeGetNow(&request->stats.requestStopped);
			request->http->stats.requestsFinished += 1;
			doCallCondition(request->http->callbacks->requestCondition, request, kFskHTTPConditionRequestResponseFinished, request->refCon);
			request->state = kHTTPDone;
			if (request->keepAlive && !request->http->stopped) {
				if ((request->in.max - request->in.pos) > 0) {
					FskHeaderStructDispose(request->requestHeaders);
					FskHeaderStructDispose(request->responseHeaders);
					FskHeaderStructNew(&request->requestHeaders);
					FskHeaderStructNew(&request->responseHeaders);
					request->keepAlive = false;
					request->out.max = 0;
					request->out.pos = 0;
					FskMemSet(&request->stats, 0, sizeof(request->stats));
					FskTimeGetNow(&request->stats.requestStarted);
					request->state = kHTTPProcessRequestHeaders;
				}
			}

			if (request->state != kHTTPDone)
				break;

		case kHTTPDone:
			FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestState, request);
			if (request->keepAlive && !request->http->stopped) {
				FskHeaderStructDispose(request->requestHeaders);
				FskHeaderStructDispose(request->responseHeaders);
				FskHeaderStructNew(&request->requestHeaders);
				FskHeaderStructNew(&request->responseHeaders);
				request->keepAlive = false;
				request->in.max = 0;
				request->in.pos = 0;
				request->out.max = 0;
				request->out.pos = 0;
				FskMemSet(&request->stats, 0, sizeof(request->stats));
				retVal = kFskErrNoData;		// will cause data handler to be installed 
				request->state = kHTTPNewSession;
			}
			else {
				request->state = kHTTPClose;
				retVal = kFskErrNeedMoreTime;
			}
			break;

		case kHTTPFulfillExpectation:
			FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestState, request);
			request->state = kHTTPSendDataChunk;
			request->nextState = kHTTPReadRequestBody;
			request->out.max += snprintf(request->out.buf, request->out.bufferSize, "%s %d %s\r\n\r\n", httpProtocolVersionString(request), 100, FskFindResponse(100));
			break;

		case kHTTPDenyExpectation:
			FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestState, request);
			request->state = kHTTPSendDataChunk;
			request->nextState = kHTTPDone;
			request->out.max += snprintf(request->out.buf, request->out.bufferSize, "%s %d %s\r\n\r\n", httpProtocolVersionString(request), 417, FskFindResponse(417));
			break;

		case kHTTPServerError:
			FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestState, request);
			request->state = kHTTPSocketError;
			// fall through
		case kHTTPSocketError:
			FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestState, request);
			request->http->stats.connectionsAborted++;
			doCallCondition(request->http->callbacks->requestCondition, request, kFskHTTPConditionRequestErrorAbort, request->refCon);
			request->state = kHTTPClose;
			// fall through
		case kHTTPClose:
			FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestState, request);
			request->state = kHTTPRequestComplete;
			needsDispose = true;
			break;

		case kHTTPRequestComplete:
			FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestState, request);
			retVal = kFskErrNone;				// request is finished, don't call back
			break;

		case kHTTPSessionSuspend:
			FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestState, request);
			retVal = kFskErrNone;				// do nothing in suspend state
			break;
		
		default:
			FskInstrumentedItemSendMessage(request, kFskHTTPInstrMsgRequestState, request);
			request->state = kHTTPClose;		// unknown state
			break;
			;
	}

	if ((request->state == kHTTPServerError)
		|| (request->state == kHTTPSocketError)
		|| (request->state == kHTTPDone)
		|| (request->state == kHTTPClose))
		retVal = kFskErrNeedMoreTime;

	if (retVal == kFskErrNoData) {
		FskThreadAddDataHandler(&request->dataHandler, (FskThreadDataSource)request->skt, httpServerDataHandler, true, false, request);
	}
	else if (retVal == kFskErrSocketFull) {
		FskThreadAddDataHandler(&request->dataHandler, (FskThreadDataSource)request->skt, httpServerDataHandler, false, true, request);
	}
	else if (retVal == kFskErrNeedMoreTime) {
		FskTimeCallbackScheduleNextRun(request->cycleCallback, httpServerTimeCycle, request);
	}
	else if (retVal == kFskErrNone) {
		// nothing doin
	}
	else {
		FskInstrumentedTypePrintfDebug(&gFskHTTPServerTypeInstrumentation, "httpCycle - weird retVal %d\n", retVal);
	}

	if (needsDispose) {
		FskListRemove((FskList*)&request->http->activeRequests, request);
		FskTimeCallbackDispose(request->keepAliveKillCallback);
		request->keepAliveKillCallback = NULL;
		if (kFskErrNone != doCallCondition(request->http->callbacks->requestCondition, request, kFskHTTPConditionConnectionTerminating, request->refCon))
			FskHTTPServerRequestDispose(request);
	}
	else {
		if ((retVal == kFskErrNeedMoreTime) || ((retVal != kFskErrNone) && request->keepAlive)) {
			FskTimeCallbackScheduleFuture(request->keepAliveKillCallback, FskHTTPServerRequestGetKeepAliveTimeout(request), 0, httpKillKeepAlive, request);
		}
	}

}