Example #1
0
static ConstStrA findInAllowedSet(ConstStrA field, ConstStrA allowedSet) {
	using namespace LightSpeed;
	for (ConstStrA::SplitIterator iter = allowedSet.split(',');iter.hasItems();) {
		ConstStrA value = iter.getNext();
		natural eq = value.find('=');
		if (eq == naturalNull) {
			if (value == field) return value;
		} else {
			if (value.head(eq) == field) {
				return value.offset(eq+1);
			}
		}
	}
	return ConstStrA();
}
void HttpReqImpl::redirect(ConstStrA url, int code) {
	if (code == 0) {
		if (url.head(1) == ConstStrA('+')) code = 301;
		else code = 307;
	}


	TextParser<char> parser;
	if (parser("%[a-z]0://%",url)) {
		header(fldLocation, url);
	} else {
		StringA absurl = getAbsoluteUrl(url);
		header(fldLocation, absurl);
	}
	header(fldContentLength, "0");
	status(code);
	sendHeaders();

}
static ConstStrA getStatusMessage(natural status) {
	char buff[3];
	if (status >= 100 && status <= 999) {
		buff[0] = status / 100 + '0';
		buff[1] = (status / 10) % 10 + '0';
		buff[2] = status % 10 + '0';
		ConstStrA srchText(buff, 3);
		natural l = 0, h = countof(statusMessages);
		while (l < h) {
			natural m = (l + h) / 2;
			ConstStrA msg = statusMessages[m];
			ConstStrA code = msg.head(3);
			if (code > srchText)
				h = m;
			else if (code < srchText)
				l = m + 1;
			else
				return msg.offset(4);
		}
	}

	return ConstStrA("Unknown status code");
}
ITCPServerConnHandler::Command  HttpReqImpl::readHeader() {

	try {

		AutoArray<char, SmallAlloc<8192> > linebuff;

		NStream::Buffer &buffer = inout->getBuffer();
		natural fetched = buffer.fetch();
		if (fetched == 0) {
			errorPage(413,ConstStrA(),"Header is too large");
			return ITCPServerConnHandler::cmdRemove;
		}
		natural pos = buffer.lookup(ConstBin("\r\n"),fetched);
		while (pos != naturalNull) {

			linebuff.resize(pos+2);
			buffer.read(linebuff.data(),pos+2);
			ConstStrA line = linebuff.head(pos);

			if (method.empty()) {
				if (pos == 0) return ITCPServerConnHandler::cmdWaitRead;

				reqBeginTime = TimeStamp::now();
				reportDuration = true;

				cropWhite(line);
				ConstStrA::SplitIterator splt = line.split(' ');
				method = hdrPool.add(ConstStrA(splt.getNext()));
				path = hdrPool.add(ConstStrA(splt.getNext()));
				while (path.empty()) path = hdrPool.add(ConstStrA(splt.getNext()));
				protocol = hdrPool.add(ConstStrA(splt.getNext()));
				while (protocol.empty()) protocol = hdrPool.add(ConstStrA(splt.getNext()));
				//parse some fields
				TextParser<char,StaticAlloc<256> > parser;

				//check http version
				if (parser("HTTP/%u1.%u2",protocol)) {
						httpMajVer = (unsigned short)((natural)parser[1]);
						httpMinVer = (unsigned short)((natural)parser[2]);
						if (httpMajVer != 1 || (httpMinVer != 0 && httpMinVer != 1))
							return errorPageKA(505);
						useHTTP11(httpMinVer == 1);
				} else {
					return errorPageKA(400,StringA(ConstStrA("Unknown protocol: ")+ protocol));
				}
			} else if (line.empty()) {
				return finishReadHeader();
			} else {

				natural dblcolon = line.find(':');
				if (dblcolon == naturalNull) {
					errorPage(400,ConstStrA(),"line");
					return ITCPServerConnHandler::cmdRemove;
				}
				ConstStrA field = line.head(dblcolon);
				ConstStrA value = line.offset(dblcolon+1);
				cropWhite(field);
				cropWhite(value);
				requestHdrs.insert(hdrPool.add(field),hdrPool.add(value));
			}
			pos = buffer.lookup(ConstBin("\r\n"));
		}
		return ITCPServerConnHandler::cmdWaitRead;
	} catch (AllocatorLimitException &) {
		errorPage(413,ConstStrA(),"Header is too large (4096 bytes)");
		return ITCPServerConnHandler::cmdRemove;
	}
}