From 01c12cb1ef517ae29669a1cceda973f4e8dac6d0 Mon Sep 17 00:00:00 2001 From: Nicholas Hurley Date: Wed, 24 Aug 2016 14:35:43 -0700 Subject: [PATCH] Bug 1296280 (part 2) - Add pref for our SETTINGS_MAX_TABLE_SIZE. r=mcmanus MozReview-Commit-ID: 44CYEvJOno0 --HG-- extra : rebase_source : 5317d25981bf83ab8cc9b921055cc9028a1d4470 --- netwerk/protocol/http/Http2Compression.cpp | 16 ++++++++++++++++ netwerk/protocol/http/Http2Compression.h | 2 ++ netwerk/protocol/http/Http2Session.cpp | 12 ++++++++++-- netwerk/protocol/http/nsHttpHandler.cpp | 8 ++++++++ netwerk/protocol/http/nsHttpHandler.h | 8 ++++++++ 5 files changed, 44 insertions(+), 2 deletions(-) diff --git a/netwerk/protocol/http/Http2Compression.cpp b/netwerk/protocol/http/Http2Compression.cpp index 3174f837659d..470721c19ed6 100644 --- a/netwerk/protocol/http/Http2Compression.cpp +++ b/netwerk/protocol/http/Http2Compression.cpp @@ -281,6 +281,7 @@ Http2BaseCompressor::Http2BaseCompressor() : mOutput(nullptr) , mMaxBuffer(kDefaultMaxBuffer) , mMaxBufferSetting(kDefaultMaxBuffer) + , mSetInitialMaxBufferSizeAllowed(true) , mPeakSize(0) , mPeakCount(0) { @@ -383,10 +384,24 @@ Http2BaseCompressor::SetMaxBufferSizeInternal(uint32_t maxBufferSize) mMaxBuffer = maxBufferSize; } +nsresult +Http2BaseCompressor::SetInitialMaxBufferSize(uint32_t maxBufferSize) +{ + MOZ_ASSERT(mSetInitialMaxBufferSizeAllowed); + + if (mSetInitialMaxBufferSizeAllowed) { + mMaxBufferSetting = maxBufferSize; + return NS_OK; + } + + return NS_ERROR_FAILURE; +} + nsresult Http2Decompressor::DecodeHeaderBlock(const uint8_t *data, uint32_t datalen, nsACString &output, bool isPush) { + mSetInitialMaxBufferSizeAllowed = false; mOffset = 0; mData = data; mDataLen = datalen; @@ -1035,6 +1050,7 @@ Http2Compressor::EncodeHeaderBlock(const nsCString &nvInput, const nsACString &host, const nsACString &scheme, bool connectForm, nsACString &output) { + mSetInitialMaxBufferSizeAllowed = false; mOutput = &output; output.SetCapacity(1024); output.Truncate(); diff --git a/netwerk/protocol/http/Http2Compression.h b/netwerk/protocol/http/Http2Compression.h index 0b2167f53168..4cf9e740bfc3 100644 --- a/netwerk/protocol/http/Http2Compression.h +++ b/netwerk/protocol/http/Http2Compression.h @@ -66,6 +66,7 @@ public: Http2BaseCompressor(); virtual ~Http2BaseCompressor(); size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + nsresult SetInitialMaxBufferSize(uint32_t maxBufferSize); protected: const static uint32_t kDefaultMaxBuffer = 4096; @@ -80,6 +81,7 @@ protected: uint32_t mMaxBuffer; uint32_t mMaxBufferSetting; + bool mSetInitialMaxBufferSizeAllowed; uint32_t mPeakSize; uint32_t mPeakCount; diff --git a/netwerk/protocol/http/Http2Session.cpp b/netwerk/protocol/http/Http2Session.cpp index a73673ae0dac..364a846872e8 100644 --- a/netwerk/protocol/http/Http2Session.cpp +++ b/netwerk/protocol/http/Http2Session.cpp @@ -832,10 +832,10 @@ Http2Session::SendHello() MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); LOG3(("Http2Session::SendHello %p\n", this)); - // sized for magic + 4 settings and a session window update and 5 priority frames + // sized for magic + 5 settings and a session window update and 5 priority frames // 24 magic, 33 for settings (9 header + 4 settings @6), 13 for window update, // 5 priority frames at 14 (9 + 5) each - static const uint32_t maxSettings = 4; + static const uint32_t maxSettings = 5; static const uint32_t prioritySize = 5 * (kFrameHeaderBytes + 5); static const uint32_t maxDataLen = 24 + kFrameHeaderBytes + maxSettings * 6 + 13 + prioritySize; char *packet = EnsureOutputBuffer(maxDataLen); @@ -854,6 +854,14 @@ Http2Session::SendHello() // 2nd entry is bytes 15 to 20 // 3rd entry is bytes 21 to 26 // 4th entry is bytes 27 to 32 + // 5th entry is bytes 33 to 38 + + // Let the other endpoint know about our default HPACK decompress table size + uint32_t maxHpackBufferSize = gHttpHandler->DefaultHpackBuffer(); + mDecompressor.SetInitialMaxBufferSize(maxHpackBufferSize); + NetworkEndian::writeUint16(packet + kFrameHeaderBytes + (6 * numberOfEntries), SETTINGS_TYPE_HEADER_TABLE_SIZE); + NetworkEndian::writeUint32(packet + kFrameHeaderBytes + (6 * numberOfEntries) + 2, maxHpackBufferSize); + numberOfEntries++; if (!gHttpHandler->AllowPush()) { // If we don't support push then set MAX_CONCURRENT to 0 and also diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp index 71fc0645e4fa..b49eea182d93 100644 --- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -239,6 +239,7 @@ nsHttpHandler::nsHttpHandler() , mTCPKeepaliveLongLivedIdleTimeS(600) , mEnforceH1Framing(FRAMECHECK_BARELY) , mKeepEmptyResponseHeadersAsEmtpyString(false) + , mDefaultHpackBuffer(4096) { LOG(("Creating nsHttpHandler [this=%p].\n", this)); @@ -1693,6 +1694,13 @@ nsHttpHandler::PrefsChanged(nsIPrefBranch *prefs, const char *pref) } } + if (PREF_CHANGED(HTTP_PREF("spdy.hpack-default-buffer"))) { + rv = prefs->GetIntPref(HTTP_PREF("spdy.default-hpack-buffer"), &val); + if (NS_SUCCEEDED(rv)) { + mDefaultHpackBuffer = val; + } + } + // Enable HTTP response timeout if TCP Keepalives are disabled. mResponseTimeoutEnabled = !mTCPKeepaliveShortLivedEnabled && !mTCPKeepaliveLongLivedEnabled; diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h index 57596052164c..3c62aa59306c 100644 --- a/netwerk/protocol/http/nsHttpHandler.h +++ b/netwerk/protocol/http/nsHttpHandler.h @@ -368,6 +368,11 @@ public: return mKeepEmptyResponseHeadersAsEmtpyString; } + uint32_t DefaultHpackBuffer() const + { + return mDefaultHpackBuffer; + } + private: virtual ~nsHttpHandler(); @@ -587,6 +592,9 @@ private: // (Bug 6699259) bool mKeepEmptyResponseHeadersAsEmtpyString; + // The default size (in bytes) of the HPACK decompressor table. + uint32_t mDefaultHpackBuffer; + private: // For Rate Pacing Certain Network Events. Only assign this pointer on // socket thread.