summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--include/sitecing/sitecing_interface_cgi.h29
-rw-r--r--lib/sitecing_interface_cgi.cc34
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
@@ -15,48 +15,69 @@
15 15
16namespace sitecing { 16namespace 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
4namespace sitecing { 4namespace 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}