Example #1
0
void KprZeroconfEmbeddedCallback(FskTimeCallBack timer UNUSED, const FskTime time UNUSED, void *param)
{
	struct timeval timeout = { 0, 0 };
	sigset_t pSignalsReceived;
	mDNSBool pDataDispatched;
	mStatus status = mDNSPosixRunEventLoopOnce(&mDNSStorage, &timeout, &pSignalsReceived, &pDataDispatched);
	if (gEmbeddedServiceTimer)
		FskTimeCallbackScheduleFuture(gEmbeddedServiceTimer, 1, 0, KprZeroconfEmbeddedCallback, NULL);
}
Example #2
0
static FskErr httpServerListenerStart(FskHTTPServerListener listener, FskSocket skt) {
	FskErr err = kFskErrNone;
	FskHTTPServerRequest request;

	if (listener->http->stopped) {
		FskInstrumentedItemSendMessage(listener->http, kFskHTTPInstrMsgConnectionRefusedStopped, listener);
		listener->http->stats.connectionsRefused++;
		FskNetSocketClose(skt);
		goto bail;
	}
		
	err = FskMemPtrNewClear(sizeof(FskHTTPServerRequestRecord), (FskMemPtr*)&request);
	BAIL_IF_ERR(err);

	sFskHTTPServerRequestUpUse(request);

	request->http = listener->http;
	request->skt = skt;	
	FskNetSocketGetRemoteAddress(skt, (UInt32 *)&request->requesterAddress, &request->requesterPort);
	FskNetSocketMakeNonblocking(request->skt);
	err = FskHeaderStructNew(&request->requestHeaders);
	BAIL_IF_ERR(err);
	err = FskHeaderStructNew(&request->responseHeaders);
	BAIL_IF_ERR(err);
	request->in.bufferSize = request->http->defaultBufferSize;
	request->out.bufferSize = request->http->defaultBufferSize;
	err = FskMemPtrNew(request->in.bufferSize, (FskMemPtr*)&request->in.buf);
	BAIL_IF_ERR(err);
	err = FskMemPtrNew(request->out.bufferSize, (FskMemPtr*)&request->out.buf);
	BAIL_IF_ERR(err);

	FskListAppend((FskList*)&request->http->activeRequests, request);
	FskTimeCallbackNew(&request->cycleCallback);
	FskTimeCallbackNew(&request->keepAliveKillCallback);

	listener->http->stats.connectionsMade++;

	request->state = kHTTPNewSession;

	FskInstrumentedItemNew(request, NULL, &gFskHTTPServerRequestTypeInstrumentation);
	FskInstrumentedItemSetOwner(request, request->http);
	
	FskTimeCallbackScheduleNextRun(request->cycleCallback, httpServerTimeCycle, request);
	doCallCondition(request->http->callbacks->requestCondition, request, kFskHTTPConditionConnectionInitialized, request->refCon);
	FskTimeCallbackNew(&request->timer);
	FskTimeCallbackScheduleFuture(request->timer, 1, 0, KprHTTPServerTimerCallback, request);
bail:
	if (err)
		FskHTTPServerRequestDispose(request);
	return err;
}
Example #3
0
FskErr androidAudioOutStart(FskAudioOut audioOut, FskSampleTime atSample) {
	FskErr err = kFskErrNone;
	androidAudioExt *ext = (androidAudioExt*)audioOut->ext;
	SLresult	res;

	FskAudioNativePrintfVerbose("audioOutStart %x - atSample %lld", audioOut, atSample);
	if (audioOut->playing)
		goto bail;
	if (!ext->playItf) {
		FskAudioNativePrintfMinimal("huh? No playItf");
		err = kFskErrOperationFailed;
		goto bail;
	}

	audioOut->zeroTime = atSample;
	ext->stoppedAtSamplePosition = 0;

	FskTimeCallbackNew(&ext->flushTimer);
	FskTimeCallbackScheduleFuture(ext->flushTimer, 0, kFlushAndRefillTime, flushNowCallback, audioOut);
	FskAudioNativePrintfVerbose("androidAudioOutStart %x - zeroTime %d", audioOut, audioOut->zeroTime);

	// in case volume has changed when audio was off
//	androidAudioOutSetVolume(audioOut, audioOut->leftVolume, audioOut->rightVolume);

	refillQueue(audioOut);
	fillBuffers(audioOut);
	audioOut->playing = true;
//	refillQueue(audioOut);

    FskTimeGetNow(&ext->lastTime);

	FskMutexAcquire(gActiveAudioMutex);
	gActiveAudioOut = audioOut;
	FskMutexRelease(gActiveAudioMutex);

	res = (*ext->playItf)->SetPlayState(ext->playItf, SL_PLAYSTATE_PLAYING);
	CheckErr(" audioOutStart - set playstate playing", res);

	{
		SLmillisecond msec;
		res = (*ext->playItf)->GetPosition(ext->playItf, &msec);
		CheckErr(" androidAudioOutStart", res);
		ext->startedAtSamplePosition = MSToSamples(audioOut, msec);
	}

bail:
	return err;
}
Example #4
0
static void gpioPoller(FskTimeCallBack callback, const FskTime time, void *param)
{
    FskGPIO walker;
    FskThread thread = FskThreadGetCurrent();

    for (walker = gGPIOPollers; NULL != walker; walker = walker->next) {
        int value = FskGPIOPlatformRead(walker);
        if (value == walker->pollerValue)
            continue;

        walker->pollerValue = value;

        if (thread == walker->thread)
            KprPinsPollerRun(walker->poller);
        else
            FskThreadPostCallback(walker->thread, gpioPollerThreadCallback, walker, NULL, NULL, NULL);
    }

    FskTimeCallbackScheduleFuture(gGPIOPoller, 0, 33, gpioPoller, NULL);
}
Example #5
0
FskErr KprLabelInsertStringWithLength(KprLabel self, char* text, UInt32 size)
{
	FskErr err = kFskErrNone;
	UInt32 oldSize = FskStrLen(self->text);
	SInt32 fromSize = fxUnicodeToUTF8Offset(self->text, self->from);
	SInt32 toSize = fxUnicodeToUTF8Offset(self->text, self->to);
	UInt32 newSize = oldSize - (toSize - fromSize) + size;
	char* buffer;
	bailIfError(FskMemPtrNew(newSize + 1, &buffer));
	if (fromSize > 0)
		FskMemMove(buffer, self->text, fromSize); 
	if (size > 0)
		FskMemMove(buffer + fromSize, text, size); 
	if (oldSize - toSize > 0)
		FskMemMove(buffer + fromSize + size, self->text + toSize, oldSize - toSize);
	buffer[newSize] = 0;
	FskMemPtrDispose(self->text);
	if (self->flags & kprTextHidden) {
		if ((self->from == self->length) && (self->to == self->length) && (fxUTF8ToUnicodeOffset(text, size) == 1)) {
			self->flags |= kprTextShowLast;
			if (!self->showLastCallback)
				FskTimeCallbackNew(&self->showLastCallback);
			FskTimeCallbackScheduleFuture(self->showLastCallback, 1, 0, KprLabelShowLastCallback, self);		
		}
		else {
			if (self->showLastCallback)
				FskTimeCallbackRemove(self->showLastCallback);
			self->flags &= ~kprTextShowLast;
		}
	}
	self->text = buffer;
	self->length = fxUnicodeLength(buffer);
	self->from = self->to = fxUTF8ToUnicodeOffset(buffer, fromSize + size);
bail:
	if (self->shell) {
		KprLabelMeasureSelection(self);
		KprContentInvalidate((KprContent)self);
		KprContentReflow((KprContent)self, kprSizeChanged);
	}
	return err;
}
Example #6
0
FskErr KprZeroconfPlatformServiceNew(KprZeroconfPlatformService* it, KprZeroconfPlatformService owner, DNSServiceRef serviceRef, const char* name, UInt32 port)
{
	FskErr err = kFskErrNone;
	KprZeroconfPlatformService self = NULL;
	SInt32 fd = DNSServiceRefSockFD(serviceRef);
	bailIfError(FskMemPtrNewClear(sizeof(KprZeroconfPlatformServiceRecord), &self));
	FskInstrumentedItemNew(self, NULL, &KprZeroconfPlatformServiceInstrumentation);
	self->owner = owner;
	self->serviceRef = serviceRef;
	if (name) {
		self->name = FskStrDoCopy(name);
		bailIfNULL(self->name);
	}
	self->port = port;
#if KPR_ZEROCONF_EMBEDDED
	if (!gEmbeddedServiceCount) {
		FskTimeCallbackNew(&gEmbeddedServiceTimer);
		FskTimeCallbackScheduleFuture(gEmbeddedServiceTimer, 0, 0, KprZeroconfEmbeddedCallback, NULL);
	}
	gEmbeddedServiceCount++;
#elif TARGET_OS_MAC
	CFSocketContext context;
	FskMemSet(&context, 0, sizeof(context));
	context.info = (void*)serviceRef;
	self->socket = CFSocketCreateWithNative(kCFAllocatorDefault, fd, kCFSocketReadCallBack, KprZeroconfPlatformCallBack, &context);
	self->source = CFSocketCreateRunLoopSource(NULL, self->socket, 0);
	CFRunLoopAddSource(CFRunLoopGetCurrent(), self->source, kCFRunLoopCommonModes);
#else
	self->source = FskThreadCreateDataSource(fd);
	FskSocketActivate(self->source, true);
	FskThreadAddDataHandler(&self->handler, self->source, KprZeroconfPlatformCallBack, true, false, serviceRef);
#endif
	*it = self;
	return err;
bail:
	if (err) {
		KprZeroconfPlatformServiceDispose(self);
	}
	return err;
}
Example #7
0
void flushNowCallback(FskTimeCallBack callback, const FskTime time, void *param) {
	FskAudioOut audioOut = (FskAudioOut)param;
	androidAudioExt *ext = (androidAudioExt*)audioOut->ext;
	Boolean isValid = false;

	FskAudioNativePrintfDebug("flushNowCallback");

	androidAudioOutIsValid(audioOut, &isValid);

	if (!isValid || audioOut->thread == NULL) {
		FskAudioNativePrintfVerbose("flushNowCallback - isValid? (%s) - audioOut->thread (%x) - bail", isValid ? "yes" : "no", audioOut->thread);
		return;
	}

//	removeFromQueue(audioOut, kUsed);
	if (FskThreadGetCurrent() == audioOut->thread)
		flushAndRefill(audioOut, NULL, NULL, NULL);
	else
		FskThreadPostCallback(audioOut->thread, flushAndRefill, audioOut, NULL, NULL, NULL);
	if (audioOut->playing)
		FskTimeCallbackScheduleFuture(ext->flushTimer, 0, kFlushAndRefillTime, flushNowCallback, audioOut);
}
Example #8
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);
		}
	}

}
Example #9
0
static void KprHTTPServerTimerCallback(FskTimeCallBack callback, const FskTime time, void *it)
{
	FskHTTPServerRequest self = it;
	FskTimeCallbackScheduleFuture(self->timer, 0, 200, KprHTTPServerTimerCallback, self);
	FskHTTPServerRequestCycle(self);
}