+
+shared_ptr<const dcp::Signer>
+make_signer ()
+{
+ boost::filesystem::path const sd = Config::instance()->signer_chain_directory ();
+
+ /* Remake the chain if any of it is missing */
+
+ list<boost::filesystem::path> files;
+ files.push_back ("ca.self-signed.pem");
+ files.push_back ("intermediate.signed.pem");
+ files.push_back ("leaf.signed.pem");
+ files.push_back ("leaf.key");
+
+ list<boost::filesystem::path>::const_iterator i = files.begin();
+ while (i != files.end()) {
+ boost::filesystem::path p (sd);
+ p /= *i;
+ if (!boost::filesystem::exists (p)) {
+ boost::filesystem::remove_all (sd);
+ boost::filesystem::create_directories (sd);
+ dcp::make_signer_chain (sd, openssl_path ());
+ break;
+ }
+
+ ++i;
+ }
+
+ dcp::CertificateChain chain;
+
+ {
+ boost::filesystem::path p (sd);
+ p /= "ca.self-signed.pem";
+ chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (p)));
+ }
+
+ {
+ boost::filesystem::path p (sd);
+ p /= "intermediate.signed.pem";
+ chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (p)));
+ }
+
+ {
+ boost::filesystem::path p (sd);
+ p /= "leaf.signed.pem";
+ chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (p)));
+ }
+
+ boost::filesystem::path signer_key (sd);
+ signer_key /= "leaf.key";
+
+ return shared_ptr<const dcp::Signer> (new dcp::Signer (chain, signer_key));
+}
+
+map<string, string>
+split_get_request (string url)
+{
+ enum {
+ AWAITING_QUESTION_MARK,
+ KEY,
+ VALUE
+ } state = AWAITING_QUESTION_MARK;
+
+ map<string, string> r;
+ string k;
+ string v;
+ for (size_t i = 0; i < url.length(); ++i) {
+ switch (state) {
+ case AWAITING_QUESTION_MARK:
+ if (url[i] == '?') {
+ state = KEY;
+ }
+ break;
+ case KEY:
+ if (url[i] == '=') {
+ v.clear ();
+ state = VALUE;
+ } else {
+ k += url[i];
+ }
+ break;
+ case VALUE:
+ if (url[i] == '&') {
+ r.insert (make_pair (k, v));
+ k.clear ();
+ state = KEY;
+ } else {
+ v += url[i];
+ }
+ break;
+ }
+ }
+
+ if (state == VALUE) {
+ r.insert (make_pair (k, v));
+ }
+
+ return r;
+}
+
+dcp::Size
+fit_ratio_within (float ratio, dcp::Size full_frame)
+{
+ if (ratio < full_frame.ratio ()) {
+ return dcp::Size (rint (full_frame.height * ratio), full_frame.height);
+ }