summaryrefslogtreecommitdiffabout
path: root/src
Side-by-side diff
Diffstat (limited to 'src') (more/less context) (ignore whitespace changes)
-rw-r--r--src/cgi_gateway.cc1
-rw-r--r--src/fastcgi.cc1
-rw-r--r--src/plaincgi.cc1
-rw-r--r--src/util.cc1
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,99 +1,100 @@
#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
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,96 +1,97 @@
+#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 += '"';