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
@@ -36,7 +36,15 @@ namespace sitecing {
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 */
@@ -48,13 +56,26 @@ namespace sitecing {
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}
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
@@ -4,7 +4,7 @@
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) {
@@ -12,14 +12,40 @@ namespace sitecing {
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}