Ejemplo n.º 1
0
/**
 * Process the http request line
 * parse method, URL and version
 * @param line string to process
 * @param method
 * @param URL
 * @param version
 */
void Socket::parseRequestLine(const string &line){
	syslog(LOG_DEBUG,"Request line :\"%s\"",line.c_str());
	method="";
	URL="";
	version="";
	protocol="";
	URLPath="";
	regmatch_t match[4];
	int nomatch=regexec(&regRequestLine, line.c_str(),4, match, 0);
	if(nomatch)
		throw HttpException(badRequestCode,"Erroneous request line",line);
	method=line.substr(match[1].rm_so,match[1].rm_eo-match[1].rm_so);
	syslog(LOG_DEBUG,"method :\"%s\"",method.c_str());
	URL=line.substr(match[2].rm_so,match[2].rm_eo-match[2].rm_so);
	syslog(LOG_DEBUG,"URL :\"%s\"",URL.c_str());
	version=line.substr(match[3].rm_so,match[3].rm_eo-match[3].rm_so);
	syslog(LOG_DEBUG,"version :\"%s\"",version.c_str());

	nomatch=regexec(&regURL, URL.c_str(),4, match, 0);
	if(nomatch)
		throw HttpException(badRequestCode,"Erroneous URL",URL);
	if(match[1].rm_so>=0)
		protocol=URL.substr(match[1].rm_so,match[1].rm_eo-match[1].rm_so);
	URLPath=URL.substr(match[3].rm_so,match[3].rm_eo-match[3].rm_so);
}
Ejemplo n.º 2
0
void Socket::send(const string &data, bool async){
	if(closed) return;
	writeBuffer += data;
	size_t size=writeBuffer.size();
	const unsigned char *s=(const unsigned char *)writeBuffer.data();
	syslog(LOG_INFO,"Sending %lu",(long unsigned int)size);
	size_t offset=0;
	struct pollfd devices[1];
	devices[0].fd=socket;
	devices[0].events=POLLOUT;
	const int wait=1; // 1 milisec
	const int bad=POLLERR|POLLHUP|POLLNVAL;
	time_t timeLimit=time(NULL)+JAIL_SOCKET_TIMEOUT;
	time_t fullTimeLimit=time(NULL)+JAIL_SOCKET_REQUESTTIMEOUT;
	while(true){
		int res=poll(devices,1,wait);
		if(res==-1) {
			throw HttpException(internalServerErrorCode
					,"Error poll writing data"); //Error
		}
		if(res==0 && async) break; //async write Nothing to do
		if(res==0) continue; //Nothing to do
		time_t currentTime=time(NULL);
		if(currentTime>timeLimit || currentTime>fullTimeLimit){
			syslog(LOG_ERR,"Socket write timeout");
			throw requestTimeoutCode;
		}
		if(devices[0].revents & POLLOUT){ //Write to net
			size_t toWrite=JAIL_NET_BUFFER_SIZE;
			if(toWrite>size-offset)
				toWrite=size-offset;
			int sizeWritten=netWrite(s+offset,toWrite);
			if(sizeWritten <0) {
				throw HttpException(internalServerErrorCode
						,"Socket write data error");
			}if(sizeWritten == 0){
				closed=true;
				break;
			}
			else{
				offset += sizeWritten;
				timeLimit=currentTime+JAIL_SOCKET_TIMEOUT; //Reset timeout
			}
		}
		if(devices[0].revents & POLLHUP){ //socket close
			closed=true;
			syslog(LOG_INFO,"POLLHUP");
			break;
		}
		if(devices[0].revents & bad) {
			syslog(LOG_ERR,"Error writing http data %m");
			throw HttpException(internalServerErrorCode
					,"Socket write data error");
		}
		if(offset>=size) break;
	}
	writeBuffer.erase(0,offset);
	syslog(LOG_INFO,"Send %lu",(long unsigned int)offset);
}
Ejemplo n.º 3
0
/**
 * Process http request headers (until CRLFCRLF)
 * Check request line and parse headers
 * @param input lines that form the request line and headers
 */
void HttpJailServer::validateRequest(string path){
	if(socket->getMethod() != "POST"){
		throw HttpException(notImplementedCode,
				"http METHOD not implemented",socket->getMethod());
	}
	if(path == "")
		path="/";
	string URLPath=socket->getURLPath();
	if(URLPath == "")
		URLPath="/";
	if(path != URLPath){
		throw HttpException(notFoundCode
				,"http request URL path not found"
				, "expected '"+socket->getURLPath()+"' found '"+path+"'");
	}
}
Ejemplo n.º 4
0
Filter::Result DeniedMethodsFilter::Process(CGI *cgi)
{
    if (_methods.find(cgi->_SERVER["REQUEST_METHOD"]) != _methods.end()) {
        throw HttpException(405);
    }
    return kResultPass;
}
Ejemplo n.º 5
0
/**
 * Process one header
 * Parse header and save it in header map
 * @param line header to process
 */
void Socket::parseHeader(const string &line){
	syslog(LOG_INFO,"Header :\"%s\"",line.c_str());
	regmatch_t match[3];
	int nomatch=regexec(&regHeader, line.c_str(),3, match, 0);
	if(nomatch){
		char errorm[100];
		regerror(nomatch,&regHeader,errorm,100);
		syslog(LOG_DEBUG,"No match %d: %s",nomatch,errorm);
		throw HttpException(badRequestCode,"Erroneous header",line);
	}
	string field=Util::toUppercase(line.substr(match[1].rm_so,match[1].rm_eo-match[1].rm_so));
	string value=line.substr(match[2].rm_so,match[2].rm_eo-match[2].rm_so);
	headers[field]= value;
}
Ejemplo n.º 6
0
string HttpJailServer::receive(){
	if(socket->getHeader("Expect")== "100-continue"){
		sendCode(continueCode);
	}
	int sizeToRead=atoi(socket->getHeader("Content-Length").c_str());
	if(sizeToRead != 0){
		if(sizeToRead > JAIL_REQUEST_MAX_SIZE){
			throw HttpException(requestEntityTooLargeCode
					,"http Request size too large"
					,socket->getHeader("Content-Length"));
		}
		return socket->receive(sizeToRead);
	}
	return "";
}
Ejemplo n.º 7
0
void HttpResponseFile::InitContent(std::string filename)
{
	itsIFile.open(filename.c_str(), std::ios_base::in | std::ios_base::binary);
	if (!itsIFile.good()) {
		throw HttpException("Bad file given", http::Status::NOT_FOUND);
	}

	// get length of file:
	itsIFile.seekg(0, std::ios::end);
	int length = itsIFile.tellg();
	itsIFile.seekg(0, std::ios::beg);
	itsContent.resize(length);

	std::copy(std::istreambuf_iterator<char>(itsIFile),
			std::istreambuf_iterator<char>(), itsContent.begin());
	DBG << "Content of the file=" << getContent();
}
Ejemplo n.º 8
0
string Socket::receive(int sizeToReceive){ //=0 async read
	if(closed) {
		string ret=readBuffer;
		readBuffer="";
		if(ret.size()){
			syslog(LOG_INFO,"Received %lu",(long unsigned int)ret.size());
		}
		return ret;
	}
	if(header.size()==0)
		sizeToReceive = JAIL_HEADERS_SIZE_LIMIT;
	if(sizeToReceive){
		syslog(LOG_INFO,"Receiving until %d bytes",sizeToReceive);
	}
	//If already read, return data
	if(sizeToReceive>0 && readBuffer.size()>=sizeToReceive
			&& header.size()!=0){
		string ret = readBuffer.substr(0,sizeToReceive);
		readBuffer.erase(0,sizeToReceive);
		return ret;
	}
	struct pollfd devices[1];
	devices[0].fd=socket;
	devices[0].events=POLLIN;
	const int MAX=JAIL_NET_BUFFER_SIZE;
	char buf[MAX];
	const int wait=10; // 10 milisec
	const int bad=POLLERR|POLLNVAL;
	time_t timeLimit=time(NULL)+JAIL_SOCKET_TIMEOUT;
	time_t fullTimeLimit=time(NULL)+JAIL_SOCKET_REQUESTTIMEOUT;
	while(true){
		int res=poll(devices,1,wait);
		if(res==-1) {
			syslog(LOG_INFO,"poll fail reading %m");
			throw HttpException(internalServerErrorCode
					,"Error poll reading data"); //Error
		}
		time_t currentTime=time(NULL);
		if(currentTime>timeLimit || currentTime>fullTimeLimit){
			if(sizeToReceive==0){
				syslog(LOG_DEBUG,"Socket read timeout, closed connection?");
				return "";
			}else
				throw HttpException(requestTimeoutCode
						,"Socket read timeout");
		}
		if(res==0 && sizeToReceive==0) break; //Nothing to read
		if(res==0) continue; //Nothing to do
		syslog(LOG_DEBUG,"poll return: %d",res);
		if(devices[0].revents & POLLIN){ //Read from net
			int sizeRead=netRead(buf,MAX);
			if(sizeRead >0) {
				string sread(buf,sizeRead);
				if(sread.size()!=sizeRead){
					syslog(LOG_ERR,"read net decode error");
				}
				readBuffer += sread;
				if(header.size()==0){
					size_t pos;
					if((pos=readBuffer.find("\r\n\r\n")) != string::npos){
						header=readBuffer.substr(0,pos+4);
						syslog(LOG_INFO,"Received header %lu",(long unsigned int)pos+4);
						processHeaders(header);
						readBuffer.erase(0,pos+4);
						return ""; //End of process
					}else if(readBuffer.size()>JAIL_HEADERS_SIZE_LIMIT){
						throw HttpException(requestEntityTooLargeCode,"Http headers too large");
					}
				}else if(sizeToReceive==0 || readBuffer.size()>=sizeToReceive){ //Receive complete
					break;
				}
				timeLimit=currentTime+JAIL_SOCKET_TIMEOUT; //Reset timeout
			}
			else if(sizeRead<0){
				throw HttpException(badRequestCode
						,"Error reading data");
			}
			else {
				syslog(LOG_INFO,"sizeRead==0");
				closed=true;
				break;
			}
		}
		if(devices[0].revents & POLLHUP){ //socket close
			closed=true;
			syslog(LOG_INFO,"POLLHUP");
			break;
		}
		if(devices[0].revents & bad) {
			throw HttpException(internalServerErrorCode
					,"Error reading data");
		}
	}
	string ret=readBuffer;
	readBuffer="";
	if(ret.size()){
		syslog(LOG_INFO,"Received %lu",(long unsigned int)ret.size());
	}
	return ret;
}
Ejemplo n.º 9
0
void Server::ServeFile(const std::string& fileName,HttpServerContext* context,bool download)
{
    long long size=FileUtils::GetFileSize(fileName);
    if(size==-1)
        throw HttpException(HttpNotFound,"Requested file not found.");
    time_t modifyTime=FileUtils::GetFileModifyTime(fileName);
    if((context->requestHeader.modifyTime!=0)&&(modifyTime<=context->requestHeader.modifyTime))
    {
        context->responseHeader.result=HttpNotModified;
        return;
    }
    context->responseHeader.modifyTime=modifyTime;
    File in(fileName,false);
    long long contentLength;
    if(context->requestHeader.rangeFrom==-1)
    {
        contentLength=size;
        context->responseHeader.contentLength=size;
    }
    else
    {
        if(context->requestHeader.rangeTo==-1)
            context->requestHeader.rangeTo=size-1;
        contentLength=context->requestHeader.rangeTo-context->requestHeader.rangeFrom+1;
        context->responseHeader.contentLength=contentLength;
        context->responseHeader.rangeFrom=context->requestHeader.rangeFrom;
        context->responseHeader.rangeTo=context->requestHeader.rangeTo;
        context->responseHeader.rangeTotal=size;
        in.Seek(context->requestHeader.rangeFrom);
    }
    if(!download)
    {
        int slashpos=fileName.find('/');
        string t;
        if(slashpos!=string::npos)
            t=fileName.substr(slashpos+1);
        else
            t=fileName;
        int dotpos=t.rfind('.');
        if(dotpos!=string::npos)
        {
            string ext=t.substr(dotpos+1);
            context->responseHeader.contentType=Util::MimeType(ext);
        }
    }
    else
        context->responseHeader.contentType="application/octet-stream";
    context->SendResponseHeader();
    char buf[1024];
    while(contentLength>0)
    {
        int br;
        if(contentLength<sizeof(buf))
            br=static_cast<int>(contentLength);
        else
            br=sizeof(buf);
        in.Read(buf,br);
        context->Write(buf,br);
        contentLength-=br;
    }
}