X-Git-Url: http://lists.indexdata.dk/cgi-bin?a=blobdiff_plain;f=src%2Ffilter_http_rewrite.cpp;h=a615c2f3520c462490f15a217817dc8ee592a296;hb=dcf44e3b0a3feaa4bb651f3a7acaccdae35c2c46;hp=fd1b8876a8801b3d14e7449dcc66b595db9035e0;hpb=8bcd4c3e063e932b2f80f9491ec0af66d3da5c2e;p=metaproxy-moved-to-github.git diff --git a/src/filter_http_rewrite.cpp b/src/filter_http_rewrite.cpp index fd1b887..a615c2f 100644 --- a/src/filter_http_rewrite.cpp +++ b/src/filter_http_rewrite.cpp @@ -26,6 +26,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #include +#include #include #include #include @@ -39,15 +40,16 @@ namespace metaproxy_1 { namespace filter { class HttpRewrite::Replace { public: - std::string regex; + boost::regex re; + boost::smatch what; std::string recipe; std::map group_index; const std::string search_replace( std::map & vars, - const std::string & txt) const; - std::string sub_vars ( + const std::string & txt); + std::string sub_vars( const std::map & vars) const; - void parse_groups(); + void parse_groups(std::string pattern); }; class HttpRewrite::Rule { @@ -55,7 +57,7 @@ namespace metaproxy_1 { std::list replace_list; const std::string test_patterns( std::map & vars, - const std::string & txt) const; + const std::string & txt); }; class HttpRewrite::Within { public: @@ -68,7 +70,9 @@ namespace metaproxy_1 { class HttpRewrite::Phase { public: + Phase(); std::list within_list; + int m_verbose; void rewrite_reqline(mp::odr & o, Z_HTTP_Request *hreq, std::map & vars) const; void rewrite_headers(mp::odr & o, Z_HTTP_Header *headers, @@ -78,17 +82,17 @@ namespace metaproxy_1 { std::map & vars) const; }; class HttpRewrite::Event : public HTMLParserEvent { - void openTagStart(const char *name); - void anyTagEnd(const char *name, int close_it); - void attribute(const char *tagName, - const char *name, - const char *value, - int val_len); - void closeTag(const char *name); + void openTagStart(const char *tag, int tag_len); + void anyTagEnd(const char *tag, int tag_len, int close_it); + void attribute(const char *tag, int tag_len, + const char *attr, int attr_len, + const char *value, int val_len, + const char *sep); + void closeTag(const char *tag, int tag_len); void text(const char *value, int len); const Phase *m_phase; WRBUF m_w; - std::list::const_iterator enabled_within; + std::stack::const_iterator> s_within; std::map &m_vars; public: Event(const Phase *p, std::map &vars); @@ -226,6 +230,9 @@ void yf::HttpRewrite::Phase::rewrite_body(mp::odr & o, HTMLParser parser; Event ev(this, vars); + + parser.set_verbose(m_verbose); + std::string buf(*content_buf, *content_len); parser.parse(ev, buf.c_str()); @@ -240,7 +247,6 @@ yf::HttpRewrite::Event::Event(const Phase *p, ) : m_phase(p), m_vars(vars) { m_w = wrbuf_alloc(); - enabled_within = m_phase->within_list.end(); } yf::HttpRewrite::Event::~Event() @@ -253,36 +259,44 @@ const char *yf::HttpRewrite::Event::result() return wrbuf_cstr(m_w); } -void yf::HttpRewrite::Event::openTagStart(const char *name) +void yf::HttpRewrite::Event::openTagStart(const char *tag, int tag_len) { - // check if there is - if (enabled_within == m_phase->within_list.end()) + wrbuf_putc(m_w, '<'); + wrbuf_write(m_w, tag, tag_len); + + std::string t(tag, tag_len); + std::list::const_iterator it = m_phase->within_list.begin(); + for (; it != m_phase->within_list.end(); it++) { - std::list::const_iterator it = - m_phase->within_list.begin(); - for (; it != m_phase->within_list.end(); it++) + if (it->tag.length() > 0 && yaz_strcasecmp(it->tag.c_str(), + t.c_str()) == 0) { - if (it->tag.length() > 0 && it->tag.compare(name) == 0) + std::vector attr; + boost::split(attr, it->attr, boost::is_any_of(",")); + size_t i; + for (i = 0; i < attr.size(); i++) { - enabled_within = it; + if (attr[i].compare("#text") == 0) + { + s_within.push(it); + return; + } } } } - wrbuf_putc(m_w, '<'); - wrbuf_puts(m_w, name); } -void yf::HttpRewrite::Event::anyTagEnd(const char *name, int close_it) +void yf::HttpRewrite::Event::anyTagEnd(const char *tag, int tag_len, + int close_it) { if (close_it) { - std::list::const_iterator it = enabled_within; - if (it != m_phase->within_list.end()) + if (!s_within.empty()) { - if (it->tag.compare(name) == 0) - { - enabled_within = m_phase->within_list.end(); - } + 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) + s_within.pop(); } } if (close_it) @@ -290,24 +304,28 @@ void yf::HttpRewrite::Event::anyTagEnd(const char *name, int close_it) wrbuf_putc(m_w, '>'); } -void yf::HttpRewrite::Event::attribute(const char *tagName, - const char *name, - const char *value, - int val_len) +void yf::HttpRewrite::Event::attribute(const char *tag, int tag_len, + const char *attr, int attr_len, + const char *value, int val_len, + const char *sep) { std::list::const_iterator it = m_phase->within_list.begin(); bool subst = false; for (; it != m_phase->within_list.end(); it++) { - if (it->tag.length() == 0 || it->tag.compare(tagName) == 0) + std::string t(tag, tag_len); + if (it->tag.length() == 0 || + yaz_strcasecmp(it->tag.c_str(), t.c_str()) == 0) { + 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") && attr[i].compare(name) == 0) + if (attr[i].compare("#text") && + yaz_strcasecmp(attr[i].c_str(), a.c_str()) == 0) subst = true; } } @@ -316,61 +334,46 @@ void yf::HttpRewrite::Event::attribute(const char *tagName, } wrbuf_putc(m_w, ' '); - wrbuf_puts(m_w, name); - wrbuf_puts(m_w, "=\""); - - std::string output; - if (subst) + wrbuf_write(m_w, attr, attr_len); + if (value) { - std::string input(value, val_len); - output = it->rule->test_patterns(m_vars, input); + wrbuf_puts(m_w, "="); + wrbuf_puts(m_w, sep); + + std::string output; + if (subst) + { + std::string input(value, val_len); + output = it->rule->test_patterns(m_vars, input); + } + if (output.empty()) + wrbuf_write(m_w, value, val_len); + else + wrbuf_puts(m_w, output.c_str()); + wrbuf_puts(m_w, sep); } - if (output.empty()) - wrbuf_write(m_w, value, val_len); - else - wrbuf_puts(m_w, output.c_str()); - wrbuf_puts(m_w, "\""); } -void yf::HttpRewrite::Event::closeTag(const char *name) +void yf::HttpRewrite::Event::closeTag(const char *tag, int tag_len) { - std::list::const_iterator it = enabled_within; - if (it != m_phase->within_list.end()) + if (!s_within.empty()) { - if (it->tag.compare(name) == 0) - { - enabled_within = m_phase->within_list.end(); - } + 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) + s_within.pop(); } wrbuf_puts(m_w, "::const_iterator it = enabled_within; - bool subst = false; - - if (it != m_phase->within_list.end()) - { - subst = true; - if (it->attr.length() > 0) - { - subst = false; - 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") == 0) - { - subst = true; - } - } - } - } + std::list::const_iterator it = m_phase->within_list.end(); + if (!s_within.empty()) + it = s_within.top(); std::string output; - if (subst) + if (it != m_phase->within_list.end()) { std::string input(value, len); output = it->rule->test_patterns(m_vars, input); @@ -381,16 +384,15 @@ void yf::HttpRewrite::Event::text(const char *value, int len) wrbuf_puts(m_w, output.c_str()); } - /** * Tests pattern from the vector in order and executes recipe on the first match. */ const std::string yf::HttpRewrite::Rule::test_patterns( std::map & vars, - const std::string & txt) const + const std::string & txt) { - std::list::const_iterator it = replace_list.begin(); + std::list::iterator it = replace_list.begin(); for (; it != replace_list.end(); it++) { @@ -402,11 +404,8 @@ const std::string yf::HttpRewrite::Rule::test_patterns( const std::string yf::HttpRewrite::Replace::search_replace( std::map & vars, - const std::string & txt) const + const std::string & txt) { - //exec regex against value - boost::regex re(regex); - boost::smatch what; std::string::const_iterator start, end; start = txt.begin(); end = txt.end(); @@ -421,8 +420,7 @@ const std::string yf::HttpRewrite::Replace::search_replace( = group_index.find(i); if (it != group_index.end()) { //it is - if (!what[i].str().empty()) - vars[it->second] = what[i]; + vars[it->second] = what[i]; } } @@ -440,11 +438,11 @@ const std::string yf::HttpRewrite::Replace::search_replace( return out; } -void yf::HttpRewrite::Replace::parse_groups() +void yf::HttpRewrite::Replace::parse_groups(std::string pattern) { int gnum = 0; bool esc = false; - const std::string & str = regex; + const std::string &str = pattern; std::string res; yaz_log(YLOG_LOG, "Parsing groups from '%s'", str.c_str()); for (size_t i = 0; i < str.size(); ++i) @@ -500,11 +498,11 @@ void yf::HttpRewrite::Replace::parse_groups() } esc = false; } - regex = res; + re = res; } -std::string yf::HttpRewrite::Replace::sub_vars ( - const std::map & vars) const +std::string yf::HttpRewrite::Replace::sub_vars( + const std::map & vars) const { std::string out; bool esc = false; @@ -553,9 +551,19 @@ std::string yf::HttpRewrite::Replace::sub_vars ( return out; } +yf::HttpRewrite::Phase::Phase() : m_verbose(0) +{ +} void yf::HttpRewrite::configure_phase(const xmlNode *ptr, Phase &phase) { + static const char *names[2] = { "verbose", 0 }; + std::string values[1]; + values[0] = "0"; + mp::xml::parse_attr(ptr, names, values); + + phase.m_verbose = atoi(values[0].c_str()); + std::map rules; for (ptr = ptr->children; ptr; ptr = ptr->next) { @@ -576,11 +584,12 @@ void yf::HttpRewrite::configure_phase(const xmlNode *ptr, Phase &phase) if (!strcmp((const char *) p->name, "rewrite")) { Replace replace; + std::string from; const struct _xmlAttr *attr; for (attr = p->properties; attr; attr = attr->next) { if (!strcmp((const char *) attr->name, "from")) - replace.regex = mp::xml::get_text(attr->children); + from = mp::xml::get_text(attr->children); else if (!strcmp((const char *) attr->name, "to")) replace.recipe = mp::xml::get_text(attr->children); else @@ -590,10 +599,12 @@ void yf::HttpRewrite::configure_phase(const xmlNode *ptr, Phase &phase) + " in rewrite section of http_rewrite"); } yaz_log(YLOG_LOG, "Found rewrite rule from '%s' to '%s'", - replace.regex.c_str(), replace.recipe.c_str()); - replace.parse_groups(); - if (!replace.regex.empty()) + from.c_str(), replace.recipe.c_str()); + if (!from.empty()) + { + replace.parse_groups(from); rule->replace_list.push_back(replace); + } } else throw mp::filter::FilterException