-rw-r--r-- | include/sitecing/sitecing_interface_cgi.h | 29 | ||||
-rw-r--r-- | lib/sitecing_interface_cgi.cc | 34 |
2 files changed, 55 insertions, 8 deletions
diff --git a/include/sitecing/sitecing_interface_cgi.h b/include/sitecing/sitecing_interface_cgi.h index cab947c..da538d6 100644 --- a/include/sitecing/sitecing_interface_cgi.h +++ b/include/sitecing/sitecing_interface_cgi.h | |||
@@ -1,62 +1,83 @@ | |||
1 | #ifndef __SITECING_SITECING_INTERFACE_CGI_H | 1 | #ifndef __SITECING_SITECING_INTERFACE_CGI_H |
2 | #define __SITECING_SITECING_INTERFACE_CGI_H | 2 | #define __SITECING_SITECING_INTERFACE_CGI_H |
3 | 3 | ||
4 | #include <sstream> | 4 | #include <sstream> |
5 | #include <string> | 5 | #include <string> |
6 | #include <map> | 6 | #include <map> |
7 | #include "kingate/cgi_gateway.h" | 7 | #include "kingate/cgi_gateway.h" |
8 | #include "sitecing/sitecing_interface.h" | 8 | #include "sitecing/sitecing_interface.h" |
9 | #include "sitecing/sitespace.h" | 9 | #include "sitecing/sitespace.h" |
10 | 10 | ||
11 | /** | 11 | /** |
12 | * @file | 12 | * @file |
13 | * @brief The sitecing_interface_cgi class declaration. | 13 | * @brief The sitecing_interface_cgi class declaration. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | namespace sitecing { | 16 | namespace sitecing { |
17 | using namespace std; | 17 | using namespace std; |
18 | 18 | ||
19 | /** | 19 | /** |
20 | * The interface to site-C-ing core for the CGI component. | 20 | * The interface to site-C-ing core for the CGI component. |
21 | */ | 21 | */ |
22 | class sitecing_interface_cgi : public sitecing_interface { | 22 | class sitecing_interface_cgi : public sitecing_interface { |
23 | public: | 23 | public: |
24 | /** | 24 | /** |
25 | * Pointer to the CGI gateway interface. | 25 | * Pointer to the CGI gateway interface. |
26 | */ | 26 | */ |
27 | kingate::cgi_gateway* cgigw; | 27 | kingate::cgi_gateway* cgigw; |
28 | /** | 28 | /** |
29 | * Type for the map of headers to spit out. | 29 | * Type for the map of headers to spit out. |
30 | */ | 30 | */ |
31 | typedef map<string,string> headers_t; | 31 | typedef map<string,string> headers_t; |
32 | /** | 32 | /** |
33 | * The list of headers to spit out. | 33 | * The list of headers to spit out. |
34 | */ | 34 | */ |
35 | headers_t headers; | 35 | headers_t headers; |
36 | /** | 36 | /** |
37 | * Here is where we prebuffer output. | 37 | * Here is where we prebuffer output. |
38 | */ | 38 | */ |
39 | ostringstream prebuffer; | 39 | stringbuf prebuffer; |
40 | /** | ||
41 | * Output stream, initially going to prebuffer. | ||
42 | */ | ||
43 | ostream outs; | ||
44 | /** | ||
45 | * Have headers been sent yet? | ||
46 | */ | ||
47 | bool headers_flushed; | ||
40 | /** | 48 | /** |
41 | * Pointer to the sitespace object. | 49 | * Pointer to the sitespace object. |
42 | */ | 50 | */ |
43 | sitespace *ss; // XXX: or does it belong to the generic interface? or should this 'generic' interface exist at all? | 51 | sitespace *ss; // XXX: or does it belong to the generic interface? or should this 'generic' interface exist at all? |
44 | 52 | ||
45 | /** | 53 | /** |
46 | * @param s Pointer to the sitespace object. | 54 | * @param s Pointer to the sitespace object. |
47 | */ | 55 | */ |
48 | sitecing_interface_cgi(sitespace *s); | 56 | sitecing_interface_cgi(sitespace *s); |
49 | 57 | ||
50 | /** | 58 | /** |
51 | * @todo TODO: wish I could remember -- document me. | 59 | * Set up interface for the (possibly, new) cgi gateway object, |
60 | * reset headers, empty buffer, etc. | ||
52 | */ | 61 | */ |
53 | void prepare(kingate::cgi_gateway *cg); | 62 | void prepare(kingate::cgi_gateway *cg); |
54 | /** | 63 | /** |
55 | * @todo TODO: wish I could remember -- document me. | 64 | * Flush output stream. |
65 | */ | ||
66 | void flush(bool keep_buffering=false); | ||
67 | /** | ||
68 | * Send headers to the output stream, if we haven't yet. | ||
69 | */ | ||
70 | void flush_headers(); | ||
71 | /** | ||
72 | * Are we buffering now? | ||
73 | */ | ||
74 | bool is_buffering(); | ||
75 | /** | ||
76 | * Control output buffering. | ||
56 | */ | 77 | */ |
57 | void flush(); | 78 | void set_buffering(bool do_buffer); |
58 | 79 | ||
59 | }; | 80 | }; |
60 | } | 81 | } |
61 | 82 | ||
62 | #endif /* __SITECING_SITECING_INTERFACE_CGI_H */ | 83 | #endif /* __SITECING_SITECING_INTERFACE_CGI_H */ |
diff --git a/lib/sitecing_interface_cgi.cc b/lib/sitecing_interface_cgi.cc index 5c3d295..f2bd093 100644 --- a/lib/sitecing_interface_cgi.cc +++ b/lib/sitecing_interface_cgi.cc | |||
@@ -1,25 +1,51 @@ | |||
1 | #include <cassert> | 1 | #include <cassert> |
2 | #include "sitecing/sitecing_interface_cgi.h" | 2 | #include "sitecing/sitecing_interface_cgi.h" |
3 | 3 | ||
4 | namespace sitecing { | 4 | namespace sitecing { |
5 | 5 | ||
6 | sitecing_interface_cgi::sitecing_interface_cgi(sitespace *s) | 6 | sitecing_interface_cgi::sitecing_interface_cgi(sitespace *s) |
7 | : sitecing_interface(&prebuffer), ss(s), cgigw(NULL) { | 7 | : outs(&prebuffer), sitecing_interface(&outs), ss(s), cgigw(NULL), headers_flushed(false) { |
8 | } | 8 | } |
9 | 9 | ||
10 | void sitecing_interface_cgi::prepare(kingate::cgi_gateway *cg) { | 10 | void sitecing_interface_cgi::prepare(kingate::cgi_gateway *cg) { |
11 | cgigw = cg; | 11 | cgigw = cg; |
12 | headers.clear(); | 12 | headers.clear(); |
13 | headers["Content-Type"] = "text/html"; | 13 | headers["Content-Type"] = "text/html"; |
14 | prebuffer.str(""); | 14 | prebuffer.str(""); |
15 | headers_flushed = false; | ||
16 | set_buffering(true); | ||
15 | } | 17 | } |
16 | 18 | ||
17 | void sitecing_interface_cgi::flush() { | 19 | void sitecing_interface_cgi::flush(bool keep_buffering) { |
18 | assert(cgigw); | 20 | assert(cgigw); |
21 | flush_headers(); | ||
22 | if(is_buffering()) { | ||
23 | streampos count = prebuffer.pubseekoff(0,ios_base::cur,ios_base::out); | ||
24 | cgigw->out().write(prebuffer.str().c_str(),count); | ||
25 | prebuffer.str(""); | ||
26 | } | ||
27 | cgigw->out().flush(); | ||
28 | set_buffering(keep_buffering); | ||
29 | } | ||
30 | |||
31 | void sitecing_interface_cgi::set_buffering(bool do_buffer) { | ||
32 | if(!do_buffer) | ||
33 | flush_headers(); | ||
34 | outs.rdbuf(do_buffer?&prebuffer:cgigw->out().rdbuf()); | ||
35 | } | ||
36 | |||
37 | bool sitecing_interface_cgi::is_buffering() { | ||
38 | return outs.rdbuf()==&prebuffer; | ||
39 | } | ||
40 | |||
41 | void sitecing_interface_cgi::flush_headers() { | ||
42 | assert(cgigw); | ||
43 | if(headers_flushed) | ||
44 | return; | ||
19 | for(headers_t::const_iterator i=headers.begin();i!=headers.end();i++) | 45 | for(headers_t::const_iterator i=headers.begin();i!=headers.end();i++) |
20 | cgigw->out() << i->first << ": " << i->second << "\n"; | 46 | cgigw->out() << i->first << ": " << i->second << "\n"; |
21 | (cgigw->out() << "\n").write(prebuffer.str().c_str(),prebuffer.tellp()); | 47 | cgigw->out() << "\n"; |
22 | cgigw->out().flush(); | 48 | headers_flushed = true; |
23 | } | 49 | } |
24 | 50 | ||
25 | } | 51 | } |