-rw-r--r-- | src/cgi_gateway.cc | 1 | ||||
-rw-r--r-- | src/fastcgi.cc | 1 | ||||
-rw-r--r-- | src/plaincgi.cc | 1 | ||||
-rw-r--r-- | src/util.cc | 1 |
4 files changed, 4 insertions, 0 deletions
diff --git a/src/cgi_gateway.cc b/src/cgi_gateway.cc index a2681aa..3763654 100644 --- a/src/cgi_gateway.cc +++ b/src/cgi_gateway.cc @@ -1,195 +1,196 @@ #include <errno.h> #include <ctype.h> #include <sstream> +#include <cstring> #include "kingate/cgi_gateway.h" #include "kingate/util.h" #include "kingate/exception.h" #include "config.h" #ifdef HAVE_MIMETIC # include <mimetic/mimeentity.h> # include <mimetic/parser/itparser.h> #endif /* HAVE_MIMETIC */ namespace kingate { #ifdef HAVE_MIMETIC using mimetic::MimeEntity; struct TornMimeEntity : public MimeEntity { typedef istreambuf_iterator<char> it_type; typedef it_type::iterator_category it_cat; struct IParser : public mimetic::IteratorParser<it_type,it_cat> { typedef mimetic::IteratorParser<it_type,it_cat> BT; IParser(MimeEntity& me) : BT::IteratorParser<it_type,it_cat>(me) { } void loadHeader(it_type bit,it_type eit) { m_bit = bit; m_eit = eit; BT::loadHeader(); } void loadBody(it_type bit,it_type eit) { m_bit = bit; m_eit = eit; BT::loadBody(); } }; void load(istream& hs,istream& bs,int mask=0) { IParser prs(*this); prs.iMask(mask); prs.loadHeader(it_type(hs),it_type()); prs.loadBody(it_type(bs),it_type()); } }; #endif /* HAVE_MIMETIC */ static string empty_string; cgi_gateway::basic_file_t::~basic_file_t() { } class string_file_t : public cgi_gateway::basic_file_t { public: string _file_name; string _content_type; stringstream _content; string_file_t(const string& fn,const string& ct,const string& s) : _file_name(fn), _content_type(ct), _content(s,ios::in) { } const string& filename() const { return _file_name; } const string& content_type() const { return _content_type; } istream& content() { return _content; } }; cgi_gateway::cgi_gateway(cgi_interface& ci,bool parsebody) : iface(ci), b_parsed_content(false) { // Fetch GET content try { string qs = get_meta("QUERY_STRING"); parse_query(qs,get); }catch(exception_notfound& enf) { } if(parsebody) parse_request_body(); // Parse cookies try { cookies.parse_cookies(get_meta("HTTP_COOKIE")); }catch(exception_notfound& enf) { } } cgi_gateway::~cgi_gateway() throw() { for(files_t::iterator i=files.begin();i!=files.end();++i) delete i->second; files.clear(); } void cgi_gateway::parse_request_body() { if(b_parsed_content) throw konforka::exception(CODEPOINT,"request body is already parsed"); // Fetch POST content if(!strncasecmp( content_type().c_str(), "application/x-www-form-urlencoded", sizeof("application/x-www-form-urlencoded")-1) ) { unsigned long cl = content_length(); if(cl) { char * tmp = new char[cl]; iface.in().read(tmp,cl); string qs(tmp,cl); delete tmp; parse_query(qs,post); } b_parsed_content = true; } #ifdef HAVE_MIMETIC else if(!strncasecmp( content_type().c_str(), "multipart/form-data", sizeof("multipart/form-data")-1) ) { stringstream h; h << "Content-Type: " << content_type() << "\r\n" << "Content-Length: " << content_length() << "\r\n\n"; TornMimeEntity me; me.load(h,iface.in(),0); mimetic::MimeEntityList& parts = me.body().parts(); for(mimetic::MimeEntityList::iterator i=parts.begin();i!=parts.end();++i) { MimeEntity *p = *i; const mimetic::ContentDisposition& cd = p->header().contentDisposition(); string n = cd.param("name"); string fn = cd.param("filename"); if(fn.empty()) { post.insert(params_t::value_type(n,p->body())); }else{ const mimetic::ContentType& ct = p->header().contentType(); files.insert(files_t::value_type(n,new string_file_t(fn,ct.str(),p->body()))); } } b_parsed_content = true; } #endif /* HAVE_MIMETIC */ } bool cgi_gateway::has_GET(const string& n) const { return get.find(n) != get.end(); } const string& cgi_gateway::get_GET(const string& n) const { params_t::const_iterator i = get.find(n); if(i==get.end()) throw exception_notfound(CODEPOINT,"no such parameter"); return i->second; } bool cgi_gateway::has_POST(const string& n) const { return post.find(n) != post.end(); } const string& cgi_gateway::get_POST(const string& n) const { params_t::const_iterator i = post.find(n); if(i==post.end()) throw exception_notfound(CODEPOINT,"no such parameter"); return i->second; } bool cgi_gateway::has_param(const string& n) const { return has_GET(n) || has_POST(n); } const string& cgi_gateway::get_param(const string& n) const { params_t::const_iterator i = get.find(n); if(i!=get.end()) return i->second; i = post.find(n); if(i!=post.end()) return i->second; throw exception_notfound(CODEPOINT,"no such parameter"); } bool cgi_gateway::has_file(const string& n) const { return files.find(n) != files.end(); } const cgi_gateway::file_t cgi_gateway::get_file(const string& n) const { files_t::const_iterator i = files.find(n); if(i==files.end()) throw exception_notfound(CODEPOINT,"no such parameter"); return i->second; } cgi_gateway::file_t cgi_gateway::get_file(const string& n) { files_t::const_iterator i = files.find(n); if(i==files.end()) throw exception_notfound(CODEPOINT,"no such parameter"); return i->second; } /* * deprecated stuff. */ const string& cgi_gateway::get_content_type() const { if(!has_meta("CONTENT_TYPE")) return empty_string; return get_meta("CONTENT_TYPE"); } unsigned long cgi_gateway::get_content_length() const { if(!has_meta("CONTENT_LENGTH")) return 0; string cl = get_meta("CONTENT_LENGTH"); return strtol(cl.c_str(),NULL,10); } /* * */ const string& cgi_gateway::http_request_header(const string& hn) const { string mvn = "HTTP_"; for(const char* p=hn.c_str();*p;p++) { if(*p=='-') diff --git a/src/fastcgi.cc b/src/fastcgi.cc index 8b7668c..5a6c081 100644 --- a/src/fastcgi.cc +++ b/src/fastcgi.cc @@ -1,69 +1,70 @@ #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> +#include <cstring> #include "kingate/fastcgi.h" #include "kingate/exception.h" namespace kingate { bool fcgi_socket::_initialized = false; fcgi_socket::fcgi_socket(const char *s,int bl) : sock(-1) { if(!_initialized) { if( FCGX_Init() ) throw exception(CODEPOINT,"failed to FCGX_Init()"); _initialized = true; } sock = FCGX_OpenSocket(s,bl); if(sock<0) throw exception(CODEPOINT,"failed to FCGX_OpenSocket("); // TODO: check if there is a ':', not if it starts with ':' if(*s != ':') if(chmod(s,0777)) // XXX: configurable. throw exception(CODEPOINT,"failed to chmod()"); } fcgi_socket::fcgi_socket(int s) : sock(0) { if(!_initialized) { if( FCGX_Init() ) throw exception(CODEPOINT,"failed to FCGX_Init()"); _initialized = true; } } fcgi_socket::~fcgi_socket() { if(sock>=0) close(sock); } fcgi_interface::fcgi_interface(fcgi_socket& s,int f) : sbin(buf_sbin,sizeof(buf_sbin)), sbout(buf_sbout,sizeof(buf_sbout)), sberr(buf_sberr,sizeof(buf_sberr)), sin(&sbin), sout(&sbout), serr(&sberr) { if( FCGX_InitRequest(&request,s.sock,f) ) throw exception(CODEPOINT,"failed to FCGX_InitRequest()"); if( FCGX_Accept_r(&request) ) throw exception(CODEPOINT,"failed to FCGX_Accept_r()"); sbin.attach(request.in); sbout.attach(request.out); sberr.attach(request.err); for(char **p = request.envp; *p; p++) { const char *e = strchr(*p,'='); if(!e){ // XXX: check if we have it already? metavars[*p] = string(0); }else{ int l = e-*p; e++; // XXX: check if we have it already? metavars[string(*p,l)]=e; } } } fcgi_interface::~fcgi_interface() { sout.flush(); serr.flush(); FCGX_Finish_r(&request); } } diff --git a/src/plaincgi.cc b/src/plaincgi.cc index 1cb7dc6..3a82d33 100644 --- a/src/plaincgi.cc +++ b/src/plaincgi.cc @@ -1,32 +1,33 @@ #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> +#include <cstring> #include "kingate/plaincgi.h" #include "kingate/exception.h" #include "config.h" #if !HAVE_DECL_ENVIRON extern char **environ; #endif /* HAVE_DECL_ENVIRON */ namespace kingate { plaincgi_interface::plaincgi_interface() { for(char **p = environ; *p; p++) { const char *e = strchr(*p,'='); if(!e){ // XXX: check if we have it already? metavars[*p] = string(0); }else{ int l = e-*p; e++; // XXX: check if we have it already? metavars[string(*p,l)]=e; } } } plaincgi_interface::~plaincgi_interface() { cout.flush(); cerr.flush(); } } diff --git a/src/util.cc b/src/util.cc index 48e486a..76e684f 100644 --- a/src/util.cc +++ b/src/util.cc @@ -1,106 +1,107 @@ +#include <cstring> #include "kingate/util.h" #include "kingate/exception.h" namespace kingate { static const char *safeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789" "_-" ; string url_encode(const string& str) { string rv = str; string::size_type screwed = 0; for(;;) { screwed = rv.find_first_not_of(safeChars,screwed); if(screwed == string::npos) break; while(screwed<rv.length() && !strchr(safeChars,rv.at(screwed))) { char danger = rv.at(screwed); if(danger==' ') { rv.replace(screwed++,1,1,'+'); }else{ static char tmp[4] = {'%',0,0,0}; snprintf(&tmp[1],3,"%02X",0xFF&(int)danger); rv.replace(screwed,1,tmp,3); screwed+=3; } } } return rv; } string url_decode(const string& str) { string rv = str; string::size_type unscrewed = 0; for(;;) { unscrewed = rv.find_first_of("%+",unscrewed); if(unscrewed == string::npos) break; if(rv.at(unscrewed)=='+') { rv.replace(unscrewed++,1,1,' '); }else{ if((rv.length()-unscrewed)<3) throw exception(CODEPOINT,"incorrectly escaped string"); // XXX: ensure it's hex? int danger = strtol(rv.substr(unscrewed+1,2).c_str(),NULL,16); rv.replace(unscrewed,3,1,danger); unscrewed++; } } return rv; } /* * RFC 2616: * * separators = "(" | ")" | "<" | ">" | "@" * | "," | ";" | ":" | "\" | <"> * | "/" | "[" | "]" | "?" | "=" * | "{" | "}" | SP | HT */ /* * RFC 2616: * * token = 1*<any CHAR except CTLs or separators> */ static const char *quotible_chars = "\001\002\003\004\005\006\007\010" "\011\012\013\014\015\016\017\020" "\021\022\023\024\025\026\027\030" "\031\032\033\034\035\036\037\040" "()<>@,;:\\\"/[]?={}" /* separator chars (except for SP and HT mentioned elsewhere */ "\177" ; /* * RFC 2616: * * quoted-string = ( <"> *(qdtext | quoted-pair ) <"> ) * qdtext = <any TEXT except <">> * * The backslash character ("\") MAY be used as a single-character * quoting mechanism only within quoted-string and comment constructs. * * quoted-pair = "\" CHAR */ string http_quoted_string(const string& str) { string rv = str; string::size_type sp=0; for(string::size_type q=rv.find('"');(q=rv.find('"',q))!=string::npos;q+=2) rv.insert(q,1,'\\'); rv.insert(0,1,'"'); rv += '"'; return rv; } string http_quote(const string& str) { if(str.find_first_of(quotible_chars)==string::npos) return str; return http_quoted_string(str); } } |