X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Ffilter_http_rewrite.cpp;h=0f7ea87da4486538cc4f2a24547df7b0fec6b31f;hb=55fdfbb42225f71fb791bb8f9ec033ca0fddbe44;hp=80a876a86620e3a88f6ad9d4dffdd2fd75c0f103;hpb=fafb98623457b4b29bbe3a32af19e901d92106dc;p=metaproxy-moved-to-github.git diff --git a/src/filter_http_rewrite.cpp b/src/filter_http_rewrite.cpp index 80a876a..0f7ea87 100644 --- a/src/filter_http_rewrite.cpp +++ b/src/filter_http_rewrite.cpp @@ -59,9 +59,9 @@ namespace metaproxy_1 { }; class HttpRewrite::Within { public: - std::string header; - std::string attr; - std::string tag; + boost::regex header; + boost::regex attr; + boost::regex tag; std::string type; bool reqline; RulePtr rule; @@ -226,25 +226,14 @@ void yf::HttpRewrite::Phase::rewrite_headers(mp::odr & o, std::list::const_iterator it = cit->within_list.begin(); for (; it != cit->within_list.end(); it++) { - if (it->header.length() > 0 && - yaz_strcasecmp(it->header.c_str(), header->name) == 0) + if (!it->header.empty() && + regex_match(header->name, it->header)) { - std::string sheader(header->name); - sheader += ": "; - sheader += header->value; - - if (it->exec(vars, sheader, true)) + // Match and replace only the header value + std::string hval(header->value); + if (it->exec(vars, hval, true)) { - size_t pos = sheader.find(": "); - if (pos == std::string::npos) - { - yaz_log(YLOG_LOG, "Header malformed during rewrite, ignoring"); - continue; - } - header->name = odr_strdup( - o, sheader.substr(0, pos).c_str()); - header->value = odr_strdup( - o, sheader.substr(pos + 2, std::string::npos).c_str()); + header->value = odr_strdup(o, hval.c_str()); } } } @@ -260,6 +249,10 @@ void yf::HttpRewrite::Phase::rewrite_body( { if (*content_len == 0) return; + if (!content_type) { + yaz_log(YLOG_LOG, "rewrite_body: null content_type, can not rewrite"); + return; + } std::list::const_iterator cit = content_list.begin(); for (; cit != content_list.end(); cit++) { @@ -269,13 +262,18 @@ void yf::HttpRewrite::Phase::rewrite_body( && regex_match(content_type, cit->content_re)) break; } - if (cit == content_list.end()) + if (cit == content_list.end()) { + yaz_log(YLOG_LOG,"rewrite_body: No content rule matched %s, not rewriting", + content_type ); return; + } int i; for (i = 0; i < *content_len; i++) - if ((*content_buf)[i] == 0) + if ((*content_buf)[i] == 0) { + yaz_log(YLOG_LOG,"rewrite_body: Looks like binary stuff, not rewriting"); return; // binary content. skip + } std::string content(*content_buf, *content_len); cit->parse(m_verbose, content, vars); @@ -309,19 +307,12 @@ void yf::HttpRewrite::Event::openTagStart(const char *tag, int tag_len) std::list::const_iterator it = m_content->within_list.begin(); for (; it != m_content->within_list.end(); it++) { - if (it->tag.length() > 0 && yaz_strcasecmp(it->tag.c_str(), - t.c_str()) == 0) + if (!it->tag.empty() && regex_match(t, it->tag)) { - std::vector attr; - boost::split(attr, it->attr, boost::is_any_of(",")); - size_t i; - for (i = 0; i < attr.size(); i++) + if (!it->attr.empty() && regex_match("#text", it->attr)) { - if (attr[i].compare("#text") == 0) - { - s_within.push(it); - return; - } + s_within.push(it); + return; } } } @@ -336,7 +327,7 @@ void yf::HttpRewrite::Event::anyTagEnd(const char *tag, int tag_len, { std::list::const_iterator it = s_within.top(); std::string t(tag, tag_len); - if (yaz_strcasecmp(it->tag.c_str(), t.c_str()) == 0) + if (regex_match(t, it->tag)) s_within.pop(); } } @@ -356,19 +347,11 @@ void yf::HttpRewrite::Event::attribute(const char *tag, int tag_len, for (; it != m_content->within_list.end(); it++) { std::string t(tag, tag_len); - if (it->tag.length() == 0 || - yaz_strcasecmp(it->tag.c_str(), t.c_str()) == 0) + if (it->tag.empty() || regex_match(t, it->tag)) { std::string a(attr, attr_len); - std::vector attr; - boost::split(attr, it->attr, boost::is_any_of(",")); - size_t i; - for (i = 0; i < attr.size(); i++) - { - if (attr[i].compare("#text") && - yaz_strcasecmp(attr[i].c_str(), a.c_str()) == 0) - subst = true; - } + if (!it->attr.empty() && regex_match(a, it->attr)) + subst = true; } if (subst) break; @@ -400,7 +383,7 @@ void yf::HttpRewrite::Event::closeTag(const char *tag, int tag_len) { std::list::const_iterator it = s_within.top(); std::string t(tag, tag_len); - if (yaz_strcasecmp(it->tag.c_str(), t.c_str()) == 0) + if (regex_match(t, it->tag)) s_within.pop(); } wrbuf_puts(m_w, " &vars, - mp::filter::HttpRewrite::RulePtr ruleptr) + mp::filter::HttpRewrite::RulePtr ruleptr, + bool html_context) { bool replace = false; std::string res; @@ -433,7 +417,28 @@ static bool embed_quoted_literal( const char *cp0 = cp; while (*cp) { - if (*cp == '"' || *cp == '\'') + if (html_context && !strncmp(cp, """, 6)) + { + cp += 6; + res.append(cp0, cp - cp0); + cp0 = cp; + while (*cp) + { + if (!strncmp(cp, """, 6)) + 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 == '\'') { int m = *cp; cp++; @@ -473,7 +478,7 @@ bool yf::HttpRewrite::Within::exec( { if (type == "quoted-literal") { - return embed_quoted_literal(txt, vars, rule); + return embed_quoted_literal(txt, vars, rule, true); } else { @@ -685,7 +690,7 @@ void yf::HttpRewrite::Content::quoted_literal( { std::list::const_iterator it = within_list.begin(); if (it != within_list.end()) - embed_quoted_literal(content, vars, it->rule); + embed_quoted_literal(content, vars, it->rule, false); } void yf::HttpRewrite::Content::configure( @@ -702,16 +707,52 @@ void yf::HttpRewrite::Content::configure( std::string values[6]; mp::xml::parse_attr(ptr, names, values); Within w; - w.header = values[0]; - w.attr = values[1]; - w.tag = values[2]; - std::map::const_iterator it = - rules.find(values[3]); - if (it == rules.end()) + if (values[0].length() > 0) + w.header.assign(values[0], boost::regex_constants::icase); + if (values[1].length() > 0) + w.attr.assign(values[1], boost::regex_constants::icase); + if (values[2].length() > 0) + w.tag.assign(values[2], boost::regex_constants::icase); + + std::vector rulenames; + boost::split(rulenames, values[3], boost::is_any_of(",")); + if (rulenames.size() == 0) + { throw mp::filter::FilterException - ("Reference to non-existing rule '" + values[3] + + ("Empty rule in '" + values[3] + "' in http_rewrite filter"); - w.rule = it->second; + } + else if (rulenames.size() == 1) + { + std::map::const_iterator it = + rules.find(rulenames[0]); + if (it == rules.end()) + throw mp::filter::FilterException + ("Reference to non-existing rule '" + rulenames[0] + + "' in http_rewrite filter"); + w.rule = it->second; + + } + else + { + RulePtr rule(new Rule); + size_t i; + for (i = 0; i < rulenames.size(); i++) + { + std::map::const_iterator it = + rules.find(rulenames[i]); + if (it == rules.end()) + throw mp::filter::FilterException + ("Reference to non-existing rule '" + rulenames[i] + + "' in http_rewrite filter"); + RulePtr subRule = it->second; + std::list::iterator rit = + subRule->replace_list.begin(); + for (; rit != subRule->replace_list.end(); rit++) + rule->replace_list.push_back(*rit); + } + w.rule = rule; + } w.reqline = values[4] == "1"; w.type = values[5]; if (w.type.empty() || w.type == "quoted-literal") @@ -800,8 +841,8 @@ void yf::HttpRewrite::configure_phase(const xmlNode *ptr, Phase &phase) Content c; c.type = values[0]; - // if (!values[1].empty()) - c.content_re = values[1]; + if (!values[1].empty()) + c.content_re.assign(values[1], boost::regex::icase); c.configure(ptr->children, rules); phase.content_list.push_back(c); }