예제 #1
0
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);
	}
}
예제 #2
0
void KprLabelDispose(void* it) 
{
	KprLabel self = it;
	FskTimeCallbackDispose(self->showLastCallback);
	FskMemPtrDispose(self->text);
	KprContentDispose(it);
}
예제 #3
0
파일: FskSSL.c 프로젝트: afrog33k/kinomajs
void
FskSSLDispose(void *a)
{
	FskSSL *fssl = a;

	if (fssl->timer != NULL)
		FskTimeCallbackDispose(fssl->timer);

	/* when a VM is disposed, all objects associated to the vm will be discarded? */
	xsBeginHost(fssl->vm->the);
	xsTry {
		if (fssl->skt != NULL) {
			/* someone else owns the skt */
			xsCall0_noResult(fssl->socket, xsID("detachData"));
		}
		xsCall0_noResult(fssl->socket, xsID("close"));
	} xsCatch {
	}
	xsForget(fssl->socket);
	xsForget(fssl->ssl);
	xsEndHost(fssl->vm->the);

	disposeSSLVM(fssl->vm);
	FskMemPtrDispose(a);
}
예제 #4
0
FskErr KprMQTTQueueDispose(KprMQTTQueue self)
{
	if (self) {
		KprMQTTMessage message;

		FskTimeCallbackDispose(self->resendCallback);

		message = self->inbox;
		while (message) {
			KprMQTTMessage tmp = message->next;

			KprMQTTMessageDispose(message);
			message = tmp;
		}

		message = self->outbox;
		while (message) {
			KprMQTTMessage tmp = message->next;

			KprMQTTMessageDispose(message);
			message = tmp;
		}

		FskMemPtrDispose(self);
	}
	return kFskErrNone;
}
예제 #5
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;
        }
    }
}
예제 #6
0
FskErr KprMQTTClientDispose(KprMQTTClient self)
{
	if (self) {
		KprMQTTClientForceClose(self);

		FskTimeCallbackDispose(self->pingRequestCallaback);
		FskTimeCallbackDispose(self->pingResponseCallaback);

		KprMQTTMessageDispose(self->connectMessage);
		self->connectMessage = NULL;

		KprMQTTQueueDispose(self->queue);

		FskMemPtrDispose(self->clientIdentifier);
		FskMemPtrDispose(self->host);

		FskMemPtrDispose(self);
	}
	return kFskErrNone;
}
예제 #7
0
void KprZeroconfPlatformStop()
{
#if KPR_ZEROCONF_EMBEDDED
	if (gInterfaceNotifier) {
		FskNetInterfaceRemoveNotifier(gInterfaceNotifier);
		gInterfaceNotifier = NULL;
	}
	FskTimeCallbackDispose(gEmbeddedServiceTimer);
	gEmbeddedServiceTimer = NULL;
#endif
}
예제 #8
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);
    }
}
예제 #9
0
파일: FskSSL.c 프로젝트: afrog33k/kinomajs
static void
time_callback(FskTimeCallBack callback, const FskTime time, void *param)
{
	FskSSL *fssl = param;
	FskSocket skt;
	void *refCon;

	FskTimeCallbackDispose(callback);
	fssl->timer = NULL;
	skt = fssl->skt;
	refCon = fssl->callbackData;
	if (fssl->skt == NULL)		/* check if some error has occurred and dispose everything here in that case as there's no chance to do after this point */
		FskSSLDispose(fssl);
	(*fssl->socketCallback)(skt, refCon);
	/* nothing should be here! */
}
예제 #10
0
FskErr androidAudioOutStop(FskAudioOut audioOut) {
	androidAudioExt	*ext;
	FskSampleTime pos;
	SLresult	res;
	FskErr err = kFskErrNone;

	FskAudioNativePrintfVerbose("audioOutStop %x", audioOut);

	BAIL_IF_NULL(audioOut, err, kFskErrNone);

	ext = (androidAudioExt*)audioOut->ext;
	BAIL_IF_NULL(ext, err, kFskErrNone);

	if (ext->flushTimer) {
		FskAudioNativePrintfVerbose("%x -- Disposing of flushTimer", audioOut);
		FskTimeCallbackDispose(ext->flushTimer);
		ext->flushTimer = NULL;
	}

	if (!audioOut->playing) {
		FskAudioNativePrintfDebug(" -- wuzn't playin");
		BAIL(kFskErrNone);
	}


	androidAudioOutGetSamplePosition(audioOut, &ext->stoppedAtSamplePosition);	// get final pos before we shut it down
	FskAudioNativePrintfVerbose("stoppedAtSamplePosition = %lld", ext->stoppedAtSamplePosition);

	audioOut->playing = false;
	FskAudioNativePrintfVerbose("-- stopping audioOut: %x", audioOut);

	res = (*ext->playItf)->SetPlayState(ext->playItf, SL_PLAYSTATE_STOPPED);
	CheckErr(" audioOutStop - set playstate stopped", res);

	if (gActiveAudioOut == audioOut) {
		FskMutexAcquire(gActiveAudioMutex);
		gActiveAudioOut = NULL;
		FskMutexRelease(gActiveAudioMutex);
	}

	androidAudioOutFlush(audioOut);

bail:
	removeFromQueue(audioOut, kAll);

	return err;
}
예제 #11
0
void KprZeroconfPlatformServiceDispose(KprZeroconfPlatformService self)
{
	if (self) {
#if KPR_ZEROCONF_EMBEDDED
		gEmbeddedServiceCount--;
		if (!gEmbeddedServiceCount) {
			FskTimeCallbackDispose(gEmbeddedServiceTimer);
			gEmbeddedServiceTimer = NULL;
		}
#elif TARGET_OS_MAC
		if (self->source) {
			CFRunLoopRemoveSource(CFRunLoopGetCurrent(), self->source, kCFRunLoopCommonModes);
			CFRelease(self->source);
			self->source = NULL;
		}
		if (self->socket) {
			CFSocketInvalidate(self->socket);
			CFRelease(self->socket);
			self->socket = NULL;
		}
#else
		FskSocketActivate(self->source, false);
		if (self->handler) {
			FskThreadRemoveDataHandler(&self->handler);
			self->handler = NULL;
		}
		if (self->source) {
			FskMemPtrDispose(self->source);
			self->source = NULL;
		}
#endif
		if (self->serviceRef) {
			DNSServiceRefDeallocate(self->serviceRef);
			self->serviceRef = NULL;
		}
		FskMemPtrDispose(self->txt);
		FskMemPtrDispose(self->name);
		FskInstrumentedItemDispose(self);
		FskMemPtrDispose(self);
	}
}
예제 #12
0
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);
		}
	}

}