bool InboundMJPGHTTPStreamProtocol::Send404NotFound() {
	_outputBuffer.ReadFromString("HTTP/1.0 404 Not found\r\n");
	_outputBuffer.ReadFromString(HTTP_HEADERS_SERVER": "HTTP_HEADERS_SERVER_US"\r\n");
	_outputBuffer.ReadFromString(HTTP_HEADERS_X_POWERED_BY": "HTTP_HEADERS_X_POWERED_BY_US"\r\n\r\n");
	if (!EnqueueForOutbound()) {
		FATAL("Unable to enqueue for outbound");
		return false;
	}
	GracefullyEnqueueForDelete();
	return true;
}
bool InboundMJPGHTTPStreamProtocol::SendCrossDomain() {
	if (!fileExists(_crossDomainFile)) {
		FATAL("cross domain file %s not found", STR(_crossDomainFile));
		return Send404NotFound();
	}
	File cd;
	if (!cd.Initialize(_crossDomainFile, FILE_OPEN_MODE_READ)) {
		FATAL("cross domain file %s could not be read", STR(_crossDomainFile));
		return Send404NotFound();
	}
	_outputBuffer.ReadFromString("HTTP/1.0 200 OK\r\n");
	_outputBuffer.ReadFromString(HTTP_HEADERS_SERVER": "HTTP_HEADERS_SERVER_US"\r\n");
	_outputBuffer.ReadFromString(HTTP_HEADERS_X_POWERED_BY": "HTTP_HEADERS_X_POWERED_BY_US"\r\n");
	_outputBuffer.ReadFromString(HTTP_HEADERS_CONTENT_TYPE": text/xml\r\n");
	_outputBuffer.ReadFromString(format("%s: %"PRIu64"\r\n\r\n", HTTP_HEADERS_CONTENT_LENGTH, cd.Size()));
	_outputBuffer.ReadFromFs(cd, cd.Size());
	//FINEST("_outputBuffer:\n%s", STR(_outputBuffer));
	if (!EnqueueForOutbound()) {
		FATAL("Unable to enqueue for outbound");
		return false;
	}
	GracefullyEnqueueForDelete();
	return true;
}
bool BaseVariantProtocol::Send(Variant &variant) {
	//1. Do we have a protocol?
	if (_pFarProtocol == NULL) {
		FATAL("This protocol is not linked");
		return false;
	}

	//2. Save the variant
	_lastSent = variant;

	//3. Depending on the far protocol, we do different stuff
	string rawContent = "";
	switch (_pFarProtocol->GetType()) {
		case PT_TCP:
		{
			//5. Serialize it
			if (!Serialize(rawContent, variant)) {
				FATAL("Unable to serialize variant");
				return false;
			}

			_outputBuffer.ReadFromRepeat(0, 4);
			uint32_t rawContentSize = rawContent.size();
			EHTONLP(GETIBPOINTER(_outputBuffer), rawContentSize);
			_outputBuffer.ReadFromString(rawContent);

			//6. enqueue for outbound
			if (!EnqueueForOutbound()) {
				FATAL("Unable to enqueue for outbound");
				return false;
			}
			GracefullyEnqueueForDelete();
			return true;
		}
		case PT_OUTBOUND_HTTP:
		{
#ifdef HAS_PROTOCOL_HTTP
			//7. This is a HTTP request. So, first things first: get the http protocol
			OutboundHTTPProtocol *pHTTP = (OutboundHTTPProtocol *) _pFarProtocol;

			//8. We wish to disconnect after the transfer is complete
			pHTTP->SetDisconnectAfterTransfer(true);

			//9. This will always be a POST
			pHTTP->Method(HTTP_METHOD_POST);

			//10. Our document and the host
			pHTTP->Document(variant["document"]);
			pHTTP->Host(variant["host"]);

			//11. Serialize it
			if (!Serialize(rawContent, variant["payload"])) {
				FATAL("Unable to serialize variant");
				return false;
			}

			_outputBuffer.ReadFromString(rawContent);

			//12. enqueue for outbound
			return EnqueueForOutbound();
#else
			FATAL("HTTP protocol not supported");
			return false;
#endif /* HAS_PROTOCOL_HTTP */
		}
		case PT_INBOUND_HTTP:
		{
#ifdef HAS_PROTOCOL_HTTP
			if (!Serialize(rawContent, variant)) {
				FATAL("Unable to serialize variant");
				return false;
			}

			_outputBuffer.ReadFromString(rawContent);

			return EnqueueForOutbound();
#else
			FATAL("HTTP protocol not supported");
			return false;
#endif /* HAS_PROTOCOL_HTTP */
		}
		default:
		{
			ASSERT("We should not be here");
			return false;
		}
	}
}