From 5df79c53745fde5d6c3340a2979b1429cd5892c1 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sat, 8 Oct 2011 20:30:28 +0200 Subject: Initial import of htcd system 1.0 Signed-off-by: Henrik Rydberg --- src/net/thrserv.cc | 255 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 src/net/thrserv.cc (limited to 'src/net/thrserv.cc') diff --git a/src/net/thrserv.cc b/src/net/thrserv.cc new file mode 100644 index 0000000..0d91d12 --- /dev/null +++ b/src/net/thrserv.cc @@ -0,0 +1,255 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +const mstring cron_tag="\\run.cron"; +const mstring FATAL="FATAL ERROR"; +const mstring UNKNOWN="UNKNOWN"; +const mstring REJECTED="REJECTED"; + +const int MAXHEAD=16384; +const int MAXBODY=2<<21; +const int MAXURI=4096; +const int MAXARG=4096; +const int SAFEZONE=4096; + +/////////////////////////////////////////////////////////////// + +thrServ::thrServ(htcServ& server): + pmutex(MUTEX_INIT), + pcond(MTCOND_INIT), + keepalive(0),running(0),termok(0), + first(time(0)),last(time(0)), + serv(&server), + sock(0), + user(server.user,server.htcd.docroot) +{ +} + +thrServ::~thrServ() +{ + delete sock; +} + +void thrServ::reset(isocket* s,int keep) +{ + keepalive=keep; + running=1; + termok=0; + first=time(0); + last=time(0); + sock=s; + while(!tid); + if(MCONTINUE(pcond)) throw((int)0); +} + +void thrServ::Log(const sref& msg) +{ + MLOCK(serv->htcd.mutex); + if(sock) serv->htcd.errlog<<"["<address())<<":"<port()<<"][" + <htcd.errlog<<"["<htcd.errlog.flush(); +} + +void thrServ::enter() +{ + tid=pthread_self(); + MSUSPEND(pmutex,pcond) + while(serv->htcd.running&&!termok) { + session(); + delete sock; + sock=0; + if(serv->htcd.running&&!termok) { + MSUSPEND(pmutex,pcond) + } + } +} + +void thrServ::session() try +{ + int keep=1; + while(sock&&keep&&running) { + int test=sock->test(); + if(test>0) { last=time(0); keep=handle(); } + else if(test<0) keep=0; + } +} +catch(const merror_t& e) { + Log(e.desc); +} +catch(...) { + Log(FATAL); +} + +/////////////////////////////////////////////////////////////// + +thrCron::thrCron(htcServ& server): + tid(0),running(0),serv(&server),user(server.user,server.htcd.docroot) +{ +} + +void thrCron::Log(const sref& msg) +{ + MLOCK(serv->htcd.mutex); + serv->htcd.errlog<<"["<htcd.errlog.flush(); +} + +void thrCron::enter() try +{ + tid=pthread_self(); + tcpReq tcp; tcp.port=0; + httpReq req; + mstream devnull; + htcd_req R(serv->htcd,user.toks,devnull,tcp,req); + Env env(serv->htcd.ops,R,XSYSTEM); + env.req->running=&running; + running=1; + mstream m; + env.parse(m,cron_tag); +} +catch(const merror_t& e) { + Log(e.desc); +} +catch(...) { + Log(FATAL); +} + + +/////////////////////////////////////////////////////////////// + +int thrServ::handle() +{ + tcpReq tcp; + tcp.port=sock->port(); + if(!Lookup(tcp.node,sock->address())) { + Log(REJECTED); + return 0; + } + + ////////////////////////////////////////////////////////////////// + + mstring buffer(MAXHEAD+MAXBODY+SAFEZONE); + int nhead=sock->gethead(buffer.data(),MAXHEAD); + if(nhead==0) return 0; + else if(nhead<0) return 0; + + sref message(buffer.data(),nhead); + +#if 0 + static fp_stream merr(stderr); + merr<<"QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ\n"; + merr<htcd,user.toks,cache,tcp,req); + + ////////////////////////////////////////////////////////////////// + + if(nhead>=MAXHEAD) return SendStatus(*sock,R,keep,HTTP_413); + + if(eqn(req.method,HTTP_TRACE)) { + R.resp.cont_type="message/http"; + return SendStatus(*sock,R,keep,HTTP_200,buffer.left(nhead)); + } + + if(req.expect.nempty()) { + if(eqn(req.expect,expect_continue_tag)) SendStatus(*sock,R,keep,HTTP_100); + else return SendStatus(*sock,R,keep,HTTP_417); + } + + if(req.trans_enc.nempty()||req.cont_enc.nempty()) return SendStatus(*sock,R,0,HTTP_501); + + ////////////////////////////////////////////////////////////////// + + int ilength=atoi(req.cont_length); + if(ilength>MAXBODY) return SendStatus(*sock,R,0,HTTP_413); + else if(ilength>0) { + int nbody=sock->getbody(buffer.data()+nhead,ilength); + if(nbody<0) return 0; + else { + sref sbody(buffer.data()+nhead,nbody); +#if 0 + static fp_stream merr(stderr); + merr<<"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP\n"; + merr<htcd.ops,R,XSYSTEM); + env.req->running=&running; + mstream m; + env.parse(m,serv->server); + if(!env.req->is_running()) THROW("htc: "<