summaryrefslogtreecommitdiff
path: root/project2/cgi/cgiResultWritable.cpp
blob: 1364456799f125e71fae1c815d53be64a4f8c7e1 (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
#include <pch.hpp>
#include "cgiResult.h"

class WritableToCgiResult : public TransformImpl<WritableContent, CgiResult> {
	public:
		void transform(const WritableContent * wc, CgiResult * cr, ExecContext * ec) const {
			cr->header->addHeader("Content-Type", Glib::ustring::compose("%1; charset=%2", wc->getContentType(ec), cr->encoding));
			cr->header->addHeader("Cache-control", "no-cache");
			auto size = wc->getSizeInBytes(ec);
			if (size) {
				auto range = wc->getRange(ec);
				if (range) {
					cr->header->addHeader("Status", "206 Partial Content");
					cr->header->addHeader("Content-Length", Glib::ustring::compose("%1", range->End - range->Start + 1));
					cr->header->addHeader("Content-Range", Glib::ustring::compose("%1 %2-%3/%4",
								range->Unit, range->Start, range->End, *size));
				}
				else {
					cr->header->addHeader("Content-Length", Glib::ustring::compose("%1", *size));
				}
			}
			if (wc->isSeekable()) {
				cr->header->addHeader("Accept-Ranges", "bytes");
			}
			auto modifiedTime = wc->getModifiedTime(ec);
			if (modifiedTime) {
				char buf[100];
				struct tm stm;
				gmtime_r(&*modifiedTime, &stm);
				strftime(buf, sizeof(buf), "%a, %d %b %Y %T %z", &stm);
				cr->header->addHeader("Last-Modified", buf);
			}
			cr->header->render(cr->stream);
			wc->writeTo(cr->stream, cr->encoding, ec);
		}
};
DECLARE_TRANSFORM(WritableToCgiResult);