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; } }