-rw-r--r-- | src/cgi_gateway.cc | 1 |
1 files changed, 1 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,131 +1,132 @@ | |||
1 | #include <errno.h> | 1 | #include <errno.h> |
2 | #include <ctype.h> | 2 | #include <ctype.h> |
3 | #include <sstream> | 3 | #include <sstream> |
4 | #include <cstring> | ||
4 | #include "kingate/cgi_gateway.h" | 5 | #include "kingate/cgi_gateway.h" |
5 | #include "kingate/util.h" | 6 | #include "kingate/util.h" |
6 | #include "kingate/exception.h" | 7 | #include "kingate/exception.h" |
7 | #include "config.h" | 8 | #include "config.h" |
8 | #ifdef HAVE_MIMETIC | 9 | #ifdef HAVE_MIMETIC |
9 | # include <mimetic/mimeentity.h> | 10 | # include <mimetic/mimeentity.h> |
10 | # include <mimetic/parser/itparser.h> | 11 | # include <mimetic/parser/itparser.h> |
11 | #endif /* HAVE_MIMETIC */ | 12 | #endif /* HAVE_MIMETIC */ |
12 | 13 | ||
13 | namespace kingate { | 14 | namespace kingate { |
14 | 15 | ||
15 | #ifdef HAVE_MIMETIC | 16 | #ifdef HAVE_MIMETIC |
16 | using mimetic::MimeEntity; | 17 | using mimetic::MimeEntity; |
17 | 18 | ||
18 | struct TornMimeEntity : public MimeEntity { | 19 | struct TornMimeEntity : public MimeEntity { |
19 | typedef istreambuf_iterator<char> it_type; | 20 | typedef istreambuf_iterator<char> it_type; |
20 | typedef it_type::iterator_category it_cat; | 21 | typedef it_type::iterator_category it_cat; |
21 | struct IParser : public mimetic::IteratorParser<it_type,it_cat> { | 22 | struct IParser : public mimetic::IteratorParser<it_type,it_cat> { |
22 | typedef mimetic::IteratorParser<it_type,it_cat> BT; | 23 | typedef mimetic::IteratorParser<it_type,it_cat> BT; |
23 | IParser(MimeEntity& me) | 24 | IParser(MimeEntity& me) |
24 | : BT::IteratorParser<it_type,it_cat>(me) { } | 25 | : BT::IteratorParser<it_type,it_cat>(me) { } |
25 | void loadHeader(it_type bit,it_type eit) { | 26 | void loadHeader(it_type bit,it_type eit) { |
26 | m_bit = bit; m_eit = eit; | 27 | m_bit = bit; m_eit = eit; |
27 | BT::loadHeader(); | 28 | BT::loadHeader(); |
28 | } | 29 | } |
29 | void loadBody(it_type bit,it_type eit) { | 30 | void loadBody(it_type bit,it_type eit) { |
30 | m_bit = bit; m_eit = eit; | 31 | m_bit = bit; m_eit = eit; |
31 | BT::loadBody(); | 32 | BT::loadBody(); |
32 | } | 33 | } |
33 | }; | 34 | }; |
34 | void load(istream& hs,istream& bs,int mask=0) { | 35 | void load(istream& hs,istream& bs,int mask=0) { |
35 | IParser prs(*this); | 36 | IParser prs(*this); |
36 | prs.iMask(mask); | 37 | prs.iMask(mask); |
37 | prs.loadHeader(it_type(hs),it_type()); | 38 | prs.loadHeader(it_type(hs),it_type()); |
38 | prs.loadBody(it_type(bs),it_type()); | 39 | prs.loadBody(it_type(bs),it_type()); |
39 | } | 40 | } |
40 | }; | 41 | }; |
41 | #endif /* HAVE_MIMETIC */ | 42 | #endif /* HAVE_MIMETIC */ |
42 | 43 | ||
43 | static string empty_string; | 44 | static string empty_string; |
44 | 45 | ||
45 | cgi_gateway::basic_file_t::~basic_file_t() { } | 46 | cgi_gateway::basic_file_t::~basic_file_t() { } |
46 | 47 | ||
47 | class string_file_t : public cgi_gateway::basic_file_t { | 48 | class string_file_t : public cgi_gateway::basic_file_t { |
48 | public: | 49 | public: |
49 | string _file_name; | 50 | string _file_name; |
50 | string _content_type; | 51 | string _content_type; |
51 | stringstream _content; | 52 | stringstream _content; |
52 | 53 | ||
53 | string_file_t(const string& fn,const string& ct,const string& s) | 54 | string_file_t(const string& fn,const string& ct,const string& s) |
54 | : _file_name(fn), _content_type(ct), _content(s,ios::in) { } | 55 | : _file_name(fn), _content_type(ct), _content(s,ios::in) { } |
55 | const string& filename() const { return _file_name; } | 56 | const string& filename() const { return _file_name; } |
56 | const string& content_type() const { return _content_type; } | 57 | const string& content_type() const { return _content_type; } |
57 | istream& content() { return _content; } | 58 | istream& content() { return _content; } |
58 | }; | 59 | }; |
59 | 60 | ||
60 | cgi_gateway::cgi_gateway(cgi_interface& ci,bool parsebody) | 61 | cgi_gateway::cgi_gateway(cgi_interface& ci,bool parsebody) |
61 | : iface(ci), b_parsed_content(false) { | 62 | : iface(ci), b_parsed_content(false) { |
62 | // Fetch GET content | 63 | // Fetch GET content |
63 | try { | 64 | try { |
64 | string qs = get_meta("QUERY_STRING"); | 65 | string qs = get_meta("QUERY_STRING"); |
65 | parse_query(qs,get); | 66 | parse_query(qs,get); |
66 | }catch(exception_notfound& enf) { } | 67 | }catch(exception_notfound& enf) { } |
67 | if(parsebody) | 68 | if(parsebody) |
68 | parse_request_body(); | 69 | parse_request_body(); |
69 | // Parse cookies | 70 | // Parse cookies |
70 | try { | 71 | try { |
71 | cookies.parse_cookies(get_meta("HTTP_COOKIE")); | 72 | cookies.parse_cookies(get_meta("HTTP_COOKIE")); |
72 | }catch(exception_notfound& enf) { } | 73 | }catch(exception_notfound& enf) { } |
73 | } | 74 | } |
74 | 75 | ||
75 | cgi_gateway::~cgi_gateway() throw() { | 76 | cgi_gateway::~cgi_gateway() throw() { |
76 | for(files_t::iterator i=files.begin();i!=files.end();++i) | 77 | for(files_t::iterator i=files.begin();i!=files.end();++i) |
77 | delete i->second; | 78 | delete i->second; |
78 | files.clear(); | 79 | files.clear(); |
79 | } | 80 | } |
80 | 81 | ||
81 | void cgi_gateway::parse_request_body() { | 82 | void cgi_gateway::parse_request_body() { |
82 | if(b_parsed_content) | 83 | if(b_parsed_content) |
83 | throw konforka::exception(CODEPOINT,"request body is already parsed"); | 84 | throw konforka::exception(CODEPOINT,"request body is already parsed"); |
84 | // Fetch POST content | 85 | // Fetch POST content |
85 | if(!strncasecmp( | 86 | if(!strncasecmp( |
86 | content_type().c_str(), | 87 | content_type().c_str(), |
87 | "application/x-www-form-urlencoded", | 88 | "application/x-www-form-urlencoded", |
88 | sizeof("application/x-www-form-urlencoded")-1) ) { | 89 | sizeof("application/x-www-form-urlencoded")-1) ) { |
89 | unsigned long cl = content_length(); | 90 | unsigned long cl = content_length(); |
90 | if(cl) { | 91 | if(cl) { |
91 | char * tmp = new char[cl]; | 92 | char * tmp = new char[cl]; |
92 | iface.in().read(tmp,cl); | 93 | iface.in().read(tmp,cl); |
93 | string qs(tmp,cl); | 94 | string qs(tmp,cl); |
94 | delete tmp; | 95 | delete tmp; |
95 | parse_query(qs,post); | 96 | parse_query(qs,post); |
96 | } | 97 | } |
97 | b_parsed_content = true; | 98 | b_parsed_content = true; |
98 | } | 99 | } |
99 | #ifdef HAVE_MIMETIC | 100 | #ifdef HAVE_MIMETIC |
100 | else if(!strncasecmp( | 101 | else if(!strncasecmp( |
101 | content_type().c_str(), | 102 | content_type().c_str(), |
102 | "multipart/form-data", | 103 | "multipart/form-data", |
103 | sizeof("multipart/form-data")-1) ) { | 104 | sizeof("multipart/form-data")-1) ) { |
104 | stringstream h; | 105 | stringstream h; |
105 | h | 106 | h |
106 | << "Content-Type: " << content_type() << "\r\n" | 107 | << "Content-Type: " << content_type() << "\r\n" |
107 | << "Content-Length: " << content_length() << "\r\n\n"; | 108 | << "Content-Length: " << content_length() << "\r\n\n"; |
108 | TornMimeEntity me; | 109 | TornMimeEntity me; |
109 | me.load(h,iface.in(),0); | 110 | me.load(h,iface.in(),0); |
110 | mimetic::MimeEntityList& parts = me.body().parts(); | 111 | mimetic::MimeEntityList& parts = me.body().parts(); |
111 | for(mimetic::MimeEntityList::iterator i=parts.begin();i!=parts.end();++i) { | 112 | for(mimetic::MimeEntityList::iterator i=parts.begin();i!=parts.end();++i) { |
112 | MimeEntity *p = *i; | 113 | MimeEntity *p = *i; |
113 | const mimetic::ContentDisposition& cd = p->header().contentDisposition(); | 114 | const mimetic::ContentDisposition& cd = p->header().contentDisposition(); |
114 | string n = cd.param("name"); | 115 | string n = cd.param("name"); |
115 | string fn = cd.param("filename"); | 116 | string fn = cd.param("filename"); |
116 | if(fn.empty()) { | 117 | if(fn.empty()) { |
117 | post.insert(params_t::value_type(n,p->body())); | 118 | post.insert(params_t::value_type(n,p->body())); |
118 | }else{ | 119 | }else{ |
119 | const mimetic::ContentType& ct = p->header().contentType(); | 120 | const mimetic::ContentType& ct = p->header().contentType(); |
120 | files.insert(files_t::value_type(n,new string_file_t(fn,ct.str(),p->body()))); | 121 | files.insert(files_t::value_type(n,new string_file_t(fn,ct.str(),p->body()))); |
121 | } | 122 | } |
122 | } | 123 | } |
123 | b_parsed_content = true; | 124 | b_parsed_content = true; |
124 | } | 125 | } |
125 | #endif /* HAVE_MIMETIC */ | 126 | #endif /* HAVE_MIMETIC */ |
126 | } | 127 | } |
127 | 128 | ||
128 | bool cgi_gateway::has_GET(const string& n) const { | 129 | bool cgi_gateway::has_GET(const string& n) const { |
129 | return get.find(n) != get.end(); | 130 | return get.find(n) != get.end(); |
130 | } | 131 | } |
131 | const string& cgi_gateway::get_GET(const string& n) const { | 132 | const string& cgi_gateway::get_GET(const string& n) const { |