summaryrefslogtreecommitdiffabout
path: root/src/cgi_gateway.cc
blob: eae7a03c3c900f59c35e9481428b38f73d07fa0d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#include "kingate/cgi_gateway.h"
#include "kingate/util.h"
#include "kingate/exception.h"

namespace kingate {

    cgi_gateway::cgi_gateway(cgi_interface& ci)
	: iface(ci), b_parsed_content(false) {
	    // Fetch GET content
	    if(iface.has_meta("QUERY_STRING")) {
		string qs = iface.get_meta("QUERY_STRING");
		parse_query(qs,get);
	    }
	    // Fetch POST content
	    if(!strcasecmp(get_content_type().c_str(),"application/x-www-form-urlencoded")) {
		unsigned long cl = get_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;
	    }
	}

    bool cgi_gateway::has_GET(const string& n) const {
	return get.find(n) != get.end();
    }
    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();
    }
    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);
    }
    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");
    }

    const string& cgi_gateway::get_content_type() const {
	if(!has_meta("CONTENT_TYPE"))
	    return ""; // XXX:
	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);
    }

    void cgi_gateway::parse_query(string& q,params_t& p) {
	while(!q.empty()) {
	    string::size_type amp = q.find('&');
	    string pp = (amp==string::npos)?q:q.substr(0,amp);
	    if(amp==string::npos)
		q.clear();
	    else
		q.erase(0,amp+1);
	    string::size_type eq = pp.find('=');
	    if(eq == string::npos) {
		p.insert(params_t::value_type("",url_unescape(pp)));
	    }else{
		p.insert(params_t::value_type(url_unescape(pp.substr(0,eq)),url_unescape(pp.substr(eq+1))));
	    }
	}
    }

}