// Bender // // Douglas Thrift // // $Id$ #include #include #include #include #include #include #include #include #include #include class Bender { private: void bend(const cse::String& path, const cse::String& agent); void bend(const cse::String& path); void pass(const cse::String& path); public: Bender(); }; struct Environment { cse::String get(const cse::String& name) { try { return api::TheEnvironment.Get(name); } catch (ext::Exception) { return cse::String(); } } } env; int Main(const app::Options& options) { Bender bender; return 0; } Bender::Bender() { cse::String path(env.get(_B("PATH_TRANSLATED"))); api::Pcre::RegEx script(_S() << _B("^") << env.get(_B("SCRIPT_NAME"))); if (!path.IsEmpty() && script(env.get(_B("REQUEST_URI")))) { try { _S file(path); bend(path, env.get(_B("HTTP_USER_AGENT"))); } catch (ext::Exception) { api::Cout << _B("Status: 404\r\n") << _B("Content-Type: text/html; charset=ISO-8859-1\r\n\r\n") << _B("\n") << _B("\n") << _B("404 Not Found\n") << _B("\n") << _B("

Not Found

\n") << _B("

The requested URL ") << env.get(_B("PATH_INFO")) << _B(" was not found on this server.

\n") << _B("
\n") << env.get(_B("SERVER_SIGNATURE")) << _B("\n"); } } else api::Cout << _B("Location: http://computers.douglasthrift.net/bender.xml\r\n\r\n"); } void Bender::bend(const cse::String& path, const cse::String& agent) { api::Pcre::RegEx opera(_B("Opera[ /]\\d+\\.\\d+")), gecko(_B("rv:(\\d+)\\.(\\d+).*\\) Gecko")); if (opera(agent)) bend(path); else if (api::Pcre::RegEx::Match match = gecko(agent)) { int major_(lexical_cast(match[1])), minor_(lexical_cast(match[2])); if (major_ > 1 || (major_ == 1 && minor_ >= 5)) pass(path); else bend(path); } else bend(path); } void Bender::bend(const cse::String& path) { _R document(xml::Parse(_B("bender.xml"))); _R node(*document/_B("bender")); cse::String program(*node/_B("program")); _L args; _foreach (const xml::NodeSet, arg, *node/_B("argument")) args.InsertLast(**arg); args.InsertLast(path); _S xslt(program, args); _S output; ios::ReadToWrite(*xslt.GetReader(), output); if (!output.IsEmpty()) { cse::String type(_B("text/xml")); api::Pcre::RegEx content("http-equiv=\"Content-Type\" content=\"(.*)\""); if (api::Pcre::RegEx::Match match = content(output)) type = match[1]; api::Cout << "Content-Type: " << type << "\r\n\r\n" << output; } else pass(path); } void Bender::pass(const cse::String& path) { api::Cout << _B("Content-Type: text/xml\r\n\r\n"); _S file(path); ios::ReadToWrite(file, api::Cout); }