diff options
Diffstat (limited to 'src/serv')
| -rw-r--r-- | src/serv/auth.cc | 162 | ||||
| -rw-r--r-- | src/serv/const.cc | 69 | ||||
| -rw-r--r-- | src/serv/direct.cc | 73 | ||||
| -rw-r--r-- | src/serv/form.cc | 102 | ||||
| -rw-r--r-- | src/serv/htcd.h | 74 | ||||
| -rw-r--r-- | src/serv/htcs.cc | 92 | ||||
| -rw-r--r-- | src/serv/main.cc | 122 | ||||
| -rw-r--r-- | src/serv/request.cc | 279 | ||||
| -rw-r--r-- | src/serv/tempmap.cc | 82 | ||||
| -rw-r--r-- | src/serv/tempmap.h | 57 |
10 files changed, 1112 insertions, 0 deletions
diff --git a/src/serv/auth.cc b/src/serv/auth.cc new file mode 100644 index 0000000..abf16b3 --- /dev/null +++ b/src/serv/auth.cc | |||
| @@ -0,0 +1,162 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <serv/htcd.h> | ||
| 21 | |||
| 22 | const mstring default_tag=".default"; | ||
| 23 | |||
| 24 | ///////////////////////////////////////////////////////////////// | ||
| 25 | |||
| 26 | TOK_IMPL(remote_name) { out<<Reqd(env)->tcp->node.name; } | ||
| 27 | TOK_IMPL(remote_address) { out<<Reqd(env)->tcp->node.ip; } | ||
| 28 | TOK_IMPL(remote_port) { out<<Reqd(env)->tcp->port; } | ||
| 29 | |||
| 30 | ///////////////////////////////////////////////////////////////// | ||
| 31 | |||
| 32 | inline int match(const sref& rem,const sref& longrem,const sref& dom) | ||
| 33 | { | ||
| 34 | if(rem==dom) return 1; | ||
| 35 | if(*dom!='.') return 0; | ||
| 36 | if(longrem.right_last(dom)==dom) return 1; | ||
| 37 | return 0; | ||
| 38 | } | ||
| 39 | |||
| 40 | inline int allow(const sref& uname,const sref& list) | ||
| 41 | { | ||
| 42 | mstring remote=First(uname); | ||
| 43 | mstring longrem=remote; if(longrem.find('.')<0) longrem+=default_tag; | ||
| 44 | if(remote.empty()) return 0; | ||
| 45 | if(First(list).empty()) return 1; | ||
| 46 | sref first,rest=list; | ||
| 47 | while(Split(first,rest)) if(match(remote,longrem,first)) return 1; | ||
| 48 | return 0; | ||
| 49 | } | ||
| 50 | |||
| 51 | TOK_IMPL(remote_allow) { out<<allow(Reqd(env)->tcp->node.name,env[0]); } | ||
| 52 | TOK_IMPL(bindroot) { Reqd(env)->htcd()->bindroot=env[0]; } | ||
| 53 | |||
| 54 | ///////////////////////////////////////////////////////////////// | ||
| 55 | |||
| 56 | TOK_IMPL(user_allow) { | ||
| 57 | htcd_req* htcd=Reqd(env); | ||
| 58 | mstring opt=env.parg(-1); | ||
| 59 | int now=opt.empty()?time(0):atoi(opt); | ||
| 60 | out<<htcd->user.allow_list(env[0],now,htcd->RootAllowed()); | ||
| 61 | } | ||
| 62 | |||
| 63 | TOK_IMPL(on_clear) { | ||
| 64 | htcd_req* htcd=Reqd(env); | ||
| 65 | if(htcd->user.allow_list(env[0],time(0),htcd->RootAllowed())) env.parg(out,1); | ||
| 66 | else env.parg(out,2); | ||
| 67 | } | ||
| 68 | |||
| 69 | ///////////////////////////////////////////////////////////////// | ||
| 70 | |||
| 71 | TOK_IMPL(allowed) { | ||
| 72 | int ok=0; | ||
| 73 | if(!env.db) THROW("htc: no open database"); | ||
| 74 | if(env.dbat>=0&&env.dbat<env.db->size()) { | ||
| 75 | user_t user; | ||
| 76 | env.db->Get(env.dbat,user.list); | ||
| 77 | if(user.list.size()!=user_tabs) | ||
| 78 | THROW("htc: cannot test - probably not a users database"); | ||
| 79 | mstring opt=env.parg(-1); | ||
| 80 | int now=opt.empty()?time(0):atoi(opt); | ||
| 81 | ok=user.allow_list(env[0],now,Reqd(env)->RootAllowed()); | ||
| 82 | } | ||
| 83 | out<<ok; | ||
| 84 | } | ||
| 85 | |||
| 86 | TOK_IMPL(ingroups) { | ||
| 87 | int ok=0; | ||
| 88 | if(!env.db) THROW("htc: no open database"); | ||
| 89 | if(env.dbat>=0&&env.dbat<env.db->size()) { | ||
| 90 | user_t user; | ||
| 91 | env.db->Get(env.dbat,user.list); | ||
| 92 | if(user.list.size()!=user_tabs) | ||
| 93 | THROW("htc: cannot test - probably not a users database"); | ||
| 94 | mstring opt=env.parg(-1); | ||
| 95 | int now=opt.empty()?time(0):atoi(opt); | ||
| 96 | ok=user.allow_list(env[0],now,-1); | ||
| 97 | } | ||
| 98 | out<<ok; | ||
| 99 | } | ||
| 100 | |||
| 101 | ///////////////////////////////////////////////////////////////// | ||
| 102 | |||
| 103 | void envAddAuth(tokmap& T) | ||
| 104 | { | ||
| 105 | TOK_ADD(remote_name,"",tok_t::PUBLIC, | ||
| 106 | "%Remote hostname\n" | ||
| 107 | "%Syntax: \\remote.name\n" | ||
| 108 | ); | ||
| 109 | TOK_ADD(remote_address,"",tok_t::PUBLIC, | ||
| 110 | "%Remote address\n" | ||
| 111 | "%Syntax: \\remote.address\n" | ||
| 112 | ); | ||
| 113 | TOK_ADD(remote_port,"",tok_t::PUBLIC, | ||
| 114 | "%Remote port\n" | ||
| 115 | "%Syntax: \\remote.port\n" | ||
| 116 | ); | ||
| 117 | |||
| 118 | ///////////////////////////////////////////////////////////// | ||
| 119 | |||
| 120 | TOK_ADD(remote_allow,"x",tok_t::PUBLIC, | ||
| 121 | "%True if remote hostname allowed by domain\n" | ||
| 122 | "%Syntax: \\remote.allow{domain list}\n" | ||
| 123 | "%\n" | ||
| 124 | "%May be used to restrict access without any group\n" | ||
| 125 | ); | ||
| 126 | TOK_ADD(bindroot,"x",tok_t::SYSONLY, | ||
| 127 | "%Bind root access to explicit addresses\n" | ||
| 128 | "%Syntax: \\bindroot{address list}\n" | ||
| 129 | "%\n" | ||
| 130 | "%Note that domain syntax does not work here; you\n" | ||
| 131 | "%want to have total control over all root access.\n" | ||
| 132 | ); | ||
| 133 | |||
| 134 | ///////////////////////////////////////////////////////////// | ||
| 135 | |||
| 136 | TOK_ADD(user_allow,"x?",tok_t::SYSONLY, | ||
| 137 | "%Core test on user clearance\n" | ||
| 138 | "%Syntax: \\user.allow{groups}<time>\n" | ||
| 139 | "%\n" | ||
| 140 | "%In case of several groups, all must be allowed.\n" | ||
| 141 | ); | ||
| 142 | TOK_ADD(on_clear,"xr?",tok_t::SYSONLY, | ||
| 143 | "%Do if user is allowed in all groups now\n" | ||
| 144 | "%Syntax: \\on.clear{groups}{body}<else>\n" | ||
| 145 | ); | ||
| 146 | |||
| 147 | ///////////////////////////////////////////////////////////// | ||
| 148 | |||
| 149 | TOK_ADD(allowed,"x?",tok_t::SYSONLY, | ||
| 150 | "%True if the current record is allowed in all groups now\n" | ||
| 151 | "%Syntax: \\allowed{groups}<time>\n" | ||
| 152 | "%\n" | ||
| 153 | "%Only used as a query function\n" | ||
| 154 | ); | ||
| 155 | |||
| 156 | TOK_ADD(ingroups,"x?",tok_t::SYSONLY, | ||
| 157 | "%True if the current record is part of all groups now\n" | ||
| 158 | "%Syntax: \\ingroups{groups}<time>\n" | ||
| 159 | "%\n" | ||
| 160 | "%Only used as a query function\n" | ||
| 161 | ); | ||
| 162 | } | ||
diff --git a/src/serv/const.cc b/src/serv/const.cc new file mode 100644 index 0000000..f252a17 --- /dev/null +++ b/src/serv/const.cc | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <serv/htcd.h> | ||
| 21 | |||
| 22 | inline tok_t* Const(tokmap& map,const char* s,const sref& b) throw(merror_t) { | ||
| 23 | return Const(map,sref(s),b,tok_t::PUBLIC); | ||
| 24 | } | ||
| 25 | |||
| 26 | void envAddConst(tokmap& T) | ||
| 27 | { | ||
| 28 | Const(T,"HTTP.100",HTTP_100); | ||
| 29 | Const(T,"HTTP.101",HTTP_101); | ||
| 30 | Const(T,"HTTP.200",HTTP_200); | ||
| 31 | Const(T,"HTTP.201",HTTP_201); | ||
| 32 | Const(T,"HTTP.202",HTTP_202); | ||
| 33 | Const(T,"HTTP.203",HTTP_203); | ||
| 34 | Const(T,"HTTP.204",HTTP_204); | ||
| 35 | Const(T,"HTTP.205",HTTP_205); | ||
| 36 | Const(T,"HTTP.206",HTTP_206); | ||
| 37 | Const(T,"HTTP.300",HTTP_300); | ||
| 38 | Const(T,"HTTP.301",HTTP_301); | ||
| 39 | Const(T,"HTTP.302",HTTP_302); | ||
| 40 | Const(T,"HTTP.303",HTTP_303); | ||
| 41 | Const(T,"HTTP.304",HTTP_304); | ||
| 42 | Const(T,"HTTP.305",HTTP_305); | ||
| 43 | Const(T,"HTTP.306",HTTP_306); | ||
| 44 | Const(T,"HTTP.307",HTTP_307); | ||
| 45 | Const(T,"HTTP.400",HTTP_400); | ||
| 46 | Const(T,"HTTP.401",HTTP_401); | ||
| 47 | Const(T,"HTTP.402",HTTP_402); | ||
| 48 | Const(T,"HTTP.403",HTTP_403); | ||
| 49 | Const(T,"HTTP.404",HTTP_404); | ||
| 50 | Const(T,"HTTP.405",HTTP_405); | ||
| 51 | Const(T,"HTTP.406",HTTP_406); | ||
| 52 | Const(T,"HTTP.407",HTTP_407); | ||
| 53 | Const(T,"HTTP.408",HTTP_408); | ||
| 54 | Const(T,"HTTP.409",HTTP_409); | ||
| 55 | Const(T,"HTTP.410",HTTP_410); | ||
| 56 | Const(T,"HTTP.411",HTTP_411); | ||
| 57 | Const(T,"HTTP.412",HTTP_412); | ||
| 58 | Const(T,"HTTP.413",HTTP_413); | ||
| 59 | Const(T,"HTTP.414",HTTP_414); | ||
| 60 | Const(T,"HTTP.415",HTTP_415); | ||
| 61 | Const(T,"HTTP.416",HTTP_416); | ||
| 62 | Const(T,"HTTP.417",HTTP_417); | ||
| 63 | Const(T,"HTTP.500",HTTP_500); | ||
| 64 | Const(T,"HTTP.501",HTTP_501); | ||
| 65 | Const(T,"HTTP.502",HTTP_502); | ||
| 66 | Const(T,"HTTP.503",HTTP_503); | ||
| 67 | Const(T,"HTTP.504",HTTP_504); | ||
| 68 | Const(T,"HTTP.505",HTTP_505); | ||
| 69 | } | ||
diff --git a/src/serv/direct.cc b/src/serv/direct.cc new file mode 100644 index 0000000..1e7c2d6 --- /dev/null +++ b/src/serv/direct.cc | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <serv/htcd.h> | ||
| 21 | #include <mt/dates.h> | ||
| 22 | |||
| 23 | const mstring log_cmd="\\group:\\user.id"; | ||
| 24 | |||
| 25 | TOK_IMPL(error) { | ||
| 26 | throw("htc: 'error' no longer supported"); | ||
| 27 | } | ||
| 28 | |||
| 29 | TOK_IMPL(log) { | ||
| 30 | htcd_req* htc=Reqd(env); | ||
| 31 | MLOCK(htc->htcd()->mutex); | ||
| 32 | fp_stream& tlog=htc->htcd()->errlog; | ||
| 33 | tlog<<"["<<time(0)<<"]["<<htc->tcp->node.ip<<"][" | ||
| 34 | <<htc->tcp->node.name<<":"<<htc->tcp->port<<"][" | ||
| 35 | <<htc->group<<":"<<htc->user.uid()<<"] "; | ||
| 36 | env.parg(tlog,0); | ||
| 37 | tlog<<"\n"; | ||
| 38 | tlog.flush(); | ||
| 39 | } | ||
| 40 | |||
| 41 | TOK_IMPL(output) { | ||
| 42 | env.parg(*Reqd(env)->output,0); | ||
| 43 | } | ||
| 44 | |||
| 45 | void envAddDirect(tokmap& T) | ||
| 46 | { | ||
| 47 | TOK_ADD(output,"r",tok_t::PUBLIC, | ||
| 48 | "%Redirect to output stream\n" | ||
| 49 | "%Syntax: \\output{body}\n" | ||
| 50 | "%\n" | ||
| 51 | "%Normally used on server-level, when output refers\n" | ||
| 52 | "%to a socket.\n" | ||
| 53 | ); | ||
| 54 | |||
| 55 | TOK_ADD(error,"r",tok_t::SYSONLY, | ||
| 56 | "%Redirect to error stream\n" | ||
| 57 | "%Syntax: \\error{body}\n" | ||
| 58 | "%\n" | ||
| 59 | "%Normally used for debugging and loggin of errors.\n" | ||
| 60 | ); | ||
| 61 | |||
| 62 | TOK_ADD(log,"r",tok_t::SYSONLY, | ||
| 63 | "%Message log\n" | ||
| 64 | "%Syntax: \\log{msg}\n" | ||
| 65 | "%\n" | ||
| 66 | "%Outputs to log stream a single line with pre-set information:\n" | ||
| 67 | "%\n" | ||
| 68 | "%IP address\n" | ||
| 69 | "%Time\n" | ||
| 70 | "%Request\n" | ||
| 71 | "%Response\n" | ||
| 72 | ); | ||
| 73 | } | ||
diff --git a/src/serv/form.cc b/src/serv/form.cc new file mode 100644 index 0000000..815f9c4 --- /dev/null +++ b/src/serv/form.cc | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <serv/htcd.h> | ||
| 21 | |||
| 22 | const mstring tag="T."; | ||
| 23 | const mstring ncookie_tag="ncookie"; | ||
| 24 | const mstring multipart_tag="multipart"; | ||
| 25 | const mstring body_tag="T.body"; | ||
| 26 | |||
| 27 | static mstring Tag(const sref& in) | ||
| 28 | { | ||
| 29 | mstring name=in; | ||
| 30 | for(int i=0;i<name.size();i++) if(name[i]=='_') name[i]='.'; | ||
| 31 | if(tag.empty()||tag==name.left(tag.size())) return name; | ||
| 32 | name.insert(0,tag); | ||
| 33 | return name; | ||
| 34 | } | ||
| 35 | |||
| 36 | static void AddConst(tokmap& map,const sref& s,const sref& b) throw(merror_t) | ||
| 37 | { | ||
| 38 | tok_t* p=map.get_this(s); | ||
| 39 | if(p) { | ||
| 40 | mstring nb=p->body; nb.append(1,' '); nb+=b; | ||
| 41 | Const(map,s,nb,tok_t::PUBLIC,1); | ||
| 42 | } | ||
| 43 | else Const(map,s,b,tok_t::PUBLIC); | ||
| 44 | } | ||
| 45 | |||
| 46 | static void PushMultipart(tokmap& map,const Mime& root) throw(merror_t) | ||
| 47 | { | ||
| 48 | rpile part; | ||
| 49 | if(root.Multipart(part)) { | ||
| 50 | for(int i=0;i<part.size();i++) { | ||
| 51 | Mime msg(part[i]); | ||
| 52 | if(msg.cont_disp_name.nempty()) { | ||
| 53 | mstring name=Tag(msg.cont_disp_name); | ||
| 54 | if(msg.cont_disp_file.nempty()) { | ||
| 55 | reference_t* tok=Reference(map,name,msg.cont_disp_file,tok_t::PUBLIC); | ||
| 56 | swrite via; | ||
| 57 | if(eqn(msg.cont_trans_enc,trans_base64)) | ||
| 58 | decode64(via(tok->data),msg.body); | ||
| 59 | else if(eqn(msg.cont_trans_enc,trans_quote)) | ||
| 60 | decodeQP(via(tok->data),msg.body); | ||
| 61 | else | ||
| 62 | via(tok->data)<<msg.body; | ||
| 63 | } | ||
| 64 | else AddConst(map,name,msg.body); | ||
| 65 | } | ||
| 66 | } | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | static void PushWWWForm(tokmap& map,const sref& in) throw(merror_t) | ||
| 71 | { | ||
| 72 | sspile tmp; | ||
| 73 | Unpack(tmp,in); | ||
| 74 | for(int i=0;i<tmp.size();i++) | ||
| 75 | AddConst(map,Tag(tmp[i].first),tmp[i].second); | ||
| 76 | } | ||
| 77 | |||
| 78 | void SetCookies(tokmap& map,const httpReq& req) | ||
| 79 | { | ||
| 80 | Const(map,ncookie_tag,itoa(req.cookies.size()),tok_t::PUBLIC); | ||
| 81 | int n=0; | ||
| 82 | for(sspile::const_iterator p=req.cookies.begin();p!=req.cookies.end();p++) { | ||
| 83 | mstring name,val; | ||
| 84 | name.convert("cookie%d.name",n); | ||
| 85 | val.convert("cookie%d.val",n); | ||
| 86 | Const(map,name,p->first,tok_t::PUBLIC); | ||
| 87 | Const(map,val,p->second,tok_t::PUBLIC); | ||
| 88 | n++; | ||
| 89 | } | ||
| 90 | if(req.arg.nempty()) PushWWWForm(map,req.arg); | ||
| 91 | } | ||
| 92 | |||
| 93 | void envAddForm(tokmap& map,const httpReq& req) | ||
| 94 | { | ||
| 95 | if(req.method==HTTP_POST) { | ||
| 96 | if(req.cont_type.find(multipart_tag,cset_lcase)>=0) PushMultipart(map,req); | ||
| 97 | else PushWWWForm(map,req.body); | ||
| 98 | } | ||
| 99 | else if(req.method==HTTP_PUT) { | ||
| 100 | Const(map,body_tag,req.body,tok_t::PUBLIC); | ||
| 101 | } | ||
| 102 | } | ||
diff --git a/src/serv/htcd.h b/src/serv/htcd.h new file mode 100644 index 0000000..7eaa8dc --- /dev/null +++ b/src/serv/htcd.h | |||
| @@ -0,0 +1,74 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef HTCdH | ||
| 21 | #define HTCdH | ||
| 22 | |||
| 23 | #include <serv/tempmap.h> | ||
| 24 | #include <sh/htc.h> | ||
| 25 | #include <http/http.h> | ||
| 26 | |||
| 27 | /////////////////////////////////////////////////// | ||
| 28 | |||
| 29 | struct HTCd : public HTC { | ||
| 30 | fp_stream logger,errlog; | ||
| 31 | mstring bindroot; | ||
| 32 | mutex_t mutex; | ||
| 33 | |||
| 34 | HTCd(const mstring& path); | ||
| 35 | ~HTCd(); | ||
| 36 | }; | ||
| 37 | |||
| 38 | /////////////////////////////////////////////////// | ||
| 39 | |||
| 40 | struct htcd_user : public htc_user { | ||
| 41 | htcd_user(tokmap& p,const mstring& path); | ||
| 42 | }; | ||
| 43 | |||
| 44 | /////////////////////////////////////////////////// | ||
| 45 | |||
| 46 | struct tcpReq { | ||
| 47 | IPnode node; | ||
| 48 | int port; | ||
| 49 | }; | ||
| 50 | |||
| 51 | /////////////////////////////////////////////////// | ||
| 52 | |||
| 53 | struct htcd_req : public htc_req { | ||
| 54 | mstream* output; | ||
| 55 | tcpReq* tcp; | ||
| 56 | httpReq* req; | ||
| 57 | httpResp resp; | ||
| 58 | |||
| 59 | HTCd* htcd() { return (HTCd*)glob; } | ||
| 60 | |||
| 61 | void AddBody(const sref& body); | ||
| 62 | int RootAllowed(); | ||
| 63 | |||
| 64 | htcd_req(HTCd& g,tokmap& p,mstream& out,tcpReq& trec,httpReq& hrec); | ||
| 65 | }; | ||
| 66 | |||
| 67 | inline htcd_req* Reqd(Env& env) throw(merror_t) { return (htcd_req*)env.req; } | ||
| 68 | |||
| 69 | /////////////////////////////////////////////////// | ||
| 70 | |||
| 71 | void Setup(tokmap& user,HTCd& htcd); | ||
| 72 | |||
| 73 | #endif | ||
| 74 | |||
diff --git a/src/serv/htcs.cc b/src/serv/htcs.cc new file mode 100644 index 0000000..42ac8e3 --- /dev/null +++ b/src/serv/htcs.cc | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <serv/htcd.h> | ||
| 21 | #include <hdb/buffer.h> | ||
| 22 | #include <mt/lock.h> | ||
| 23 | |||
| 24 | static fp_stream mout(stdout),merr(stderr); | ||
| 25 | const mstring left="{",right="}"; | ||
| 26 | |||
| 27 | static int unbalanced(const sref& in) | ||
| 28 | { | ||
| 29 | static const charset tag("{[("); | ||
| 30 | if(in.empty()) return 1; | ||
| 31 | sref s=in.right_first_of(tag); | ||
| 32 | while(s.nempty()) { | ||
| 33 | int p=-1; | ||
| 34 | switch(*s) { | ||
| 35 | case '{': p=s.skip(cset_braces); break; | ||
| 36 | case '[': p=s.skip(cset_indices); break; | ||
| 37 | case '(': p=s.skip(cset_para); break; | ||
| 38 | } | ||
| 39 | if(p<0) return 1; | ||
| 40 | s=s.adv(p).right_first_of(tag); | ||
| 41 | } | ||
| 42 | return 0; | ||
| 43 | } | ||
| 44 | |||
| 45 | main(int argc,char* argv[]) try | ||
| 46 | { | ||
| 47 | NODELOCK(USERMAP); | ||
| 48 | if(argc<2) THROW("Usage: "<<argv[0]<<" <docroot>"); | ||
| 49 | mstring path=argv[1]; | ||
| 50 | if(path.back()=='/') path=path.popb(); | ||
| 51 | HTCd htcd(path); | ||
| 52 | tokmap user(htcd.toks); | ||
| 53 | Setup(user,htcd); | ||
| 54 | htcd_user thr(user,path); | ||
| 55 | tcpReq tcp; tcp.port=0; | ||
| 56 | httpReq hreq; hreq.method="GET"; | ||
| 57 | htcd_req req(htcd,thr.toks,mout,tcp,hreq); | ||
| 58 | Env env(htcd.ops,req,XSYSTEM); | ||
| 59 | if(argc>2) { | ||
| 60 | for(int i=3;i<argc;i++) env.xpush(left+sref(argv[i])+right); | ||
| 61 | mstring buffer; LoadBuffer(buffer,argv[2]); | ||
| 62 | if(*buffer=='#') buffer.erase(0,buffer.find('\n')+1); | ||
| 63 | mstream m; | ||
| 64 | env.eval(m,buffer,1); | ||
| 65 | } | ||
| 66 | else { | ||
| 67 | mstring buffer,line; | ||
| 68 | while(!feof(stdin)) { | ||
| 69 | merr<<"htcd>"; | ||
| 70 | buffer.clear(); | ||
| 71 | while(!feof(stdin)&&unbalanced(buffer)) { | ||
| 72 | getline(line,stdin); | ||
| 73 | buffer.append(sref(line)); | ||
| 74 | buffer+='\n'; | ||
| 75 | } | ||
| 76 | try { | ||
| 77 | env.parse(mout,buffer); | ||
| 78 | mout<<"\n"; | ||
| 79 | } | ||
| 80 | catch(const merror_t& e) { | ||
| 81 | merr<<e.desc<<"\n"; | ||
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
| 85 | return 0; | ||
| 86 | } | ||
| 87 | catch(const merror_t& e) { | ||
| 88 | merr<<"ERROR: ["<<e.desc<<"]\n"; | ||
| 89 | return -1; | ||
| 90 | } | ||
| 91 | |||
| 92 | |||
diff --git a/src/serv/main.cc b/src/serv/main.cc new file mode 100644 index 0000000..f02f10c --- /dev/null +++ b/src/serv/main.cc | |||
| @@ -0,0 +1,122 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <serv/htcd.h> | ||
| 21 | #include <hdb/buffer.h> | ||
| 22 | |||
| 23 | const mstring RCURI="/sys/htcd.rc"; | ||
| 24 | const mstring TREEURI="/sys/sitemap.hdb"; | ||
| 25 | const mstring TEMPURI="/sys/temp.hdb"; | ||
| 26 | |||
| 27 | const mstring LOGURI="/sys/htcd.log"; | ||
| 28 | const mstring ERRURI="/sys/htcd.err"; | ||
| 29 | |||
| 30 | /////////////////////////////////////////////////// | ||
| 31 | |||
| 32 | static void OpenTREE(dbmap& db,const sref& path) | ||
| 33 | { | ||
| 34 | mstring TREEMAP=path+TREEURI; | ||
| 35 | db.Open(TREEMAP,1); | ||
| 36 | if(db.Tables()==0) for(int i=0;i<tree_tabs;i++) db.InsertTable(i,tree_tab[i]); | ||
| 37 | } | ||
| 38 | |||
| 39 | static void OpenTEMP(dbmap& db,const sref& path) | ||
| 40 | { | ||
| 41 | mstring TEMPMAP=path+TEMPURI; | ||
| 42 | db.Open(TEMPMAP,1); | ||
| 43 | if(db.Tables()==0) for(int i=0;i<temp_tabs;i++) db.InsertTable(i,temp_tab[i]); | ||
| 44 | } | ||
| 45 | |||
| 46 | htcd_user::htcd_user(tokmap& p,const mstring& path) : htc_user(p) | ||
| 47 | { | ||
| 48 | OpenTREE(DBRef(toks,TREE_tag,ms_empty,tok_t::SYSONLY)->db,path); | ||
| 49 | OpenTEMP(DBRef(toks,TEMP_tag,ms_empty,tok_t::SYSONLY)->db,path); | ||
| 50 | } | ||
| 51 | |||
| 52 | /////////////////////////////////////////////////// | ||
| 53 | |||
| 54 | void SetCookies(tokmap& map,const httpReq& req); | ||
| 55 | void envAddForm(tokmap& map,const httpReq& req); | ||
| 56 | |||
| 57 | int htcd_req::RootAllowed() | ||
| 58 | { | ||
| 59 | if(htcd()->bindroot.empty()) return 1; | ||
| 60 | sref first,rest=htcd()->bindroot; | ||
| 61 | while(Split(first,rest)) if(first==tcp->node.name) return 1; | ||
| 62 | return 0; | ||
| 63 | } | ||
| 64 | |||
| 65 | htcd_req::htcd_req(HTCd& g,tokmap& p,mstream& out, | ||
| 66 | tcpReq& trec,httpReq& hrec) : htc_req(g,p) | ||
| 67 | { | ||
| 68 | output=&out; | ||
| 69 | tcp=&trec; | ||
| 70 | req=&hrec; | ||
| 71 | SetCookies(toks,hrec); | ||
| 72 | } | ||
| 73 | |||
| 74 | void htcd_req::AddBody(const sref& body) | ||
| 75 | { | ||
| 76 | req->body=body; | ||
| 77 | envAddForm(toks,*req); | ||
| 78 | } | ||
| 79 | |||
| 80 | /////////////////////////////////////////////////// | ||
| 81 | |||
| 82 | void envAddDirect(tokmap& map); | ||
| 83 | void envAddReq(tokmap& map); | ||
| 84 | void envAddConst(tokmap& map); | ||
| 85 | void envAddAuth(tokmap& map); | ||
| 86 | void envAddTemp(tokmap& map); | ||
| 87 | |||
| 88 | HTCd::HTCd(const mstring& path): | ||
| 89 | logger(fopen((path+LOGURI).c_str(),"a+")), | ||
| 90 | errlog(fopen((path+ERRURI).c_str(),"a+")), | ||
| 91 | HTC(path) | ||
| 92 | { | ||
| 93 | envAddDirect(toks); | ||
| 94 | envAddReq(toks); | ||
| 95 | envAddConst(toks); | ||
| 96 | envAddAuth(toks); | ||
| 97 | envAddTemp(toks); | ||
| 98 | |||
| 99 | memset(&mutex,0,sizeof(mutex)); | ||
| 100 | errlog<<"["<<time(0)<<"][MAIN][HTCd started]\n"; | ||
| 101 | errlog.flush(); | ||
| 102 | } | ||
| 103 | |||
| 104 | HTCd::~HTCd() | ||
| 105 | { | ||
| 106 | fclose(errlog.fp); | ||
| 107 | fclose(logger.fp); | ||
| 108 | } | ||
| 109 | |||
| 110 | void Setup(tokmap& user,HTCd& htcd) | ||
| 111 | { | ||
| 112 | tcpReq tcp; tcp.port=0; | ||
| 113 | httpReq hreq; hreq.method="GET"; | ||
| 114 | mstream m1; | ||
| 115 | htcd_req req(htcd,htcd.toks,m1,tcp,hreq); | ||
| 116 | Env env(htcd.ops,req,XSYSTEM); | ||
| 117 | mstring buffer; | ||
| 118 | LoadBuffer(buffer,htcd.docroot+RCURI); | ||
| 119 | Env e(env,user,htcd.docroot+RCURI); | ||
| 120 | mstream m2; | ||
| 121 | e.parse(m2,buffer); | ||
| 122 | } | ||
diff --git a/src/serv/request.cc b/src/serv/request.cc new file mode 100644 index 0000000..163797f --- /dev/null +++ b/src/serv/request.cc | |||
| @@ -0,0 +1,279 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <serv/htcd.h> | ||
| 21 | |||
| 22 | TOK_IMPL(req_mime_version) { out<<Reqd(env)->req->mime_version; } | ||
| 23 | TOK_IMPL(req_cont_type) { out<<Reqd(env)->req->cont_type; } | ||
| 24 | TOK_IMPL(req_cont_type_charset) { out<<Reqd(env)->req->cont_type_charset; } | ||
| 25 | TOK_IMPL(req_cont_type_name) { out<<Reqd(env)->req->cont_type_name; } | ||
| 26 | TOK_IMPL(req_cont_type_boundary) { out<<Reqd(env)->req->cont_type_boundary; } | ||
| 27 | TOK_IMPL(req_cont_id) { out<<Reqd(env)->req->cont_id; } | ||
| 28 | TOK_IMPL(req_cont_desc) { out<<Reqd(env)->req->cont_desc; } | ||
| 29 | TOK_IMPL(req_cont_disp) { out<<Reqd(env)->req->cont_disp; } | ||
| 30 | TOK_IMPL(req_cont_disp_name) { out<<Reqd(env)->req->cont_disp_name; } | ||
| 31 | TOK_IMPL(req_cont_disp_file) { out<<Reqd(env)->req->cont_disp_file; } | ||
| 32 | TOK_IMPL(req_cont_trans_enc) { out<<Reqd(env)->req->cont_trans_enc; } | ||
| 33 | TOK_IMPL(req_cont_length) { out<<Reqd(env)->req->cont_length; } | ||
| 34 | |||
| 35 | TOK_IMPL(req_cache) { out<<Reqd(env)->req->cache; } | ||
| 36 | TOK_IMPL(req_connect) { out<<Reqd(env)->req->connect; } | ||
| 37 | TOK_IMPL(req_date) { out<<Reqd(env)->req->date; } | ||
| 38 | TOK_IMPL(req_pragma) { out<<Reqd(env)->req->pragma; } | ||
| 39 | TOK_IMPL(req_trailer) { out<<Reqd(env)->req->trailer; } | ||
| 40 | TOK_IMPL(req_trans_enc) { out<<Reqd(env)->req->trans_enc; } | ||
| 41 | TOK_IMPL(req_upgrade) { out<<Reqd(env)->req->upgrade; } | ||
| 42 | TOK_IMPL(req_via) { out<<Reqd(env)->req->via; } | ||
| 43 | TOK_IMPL(req_warning) { out<<Reqd(env)->req->warning; } | ||
| 44 | TOK_IMPL(req_allow) { out<<Reqd(env)->req->allow; } | ||
| 45 | TOK_IMPL(req_cont_enc) { out<<Reqd(env)->req->cont_enc; } | ||
| 46 | TOK_IMPL(req_cont_lang) { out<<Reqd(env)->req->cont_lang; } | ||
| 47 | TOK_IMPL(req_cont_location) { out<<Reqd(env)->req->cont_location; } | ||
| 48 | TOK_IMPL(req_cont_md5) { out<<Reqd(env)->req->cont_md5; } | ||
| 49 | TOK_IMPL(req_cont_range) { out<<Reqd(env)->req->cont_range; } | ||
| 50 | TOK_IMPL(req_expires) { out<<Reqd(env)->req->expires; } | ||
| 51 | TOK_IMPL(req_lastmod) { out<<Reqd(env)->req->lastmod; } | ||
| 52 | |||
| 53 | TOK_IMPL(req_method) { out<<Reqd(env)->req->method; } | ||
| 54 | TOK_IMPL(req_uri) { out<<Reqd(env)->req->uri; } | ||
| 55 | TOK_IMPL(req_arg) { out<<Reqd(env)->req->arg; } | ||
| 56 | TOK_IMPL(req_version) { out<<Reqd(env)->req->version; } | ||
| 57 | TOK_IMPL(req_accept) { out<<Reqd(env)->req->accept; } | ||
| 58 | TOK_IMPL(req_accept_charset) { out<<Reqd(env)->req->accept_charset; } | ||
| 59 | TOK_IMPL(req_accept_enc) { out<<Reqd(env)->req->accept_enc; } | ||
| 60 | TOK_IMPL(req_accept_lang) { out<<Reqd(env)->req->accept_lang; } | ||
| 61 | TOK_IMPL(req_accept_range) { out<<Reqd(env)->req->accept_range; } | ||
| 62 | TOK_IMPL(req_auth) { out<<Reqd(env)->req->auth; } | ||
| 63 | TOK_IMPL(req_expect) { out<<Reqd(env)->req->expect; } | ||
| 64 | TOK_IMPL(req_from) { out<<Reqd(env)->req->from; } | ||
| 65 | TOK_IMPL(req_host) { out<<Reqd(env)->req->host; } | ||
| 66 | TOK_IMPL(req_if_match) { out<<Reqd(env)->req->if_match; } | ||
| 67 | TOK_IMPL(req_if_mod) { out<<Reqd(env)->req->if_mod; } | ||
| 68 | TOK_IMPL(req_if_none) { out<<Reqd(env)->req->if_none; } | ||
| 69 | TOK_IMPL(req_if_range) { out<<Reqd(env)->req->if_range; } | ||
| 70 | TOK_IMPL(req_if_unmod) { out<<Reqd(env)->req->if_unmod; } | ||
| 71 | TOK_IMPL(req_max_forwards) { out<<Reqd(env)->req->max_forwards; } | ||
| 72 | TOK_IMPL(req_proxy) { out<<Reqd(env)->req->proxy; } | ||
| 73 | TOK_IMPL(req_range) { out<<Reqd(env)->req->range; } | ||
| 74 | TOK_IMPL(req_referer) { out<<Reqd(env)->req->referer; } | ||
| 75 | TOK_IMPL(req_te) { out<<Reqd(env)->req->te; } | ||
| 76 | TOK_IMPL(req_useragent) { out<<Reqd(env)->req->user_agent; } | ||
| 77 | |||
| 78 | /////////////////////////////////////////////////////////////////// | ||
| 79 | |||
| 80 | TOK_IMPL(resp_cookie) { | ||
| 81 | Reqd(env)->resp.set_cookies.push_back(cookie_t(env[0],env[1],env.parg(2))); | ||
| 82 | } | ||
| 83 | TOK_IMPL(resp_mime_version) { Reqd(env)->resp.mime_version=env[0]; } | ||
| 84 | TOK_IMPL(resp_cont_type) { Reqd(env)->resp.cont_type=env[0]; } | ||
| 85 | TOK_IMPL(resp_cont_type_charset) { Reqd(env)->resp.cont_type_charset=env[0]; } | ||
| 86 | TOK_IMPL(resp_cont_type_name) { Reqd(env)->resp.cont_type_name=env[0]; } | ||
| 87 | TOK_IMPL(resp_cont_type_boundary) { Reqd(env)->resp.cont_type_boundary=env[0]; } | ||
| 88 | TOK_IMPL(resp_cont_id) { Reqd(env)->resp.cont_id=env[0]; } | ||
| 89 | TOK_IMPL(resp_cont_desc) { Reqd(env)->resp.cont_desc=env[0]; } | ||
| 90 | TOK_IMPL(resp_cont_disp) { Reqd(env)->resp.cont_disp=env[0]; } | ||
| 91 | TOK_IMPL(resp_cont_disp_name) { Reqd(env)->resp.cont_disp_name=env[0]; } | ||
| 92 | TOK_IMPL(resp_cont_disp_file) { Reqd(env)->resp.cont_disp_file=env[0]; } | ||
| 93 | TOK_IMPL(resp_cont_trans_enc) { Reqd(env)->resp.cont_trans_enc=env[0]; } | ||
| 94 | TOK_IMPL(resp_cont_length) { Reqd(env)->resp.cont_length=env[0]; } | ||
| 95 | |||
| 96 | TOK_IMPL(resp_cache) { Reqd(env)->resp.cache=env[0]; } | ||
| 97 | TOK_IMPL(resp_connect) { Reqd(env)->resp.connect=env[0]; } | ||
| 98 | TOK_IMPL(resp_date) { Reqd(env)->resp.date=env[0]; } | ||
| 99 | TOK_IMPL(resp_pragma) { Reqd(env)->resp.pragma=env[0]; } | ||
| 100 | TOK_IMPL(resp_trailer) { Reqd(env)->resp.trailer=env[0]; } | ||
| 101 | TOK_IMPL(resp_trans_enc) { Reqd(env)->resp.trans_enc=env[0]; } | ||
| 102 | TOK_IMPL(resp_upgrade) { Reqd(env)->resp.upgrade=env[0]; } | ||
| 103 | TOK_IMPL(resp_via) { Reqd(env)->resp.via=env[0]; } | ||
| 104 | TOK_IMPL(resp_warning) { Reqd(env)->resp.warning=env[0]; } | ||
| 105 | TOK_IMPL(resp_allow) { Reqd(env)->resp.allow=env[0]; } | ||
| 106 | TOK_IMPL(resp_cont_enc) { Reqd(env)->resp.cont_enc=env[0]; } | ||
| 107 | TOK_IMPL(resp_cont_lang) { Reqd(env)->resp.cont_lang=env[0]; } | ||
| 108 | TOK_IMPL(resp_cont_location) { Reqd(env)->resp.cont_location=env[0]; } | ||
| 109 | TOK_IMPL(resp_cont_md5) { Reqd(env)->resp.cont_md5=env[0]; } | ||
| 110 | TOK_IMPL(resp_cont_range) { Reqd(env)->resp.cont_range=env[0]; } | ||
| 111 | TOK_IMPL(resp_expires) { Reqd(env)->resp.expires=env[0]; } | ||
| 112 | TOK_IMPL(resp_lastmod) { Reqd(env)->resp.lastmod=env[0]; } | ||
| 113 | |||
| 114 | TOK_IMPL(resp_version) { Reqd(env)->resp.version=env[0]; } | ||
| 115 | TOK_IMPL(resp_status) { Reqd(env)->resp.status=env[0]; } | ||
| 116 | TOK_IMPL(resp_age) { Reqd(env)->resp.age=env[0]; } | ||
| 117 | TOK_IMPL(resp_etag) { Reqd(env)->resp.etag=env[0]; } | ||
| 118 | TOK_IMPL(resp_location) { Reqd(env)->resp.location=env[0]; } | ||
| 119 | TOK_IMPL(resp_proxy_auth) { Reqd(env)->resp.proxy_authent=env[0]; } | ||
| 120 | TOK_IMPL(resp_retry) { Reqd(env)->resp.retry=env[0]; } | ||
| 121 | TOK_IMPL(resp_server) { Reqd(env)->resp.server=env[0]; } | ||
| 122 | TOK_IMPL(resp_vary) { Reqd(env)->resp.vary=env[0]; } | ||
| 123 | TOK_IMPL(resp_auth) { Reqd(env)->resp.authent=env[0]; } | ||
| 124 | |||
| 125 | TOK_IMPL(resp_accept) { Reqd(env)->resp.accept=env[0]; } | ||
| 126 | TOK_IMPL(resp_accept_charset) { Reqd(env)->resp.accept_charset=env[0]; } | ||
| 127 | TOK_IMPL(resp_accept_enc) { Reqd(env)->resp.accept_enc=env[0]; } | ||
| 128 | TOK_IMPL(resp_accept_lang) { Reqd(env)->resp.accept_lang=env[0]; } | ||
| 129 | TOK_IMPL(resp_accept_range) { Reqd(env)->resp.accept_range=env[0]; } | ||
| 130 | |||
| 131 | /////////////////////////////////////////////////////////////////// | ||
| 132 | |||
| 133 | TOK_IMPL(resp_getstatus) { out<<Reqd(env)->resp.status; } | ||
| 134 | |||
| 135 | /////////////////////////////////////////////////////////////////// | ||
| 136 | |||
| 137 | TOK_IMPL(andarg) { sref s=Reqd(env)->req->arg; if(s.nempty()) out.put('?')<<s; } | ||
| 138 | |||
| 139 | /////////////////////////////////////////////////////////////////// | ||
| 140 | |||
| 141 | const mstring reqhelp="%Request header entry\n"; | ||
| 142 | const mstring resphelp="%Response header entry; takes one argument\n"; | ||
| 143 | const mstring respgethelp="%Get response header entry\n"; | ||
| 144 | const mstring x_tag="x"; | ||
| 145 | |||
| 146 | void envAddReq(tokmap& T) | ||
| 147 | { | ||
| 148 | TOK_ADD(req_mime_version,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 149 | TOK_ADD(req_cont_type,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 150 | TOK_ADD(req_cont_type_charset,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 151 | TOK_ADD(req_cont_type_name,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 152 | TOK_ADD(req_cont_type_boundary,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 153 | TOK_ADD(req_cont_id,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 154 | TOK_ADD(req_cont_desc,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 155 | TOK_ADD(req_cont_disp,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 156 | TOK_ADD(req_cont_disp_name,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 157 | TOK_ADD(req_cont_disp_file,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 158 | TOK_ADD(req_cont_trans_enc,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 159 | TOK_ADD(req_cont_length,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 160 | |||
| 161 | TOK_ADD(req_cache,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 162 | TOK_ADD(req_connect,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 163 | TOK_ADD(req_date,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 164 | TOK_ADD(req_pragma,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 165 | TOK_ADD(req_trailer,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 166 | TOK_ADD(req_trans_enc,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 167 | TOK_ADD(req_upgrade,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 168 | TOK_ADD(req_via,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 169 | TOK_ADD(req_warning,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 170 | TOK_ADD(req_allow,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 171 | TOK_ADD(req_cont_enc,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 172 | TOK_ADD(req_cont_lang,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 173 | TOK_ADD(req_cont_location,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 174 | TOK_ADD(req_cont_md5,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 175 | TOK_ADD(req_cont_range,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 176 | TOK_ADD(req_expires,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 177 | TOK_ADD(req_lastmod,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 178 | |||
| 179 | TOK_ADD(req_method,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 180 | TOK_ADD(req_uri,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 181 | TOK_ADD(req_arg,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 182 | TOK_ADD(req_version,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 183 | TOK_ADD(req_accept,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 184 | TOK_ADD(req_accept_charset,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 185 | TOK_ADD(req_accept_enc,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 186 | TOK_ADD(req_accept_lang,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 187 | TOK_ADD(req_accept_range,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 188 | TOK_ADD(req_auth,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 189 | TOK_ADD(req_expect,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 190 | TOK_ADD(req_from,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 191 | TOK_ADD(req_host,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 192 | TOK_ADD(req_if_match,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 193 | TOK_ADD(req_if_mod,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 194 | TOK_ADD(req_if_none,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 195 | TOK_ADD(req_if_range,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 196 | TOK_ADD(req_if_unmod,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 197 | TOK_ADD(req_max_forwards,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 198 | TOK_ADD(req_proxy,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 199 | TOK_ADD(req_range,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 200 | TOK_ADD(req_referer,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 201 | TOK_ADD(req_te,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 202 | TOK_ADD(req_useragent,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 203 | |||
| 204 | /////////////////////////////////////////////////////////////// | ||
| 205 | |||
| 206 | TOK_ADD(andarg,ms_empty,tok_t::PUBLIC, | ||
| 207 | "%Conditional output of argument string\n" | ||
| 208 | "%Syntax: \\andarg\n" | ||
| 209 | "%\n" | ||
| 210 | "%Outputs ?\\req.arg if \\req.arg is non-empty.\n" | ||
| 211 | ); | ||
| 212 | |||
| 213 | TOK_ADD(resp_cookie,"xx?",tok_t::SYSONLY, | ||
| 214 | "%Set cookie\n" | ||
| 215 | "%Syntax: \\resp.cookie{name}{val}<options>\n" | ||
| 216 | "%\n" | ||
| 217 | "%Sets the cookie name to value val\n" | ||
| 218 | "%The options field should be on the form expected\n" | ||
| 219 | "%in the HTTP header, for instance\n" | ||
| 220 | "%domain=something; path=/; expires=http-data\n" | ||
| 221 | "%\n" | ||
| 222 | "%No newlines should be added, and remember that ; needs\n" | ||
| 223 | "%to be escaped.\n" | ||
| 224 | ); | ||
| 225 | |||
| 226 | /////////////////////////////////////////////////////////////// | ||
| 227 | |||
| 228 | TOK_ADD(resp_mime_version,x_tag,tok_t::SYSONLY,resphelp); | ||
| 229 | TOK_ADD(resp_cont_type,x_tag,tok_t::SYSONLY,resphelp); | ||
| 230 | TOK_ADD(resp_cont_type_charset,x_tag,tok_t::SYSONLY,resphelp); | ||
| 231 | TOK_ADD(resp_cont_type_name,x_tag,tok_t::SYSONLY,resphelp); | ||
| 232 | TOK_ADD(resp_cont_type_boundary,x_tag,tok_t::SYSONLY,resphelp); | ||
| 233 | TOK_ADD(resp_cont_id,x_tag,tok_t::SYSONLY,resphelp); | ||
| 234 | TOK_ADD(resp_cont_desc,x_tag,tok_t::SYSONLY,resphelp); | ||
| 235 | TOK_ADD(resp_cont_disp,x_tag,tok_t::SYSONLY,resphelp); | ||
| 236 | TOK_ADD(resp_cont_disp_name,x_tag,tok_t::SYSONLY,resphelp); | ||
| 237 | TOK_ADD(resp_cont_disp_file,x_tag,tok_t::SYSONLY,resphelp); | ||
| 238 | TOK_ADD(resp_cont_trans_enc,x_tag,tok_t::SYSONLY,resphelp); | ||
| 239 | TOK_ADD(resp_cont_length,x_tag,tok_t::SYSONLY,resphelp); | ||
| 240 | |||
| 241 | TOK_ADD(resp_cache,x_tag,tok_t::SYSONLY,resphelp); | ||
| 242 | TOK_ADD(resp_connect,x_tag,tok_t::SYSONLY,resphelp); | ||
| 243 | TOK_ADD(resp_date,x_tag,tok_t::SYSONLY,resphelp); | ||
| 244 | TOK_ADD(resp_pragma,x_tag,tok_t::SYSONLY,resphelp); | ||
| 245 | TOK_ADD(resp_trailer,x_tag,tok_t::SYSONLY,resphelp); | ||
| 246 | TOK_ADD(resp_trans_enc,x_tag,tok_t::SYSONLY,resphelp); | ||
| 247 | TOK_ADD(resp_upgrade,x_tag,tok_t::SYSONLY,resphelp); | ||
| 248 | TOK_ADD(resp_via,x_tag,tok_t::SYSONLY,resphelp); | ||
| 249 | TOK_ADD(resp_warning,x_tag,tok_t::SYSONLY,resphelp); | ||
| 250 | TOK_ADD(resp_allow,x_tag,tok_t::SYSONLY,resphelp); | ||
| 251 | TOK_ADD(resp_cont_enc,x_tag,tok_t::SYSONLY,resphelp); | ||
| 252 | TOK_ADD(resp_cont_lang,x_tag,tok_t::SYSONLY,resphelp); | ||
| 253 | TOK_ADD(resp_cont_location,x_tag,tok_t::SYSONLY,resphelp); | ||
| 254 | TOK_ADD(resp_cont_md5,x_tag,tok_t::SYSONLY,resphelp); | ||
| 255 | TOK_ADD(resp_cont_range,x_tag,tok_t::SYSONLY,resphelp); | ||
| 256 | TOK_ADD(resp_expires,x_tag,tok_t::SYSONLY,resphelp); | ||
| 257 | TOK_ADD(resp_lastmod,x_tag,tok_t::SYSONLY,resphelp); | ||
| 258 | |||
| 259 | TOK_ADD(resp_version,x_tag,tok_t::SYSONLY,resphelp); | ||
| 260 | TOK_ADD(resp_status,x_tag,tok_t::SYSONLY,resphelp); | ||
| 261 | TOK_ADD(resp_age,x_tag,tok_t::SYSONLY,resphelp); | ||
| 262 | TOK_ADD(resp_etag,x_tag,tok_t::SYSONLY,resphelp); | ||
| 263 | TOK_ADD(resp_location,x_tag,tok_t::SYSONLY,resphelp); | ||
| 264 | TOK_ADD(resp_proxy_auth,x_tag,tok_t::SYSONLY,resphelp); | ||
| 265 | TOK_ADD(resp_retry,x_tag,tok_t::SYSONLY,resphelp); | ||
| 266 | TOK_ADD(resp_server,x_tag,tok_t::SYSONLY,resphelp); | ||
| 267 | TOK_ADD(resp_vary,x_tag,tok_t::SYSONLY,resphelp); | ||
| 268 | TOK_ADD(resp_auth,x_tag,tok_t::SYSONLY,resphelp); | ||
| 269 | |||
| 270 | TOK_ADD(resp_accept,x_tag,tok_t::SYSONLY,resphelp); | ||
| 271 | TOK_ADD(resp_accept_charset,x_tag,tok_t::SYSONLY,resphelp); | ||
| 272 | TOK_ADD(resp_accept_enc,x_tag,tok_t::SYSONLY,resphelp); | ||
| 273 | TOK_ADD(resp_accept_lang,x_tag,tok_t::SYSONLY,resphelp); | ||
| 274 | TOK_ADD(resp_accept_range,x_tag,tok_t::SYSONLY,resphelp); | ||
| 275 | |||
| 276 | /////////////////////////////////////////////////////////////// | ||
| 277 | |||
| 278 | TOK_ADD(resp_getstatus,ms_empty,tok_t::PUBLIC,respgethelp); | ||
| 279 | } | ||
diff --git a/src/serv/tempmap.cc b/src/serv/tempmap.cc new file mode 100644 index 0000000..43b8732 --- /dev/null +++ b/src/serv/tempmap.cc | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <serv/htcd.h> | ||
| 21 | #include <unistd.h> | ||
| 22 | #include <fcntl.h> | ||
| 23 | #include <sys/stat.h> | ||
| 24 | |||
| 25 | const mstring TEMPDIR="/tmp/"; | ||
| 26 | |||
| 27 | inline dbmap* GetDB(Env& env) | ||
| 28 | { | ||
| 29 | dbref_t* p=(dbref_t*)env.toks->get(TEMP_tag); | ||
| 30 | if(!env.is_clear(p)||!p->is_dbref()) THROW("htc: could not find tempfile db"); | ||
| 31 | p->db.remap(); | ||
| 32 | return &p->db; | ||
| 33 | } | ||
| 34 | |||
| 35 | TOK_IMPL(tempfile) | ||
| 36 | { | ||
| 37 | mstring path=Reqd(env)->htcd()->docroot+TEMPDIR; | ||
| 38 | mstring file=Random(8),ext=env[1]; | ||
| 39 | int fd; | ||
| 40 | while((fd=open((path+file+ext).c_str(),O_CREAT|O_EXCL|O_WRONLY|O_TRUNC,0600))==-1) | ||
| 41 | file=Random(8); | ||
| 42 | close(fd); | ||
| 43 | tempmap_t temp; | ||
| 44 | temp.name()=file+ext; | ||
| 45 | temp.start()=itoa(time(0)); | ||
| 46 | temp.stop()=itoa(time(0)+atoi(env[0])); | ||
| 47 | temp.refer()=Reqd(env)->user.uid(); | ||
| 48 | dbmap* db=GetDB(env); | ||
| 49 | if(db->empty()) temp.id()=itoa(1); | ||
| 50 | else temp.id()=itoa(atoi(db->at(db->size()-1,temp_id))+1); | ||
| 51 | int row=db->Insert(temp.list,1); | ||
| 52 | if(row<0) THROW("htc: could not add tempfile - record not unique"); | ||
| 53 | out<<temp.name(); | ||
| 54 | } | ||
| 55 | |||
| 56 | TOK_IMPL(tempfile_update) | ||
| 57 | { | ||
| 58 | mstring path=Reqd(env)->htcd()->docroot+TEMPDIR; | ||
| 59 | time_t now=time(0); | ||
| 60 | dbmap* db=GetDB(env); | ||
| 61 | int n=0; | ||
| 62 | while(n<db->size()) { | ||
| 63 | if(now>atoi(db->at(n,temp_stop))) { | ||
| 64 | remove((path+db->at(n,temp_name)).c_str()); | ||
| 65 | db->Rem(n); | ||
| 66 | } | ||
| 67 | else n++; | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | void envAddTemp(tokmap& T) | ||
| 72 | { | ||
| 73 | TOK_ADD(tempfile,"xx",tok_t::SYSONLY, | ||
| 74 | "%Create a temporary file" | ||
| 75 | "%Syntax: \\tempfile{duration}{.ext}\n" | ||
| 76 | ); | ||
| 77 | TOK_ADD(tempfile_update,"",tok_t::SYSONLY, | ||
| 78 | "%Update tempfile database\n" | ||
| 79 | "%Syntax: \\tempfile_update\n" | ||
| 80 | ); | ||
| 81 | } | ||
| 82 | |||
diff --git a/src/serv/tempmap.h b/src/serv/tempmap.h new file mode 100644 index 0000000..0b9cf5a --- /dev/null +++ b/src/serv/tempmap.h | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef TEMPMAPH | ||
| 21 | #define TEMPMAPH | ||
| 22 | |||
| 23 | #include <sh/htc.h> | ||
| 24 | |||
| 25 | const mstring TEMP_tag="TEMP"; | ||
| 26 | |||
| 27 | const int temp_tabs=5,temp_id=0,temp_name=1,temp_start=2,temp_stop=3; | ||
| 28 | const mstring temp_tab[temp_tabs]={ | ||
| 29 | "ID","NAME","START","STOP","REFER" | ||
| 30 | }; | ||
| 31 | |||
| 32 | struct tempmap_t { | ||
| 33 | spile list; | ||
| 34 | |||
| 35 | tempmap_t() : list(temp_tabs) { reset(); } | ||
| 36 | |||
| 37 | mstring& id() { return list[0]; } | ||
| 38 | mstring& name() { return list[1]; } | ||
| 39 | mstring& start() { return list[2]; } | ||
| 40 | mstring& stop() { return list[3]; } | ||
| 41 | mstring& refer() { return list[4]; } | ||
| 42 | |||
| 43 | void reset() { | ||
| 44 | list.resize(temp_tabs); | ||
| 45 | id()=itoa(0); | ||
| 46 | name().clear(); | ||
| 47 | start()=itoa(0); | ||
| 48 | stop()=itoa(0); | ||
| 49 | refer()=itoa(0); | ||
| 50 | } | ||
| 51 | }; | ||
| 52 | |||
| 53 | ///////////////////////////////////////////////////////// | ||
| 54 | |||
| 55 | void envAddTemp(tokmap& T); | ||
| 56 | |||
| 57 | #endif | ||
