1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef mozilla_net_Http2Push_Internal_h 7 #define mozilla_net_Http2Push_Internal_h 8 9 // HTTP/2 - RFC 7540 10 // https://www.rfc-editor.org/rfc/rfc7540.txt 11 12 #include "Http2Session.h" 13 #include "Http2Stream.h" 14 15 #include "mozilla/Attributes.h" 16 #include "mozilla/TimeStamp.h" 17 #include "mozilla/UniquePtr.h" 18 #include "nsHttpRequestHead.h" 19 #include "nsILoadGroup.h" 20 #include "nsIRequestContext.h" 21 #include "nsString.h" 22 #include "PSpdyPush.h" 23 24 namespace mozilla { 25 namespace net { 26 27 class Http2PushTransactionBuffer; 28 29 class Http2PushedStream final : public Http2Stream { 30 public: 31 Http2PushedStream(Http2PushTransactionBuffer *aTransaction, 32 Http2Session *aSession, Http2Stream *aAssociatedStream, 33 uint32_t aID, 34 uint64_t aCurrentForegroundTabOuterContentWindowId); ~Http2PushedStream()35 virtual ~Http2PushedStream() {} 36 37 bool GetPushComplete(); 38 39 // The consumer stream is the synthetic pull stream hooked up to this push GetConsumerStream()40 virtual Http2Stream *GetConsumerStream() override { return mConsumerStream; }; 41 42 void SetConsumerStream(Http2Stream *aStream); 43 MOZ_MUST_USE bool GetHashKey(nsCString &key); 44 45 // override of Http2Stream 46 MOZ_MUST_USE nsresult ReadSegments(nsAHttpSegmentReader *, uint32_t, 47 uint32_t *) override; 48 MOZ_MUST_USE nsresult WriteSegments(nsAHttpSegmentWriter *, uint32_t, 49 uint32_t *) override; 50 void AdjustInitialWindow() override; 51 RequestContext()52 nsIRequestContext *RequestContext() override { return mRequestContext; }; 53 void ConnectPushedStream(Http2Stream *consumer); 54 55 MOZ_MUST_USE bool TryOnPush(); 56 static MOZ_MUST_USE bool TestOnPush(Http2Stream *consumer); 57 58 virtual bool DeferCleanup(nsresult status) override; SetDeferCleanupOnSuccess(bool val)59 void SetDeferCleanupOnSuccess(bool val) { mDeferCleanupOnSuccess = val; } 60 61 bool IsOrphaned(TimeStamp now); OnPushFailed()62 void OnPushFailed() { 63 mDeferCleanupOnPush = false; 64 mOnPushFailed = true; 65 } 66 67 MOZ_MUST_USE nsresult GetBufferedData(char *buf, uint32_t count, 68 uint32_t *countWritten); 69 70 // overload of Http2Stream HasSink()71 virtual bool HasSink() override { return !!mConsumerStream; } SetPushComplete()72 virtual void SetPushComplete() override { mPushCompleted = true; } 73 GetRequestString()74 nsCString &GetRequestString() { return mRequestString; } 75 76 private: 77 Http2Stream 78 *mConsumerStream; // paired request stream that consumes from 79 // real http/2 one.. null until a match is made. 80 81 nsCOMPtr<nsIRequestContext> mRequestContext; 82 83 nsAHttpTransaction *mAssociatedTransaction; 84 85 Http2PushTransactionBuffer *mBufferedPush; 86 mozilla::TimeStamp mLastRead; 87 88 nsCString mHashKey; 89 nsresult mStatus; 90 bool mPushCompleted; // server push FIN received 91 bool mDeferCleanupOnSuccess; 92 93 // mDeferCleanupOnPush prevents Http2Session::CleanupStream() from 94 // destroying the push stream on an error code during the period between 95 // when we need to do OnPush() on another thread and the time it takes 96 // for that event to create a synthetic pull stream attached to this 97 // object. That synthetic pull will become mConsuemerStream. 98 // Ths is essentially a delete protecting reference. 99 bool mDeferCleanupOnPush; 100 bool mOnPushFailed; 101 nsCString mRequestString; 102 }; 103 104 class Http2PushTransactionBuffer final : public nsAHttpTransaction { 105 public: 106 NS_DECL_ISUPPORTS 107 NS_DECL_NSAHTTPTRANSACTION 108 109 Http2PushTransactionBuffer(); 110 111 MOZ_MUST_USE nsresult GetBufferedData(char *buf, uint32_t count, 112 uint32_t *countWritten); SetPushStream(Http2PushedStream * stream)113 void SetPushStream(Http2PushedStream *stream) { mPushStream = stream; } 114 115 private: 116 virtual ~Http2PushTransactionBuffer(); 117 uint64_t Available(); 118 119 const static uint32_t kDefaultBufferSize = 4096; 120 121 nsresult mStatus; 122 nsHttpRequestHead *mRequestHead; 123 Http2PushedStream *mPushStream; 124 bool mIsDone; 125 126 UniquePtr<char[]> mBufferedHTTP1; 127 uint32_t mBufferedHTTP1Size; 128 uint32_t mBufferedHTTP1Used; 129 uint32_t mBufferedHTTP1Consumed; 130 }; 131 132 class Http2PushedStreamWrapper : public nsISupports { 133 public: 134 NS_DECL_THREADSAFE_ISUPPORTS 135 bool DispatchRelease(); 136 137 explicit Http2PushedStreamWrapper(Http2PushedStream* aPushStream); 138 GetRequestString()139 nsCString& GetRequestString() { return mRequestString; } 140 Http2PushedStream* GetStream(); 141 void OnPushFailed(); 142 143 private: 144 virtual ~Http2PushedStreamWrapper(); 145 146 nsCString mRequestString; 147 WeakPtr<Http2Stream> mStream; 148 }; 149 150 } // namespace net 151 } // namespace mozilla 152 153 #endif // mozilla_net_Http2Push_Internal_h 154