Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 37 additions & 2 deletions include/proxy/hdrs/HTTP.h
Original file line number Diff line number Diff line change
Expand Up @@ -444,13 +444,22 @@ bool is_http1_hdr_version_supported(const HTTPVersion &http_version);

class IOBufferReader;

/** HTTP Header class.
*
* @warning Changing the size of this class (adding/removing fields) will change
* the on-disk cache format and cause cache incompatibility. The HTTPCacheAlt
* structure contains embedded HTTPHdr objects, and the cache marshalling code
* uses sizeof(HTTPCacheAlt) to read/write cache entries. Any size change will
* cause "vector inconsistency" errors when reading cache entries written by a
* different version.
*/
class HTTPHdr : public MIMEHdr
{
public:
HTTPHdrImpl *m_http = nullptr;
mutable URL m_url_cached;
mutable MIMEField *m_host_mime = nullptr;
mutable int m_host_length = 0; ///< Length of hostname.
mutable int m_host_length = 0; ///< Length of hostname (parsed, excludes port).
mutable int m_port = 0; ///< Target port.
mutable bool m_target_cached = false; ///< Whether host name and port are cached.
mutable bool m_target_in_url = false; ///< Whether host name and port are in the URL.
Expand Down Expand Up @@ -732,8 +741,34 @@ HTTPHdr::print(char *buf, int bufsize, int *bufindex, int *dumpoffset) const
inline void
HTTPHdr::_test_and_fill_target_cache() const
{
if (!m_target_cached)
if (!m_target_cached) {
this->_fill_target_cache();
return;
}

// If host came from the Host header (not URL), check for staleness by verifying
// the current Host header value length matches what we expect from cached values.
if (!m_target_in_url && m_host_mime != nullptr) {
int expected_len = m_host_length;
if (m_port_in_header && m_port > 0) {
// Account for ":port" suffix in the raw Host header value.
expected_len += 1; // colon
if (m_port < 10) {
expected_len += 1;
} else if (m_port < 100) {
expected_len += 2;
} else if (m_port < 1000) {
expected_len += 3;
} else if (m_port < 10000) {
expected_len += 4;
} else {
expected_len += 5;
}
}
if (m_host_mime->m_len_value != expected_len) {
this->_fill_target_cache();
}
}
}

/*-------------------------------------------------------------------------
Expand Down
Loading