Updated Branches: refs/heads/master 39af1908a -> 6f6b24332
TS-1444 Fix URL lookup with regex via web interface Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/6f6b2433 Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/6f6b2433 Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/6f6b2433 Branch: refs/heads/master Commit: 6f6b243322d396123038e11b0b2f938ec5259304 Parents: 39af190 Author: Alan M. Carroll <[email protected]> Authored: Tue May 7 10:49:55 2013 -0500 Committer: Alan M. Carroll <[email protected]> Committed: Tue May 7 10:49:55 2013 -0500 ---------------------------------------------------------------------- CHANGES | 1 + iocore/cache/CachePages.cc | 2 +- proxy/hdrs/HTTP.cc | 115 +++++++++++++++++++++++++++------------ proxy/hdrs/HTTP.h | 13 +++++ 4 files changed, 95 insertions(+), 36 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/6f6b2433/CHANGES ---------------------------------------------------------------------- diff --git a/CHANGES b/CHANGES index e932443..dc7729e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,7 @@ -*- coding: utf-8 -*- Changes with Apache Traffic Server 3.3.3 + *) [TS-1444] [TS-1881] URL lookup with regex through the web interface was broken. *) [TS-1880] Use pthread_setname_np to set the thread name on multiple platforms. http://git-wip-us.apache.org/repos/asf/trafficserver/blob/6f6b2433/iocore/cache/CachePages.cc ---------------------------------------------------------------------- diff --git a/iocore/cache/CachePages.cc b/iocore/cache/CachePages.cc index 65a506c..242b687 100644 --- a/iocore/cache/CachePages.cc +++ b/iocore/cache/CachePages.cc @@ -562,7 +562,7 @@ ShowCache::handleCacheScanCallback(int event, Event *e) char xx[501], m[501]; int ib = 0, xd = 0, ml = 0; - alt->request_get()->url_get()->print(xx, 500, &ib, &xd); + alt->request_get()->url_print(xx, 500, &ib, &xd); xx[ib] = '\0'; const char *mm = alt->request_get()->method_get(&ml); http://git-wip-us.apache.org/repos/asf/trafficserver/blob/6f6b2433/proxy/hdrs/HTTP.cc ---------------------------------------------------------------------- diff --git a/proxy/hdrs/HTTP.cc b/proxy/hdrs/HTTP.cc index 2def411..f02c867 100644 --- a/proxy/hdrs/HTTP.cc +++ b/proxy/hdrs/HTTP.cc @@ -1513,51 +1513,96 @@ HTTPHdr::set_url_target_from_host_field(URL* url) { // and effective) or URl would have to provide access to // the URL printer. -// The use of a magic value for Arena to indicate the internal heap is -// even uglier but it's less so than duplicating this entire method to -// change that one thing. - -char* -HTTPHdr::url_string_get(Arena* arena, int* length) { - char *zret = 0; +/// Hack the URL in the HTTP header to be 1.0 compliant, saving the +/// original values so they can be restored. +class UrlPrintHack { + friend class HTTPHdr; + UrlPrintHack(HTTPHdr* hdr) { + hdr->_test_and_fill_target_cache(); + if (hdr->m_url_cached.valid()) { + URLImpl* ui = hdr->m_url_cached.m_url_impl; + char port_buff[10]; + + // Save values that can be modified. + m_hdr = hdr; // mark as having saved values. + m_len_host = ui->m_len_host; + m_ptr_host = ui->m_ptr_host; + m_len_port = ui->m_len_port; + m_ptr_port = ui->m_ptr_port; + + /* Get dirty. We reach in to the URL implementation to + set the host and port if + 1) They are not already set and + 2) The values were in a HTTP header field. + */ + if (!hdr->m_target_in_url && hdr->m_host_length && hdr->m_host_mime) { + assert(0 == ui->m_ptr_host); // shouldn't be non-zero if not in URL. + ui->m_ptr_host = hdr->m_host_mime->m_ptr_value; + ui->m_len_host = hdr->m_host_length; + } - if (length) *length = 0; - this->_test_and_fill_target_cache(); - if (m_url_cached.valid()) { - URLImpl* ui = m_url_cached.m_url_impl; - bool should_reset_host = false; - bool should_reset_port = false; - char port_buff[10]; - - /* Get dirty. We reach in to the URL implementation to - set the host and port if - 1) They are not already set and - 2) The values were in a HTTP header field. - */ - - if (!m_target_in_url && m_host_length && m_host_mime) { - assert(0 == ui->m_ptr_host); // shouldn't be non-zero if not in URL. - ui->m_ptr_host = m_host_mime->m_ptr_value; - ui->m_len_host = m_host_length; - should_reset_host = true; + if (0 == hdr->m_url_cached.port_get_raw() && hdr->m_port_in_header) { + assert(0 == ui->m_ptr_port); // shouldn't be set if not in URL. + ui->m_ptr_port = port_buff; + ui->m_len_port = sprintf(port_buff, "%.5d", hdr->m_port); + } + } else { + m_hdr = 0; } + } - if (0 == m_url_cached.port_get_raw() && m_port_in_header) { - assert(0 == ui->m_ptr_port); // shouldn't be set if not in URL. - ui->m_ptr_port = port_buff; - ui->m_len_port = sprintf(port_buff, "%.5d", m_port); - should_reset_port = true; + /// Destructor. + /// If we have a valid header, write the original URL values back. + ~UrlPrintHack() { + if (m_hdr) { + URLImpl* ui = m_hdr->m_url_cached.m_url_impl; + ui->m_len_port = m_len_port; + ui->m_len_host = m_len_host; + ui->m_ptr_port = m_ptr_port; + ui->m_ptr_host = m_ptr_host; } + } + + /// Check if the hack worked + bool is_valid() const { + return 0 != m_hdr; + } + + /// Saved values. + ///@{ + char const* m_ptr_host; + char const* m_ptr_port; + int m_len_host; + int m_len_port; + HTTPHdr* m_hdr; + ///@} +}; + +char* +HTTPHdr::url_string_get(Arena* arena, int* length) { + char* zret = 0; + UrlPrintHack hack(this); + + if (hack.is_valid()) { + // The use of a magic value for Arena to indicate the internal heap is + // even uglier but it's less so than duplicating this entire method to + // change that one thing. zret = (arena == USE_HDR_HEAP_MAGIC) ? m_url_cached.string_get_ref(length) : m_url_cached.string_get(arena, length) ; + } + return zret; +} - if (should_reset_host) { ui->m_ptr_host = 0; ui->m_len_host = 0; } - if (should_reset_port) { ui->m_ptr_port = 0; ui->m_len_port = 0; } - } - +int +HTTPHdr::url_print(char* buff, int length, int* offset, int* skip) { + int zret = 0; + UrlPrintHack hack(this); + if (hack.is_valid()) { + zret = m_url_cached.print(buff, length, offset, skip); + } return zret; } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/6f6b2433/proxy/hdrs/HTTP.h ---------------------------------------------------------------------- diff --git a/proxy/hdrs/HTTP.h b/proxy/hdrs/HTTP.h index 553317e..45a59bf 100644 --- a/proxy/hdrs/HTTP.h +++ b/proxy/hdrs/HTTP.h @@ -576,6 +576,17 @@ public: int* length = 0 ///< Store string length here. ); + /** Print the URL. + Output is not null terminated. + @return 0 on failure, non-zero on success. + */ + int url_print( + char* buff, ///< Output buffer + int length, ///< Length of @a buffer + int* offset, ///< [in,out] ??? + int* skip ///< [in,out] ??? + ); + /** Get the URL path. This is a reference, not allocated. @return A pointer to the path or @c NULL if there is no valid URL. @@ -665,6 +676,8 @@ private: // No gratuitous copies! HTTPHdr(const HTTPHdr & m); HTTPHdr & operator =(const HTTPHdr & m); + + friend class UrlPrintHack; // don't ask. };
