summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--src/cgi_gateway.cc3
1 files changed, 2 insertions, 1 deletions
diff --git a/src/cgi_gateway.cc b/src/cgi_gateway.cc
index 1706679..a2681aa 100644
--- a/src/cgi_gateway.cc
+++ b/src/cgi_gateway.cc
@@ -1,208 +1,209 @@
#include <errno.h>
#include <ctype.h>
#include <sstream>
#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 {
- using mimetic::MimeEntity;
#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=='-')
mvn += '_';
else
mvn += toupper(*p);
}
return get_meta(mvn);
}
const string& cgi_gateway::auth_type() const {
try {
return get_meta("AUTH_TYPE");
}catch(exception_notfound& enf) {
return empty_string;
}
}