From fafb98623457b4b29bbe3a32af19e901d92106dc Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 5 Jul 2013 13:43:06 +0200 Subject: [PATCH] Honor within type="quoted-literal" --- src/filter_http_rewrite.cpp | 146 ++++++++++++++++++++++++++----------------- src/filter_http_rewrite.hpp | 4 +- src/test_filter_rewrite.cpp | 10 ++- 3 files changed, 96 insertions(+), 64 deletions(-) diff --git a/src/filter_http_rewrite.cpp b/src/filter_http_rewrite.cpp index 501c87e..80a876a 100644 --- a/src/filter_http_rewrite.cpp +++ b/src/filter_http_rewrite.cpp @@ -62,8 +62,11 @@ namespace metaproxy_1 { std::string header; std::string attr; std::string tag; + std::string type; bool reqline; RulePtr rule; + bool exec(std::map &vars, + std::string &txt, bool anchor) const; }; class HttpRewrite::Content { @@ -198,7 +201,7 @@ void yf::HttpRewrite::Phase::rewrite_reqline (mp::odr & o, if (it->reqline) { yaz_log(YLOG_LOG, "Proxy request URL is %s", path.c_str()); - if (it->rule->test_patterns(vars, path, true)) + if (it->exec(vars, path, true)) { yaz_log(YLOG_LOG, "Rewritten request URL is %s", path.c_str()); hreq->path = odr_strdup(o, path.c_str()); @@ -230,7 +233,7 @@ void yf::HttpRewrite::Phase::rewrite_headers(mp::odr & o, sheader += ": "; sheader += header->value; - if (it->rule->test_patterns(vars, sheader, true)) + if (it->exec(vars, sheader, true)) { size_t pos = sheader.find(": "); if (pos == std::string::npos) @@ -255,6 +258,8 @@ void yf::HttpRewrite::Phase::rewrite_body( int *content_len, std::map & vars) const { + if (*content_len == 0) + return; std::list::const_iterator cit = content_list.begin(); for (; cit != content_list.end(); cit++) { @@ -267,18 +272,15 @@ void yf::HttpRewrite::Phase::rewrite_body( if (cit == content_list.end()) return; - if (*content_buf) - { - int i; - for (i = 0; i < *content_len; i++) - if ((*content_buf)[i] == 0) - return; // binary content. skip - - std::string content(*content_buf, *content_len); - cit->parse(m_verbose, content, vars); - *content_buf = odr_strdup(o, content.c_str()); - *content_len = strlen(*content_buf); - } + int i; + for (i = 0; i < *content_len; i++) + if ((*content_buf)[i] == 0) + return; // binary content. skip + + std::string content(*content_buf, *content_len); + cit->parse(m_verbose, content, vars); + *content_buf = odr_strdup(o, content.c_str()); + *content_len = strlen(*content_buf); } yf::HttpRewrite::Event::Event(const Content *p, @@ -383,7 +385,7 @@ void yf::HttpRewrite::Event::attribute(const char *tag, int tag_len, if (subst) { std::string s(value, val_len); - it->rule->test_patterns(m_vars, s, true); + it->exec(m_vars, s, true); wrbuf_puts(m_w, s.c_str()); } else @@ -413,13 +415,72 @@ void yf::HttpRewrite::Event::text(const char *value, int len) if (it != m_content->within_list.end()) { std::string s(value, len); - it->rule->test_patterns(m_vars, s, false); + it->exec(m_vars, s, false); wrbuf_puts(m_w, s.c_str()); } else wrbuf_write(m_w, value, len); } +static bool embed_quoted_literal( + std::string &content, + std::map &vars, + mp::filter::HttpRewrite::RulePtr ruleptr) +{ + bool replace = false; + std::string res; + const char *cp = content.c_str(); + const char *cp0 = cp; + while (*cp) + { + if (*cp == '"' || *cp == '\'') + { + int m = *cp; + cp++; + res.append(cp0, cp - cp0); + cp0 = cp; + while (*cp) + { + if (cp[-1] != '\\' && *cp == m) + break; + if (*cp == '\n') + break; + cp++; + } + if (!*cp) + break; + std::string s(cp0, cp - cp0); + if (ruleptr->test_patterns(vars, s, true)) + replace = true; + cp0 = cp; + res.append(s); + } + else if (*cp == '/' && cp[1] == '/') + { + while (cp[1] && cp[1] != '\n') + cp++; + } + cp++; + } + res.append(cp0, cp - cp0); + content = res; + return replace; +} + +bool yf::HttpRewrite::Within::exec( + std::map & vars, + std::string & txt, bool anchor) const +{ + if (type == "quoted-literal") + { + return embed_quoted_literal(txt, vars, rule); + } + else + { + return rule->test_patterns(vars, txt, anchor); + } +} + bool yf::HttpRewrite::Rule::test_patterns( std::map & vars, std::string & txt, bool anchor) @@ -622,43 +683,9 @@ void yf::HttpRewrite::Content::quoted_literal( std::string &content, std::map &vars) const { - std::string res; - const char *cp = content.c_str(); - const char *cp0 = cp; - while (*cp) - { - if (*cp == '"' || *cp == '\'') - { - int m = *cp; - cp++; - res.append(cp0, cp - cp0); - cp0 = cp; - while (*cp) - { - if (cp[-1] != '\\' && *cp == m) - break; - if (*cp == '\n') - break; - cp++; - } - if (!*cp) - break; - std::list::const_iterator it = within_list.begin(); - std::string s(cp0, cp - cp0); - if (it != within_list.end()) - it->rule->test_patterns(vars, s, true); - cp0 = cp; - res.append(s); - } - else if (*cp == '/' && cp[1] == '/') - { - while (cp[1] && cp[1] != '\n') - cp++; - } - cp++; - } - res.append(cp0, cp - cp0); - content = res; + std::list::const_iterator it = within_list.begin(); + if (it != within_list.end()) + embed_quoted_literal(content, vars, it->rule); } void yf::HttpRewrite::Content::configure( @@ -670,9 +697,9 @@ void yf::HttpRewrite::Content::configure( continue; if (!strcmp((const char *) ptr->name, "within")) { - static const char *names[6] = - { "header", "attr", "tag", "rule", "reqline", 0 }; - std::string values[5]; + static const char *names[7] = + { "header", "attr", "tag", "rule", "reqline", "type", 0 }; + std::string values[6]; mp::xml::parse_attr(ptr, names, values); Within w; w.header = values[0]; @@ -686,6 +713,13 @@ void yf::HttpRewrite::Content::configure( "' in http_rewrite filter"); w.rule = it->second; w.reqline = values[4] == "1"; + w.type = values[5]; + if (w.type.empty() || w.type == "quoted-literal") + ; + else + throw mp::filter::FilterException + ("within type must be quoted-literal or none in " + " in http_rewrite filter"); within_list.push_back(w); } } diff --git a/src/filter_http_rewrite.hpp b/src/filter_http_rewrite.hpp index 85a66a2..bbff492 100644 --- a/src/filter_http_rewrite.hpp +++ b/src/filter_http_rewrite.hpp @@ -31,14 +31,14 @@ namespace metaproxy_1 { class Phase; class Content; class Replace; - class Rule; class Within; class Event; - typedef boost::shared_ptr RulePtr; boost::scoped_ptr req_phase; boost::scoped_ptr res_phase; void configure_phase(const xmlNode *ptr, Phase &phase); public: + class Rule; + typedef boost::shared_ptr RulePtr; HttpRewrite(); ~HttpRewrite(); void process(metaproxy_1::Package & package) const; diff --git a/src/test_filter_rewrite.cpp b/src/test_filter_rewrite.cpp index 00065a4..f26feae 100644 --- a/src/test_filter_rewrite.cpp +++ b/src/test_filter_rewrite.cpp @@ -80,7 +80,7 @@ BOOST_AUTO_TEST_CASE( test_filter_rewrite_1 ) " \n" " \n" " \n" - " \n" + " \n" " \n" " \n" " \n" @@ -115,7 +115,6 @@ BOOST_AUTO_TEST_CASE( test_filter_rewrite_1 ) const char *resp_buf = "HTTP/1.1 200 OK\r\n" - "Content-Length: 441\r\n" "Content-Type: text/html\r\n" "Link: ; rel=absolute\r\n" "Link: ; rel=relative\r\n" @@ -128,7 +127,7 @@ BOOST_AUTO_TEST_CASE( test_filter_rewrite_1 ) "" "" "" "" "

Welcome to our website. It doesn't make it easy to get pro" @@ -144,7 +143,7 @@ BOOST_AUTO_TEST_CASE( test_filter_rewrite_1 ) const char *resp_expected = "HTTP/1.1 200 OK\r\n" - "Content-Length: 564\r\n" + "Content-Length: 573\r\n" "Content-Type: text/html\r\n" "Link: ; rel=absolute\r\n" "Link: ; rel=relative\r\n" @@ -157,7 +156,7 @@ BOOST_AUTO_TEST_CASE( test_filter_rewrite_1 ) "" "" "" "" "

Welcome to our website. It doesn't make it easy to get pro" @@ -301,7 +300,6 @@ BOOST_AUTO_TEST_CASE( test_filter_rewrite_2 ) const char *resp_buf = "HTTP/1.1 200 OK\r\n" - "Content-Length: 140\r\n" "Content-Type: application/javascript\r\n" "Link: ; rel=absolute\r\n" "Link: ; rel=relative\r\n" -- 1.7.10.4