netwerk/protocol/http/Http2Push.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set sw=2 ts=8 et tw=80 : */
     3 /* This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 // HttpLog.h should generally be included first
     8 #include "HttpLog.h"
    10 // Log on level :5, instead of default :4.
    11 #undef LOG
    12 #define LOG(args) LOG5(args)
    13 #undef LOG_ENABLED
    14 #define LOG_ENABLED() LOG5_ENABLED()
    16 #include <algorithm>
    18 #include "Http2Push.h"
    20 #include "nsDependentString.h"
    22 namespace mozilla {
    23 namespace net {
    25 //////////////////////////////////////////
    26 // Http2PushedStream
    27 //////////////////////////////////////////
    29 Http2PushedStream::Http2PushedStream(Http2PushTransactionBuffer *aTransaction,
    30                                      Http2Session *aSession,
    31                                      Http2Stream *aAssociatedStream,
    32                                      uint32_t aID)
    33   :Http2Stream(aTransaction, aSession, 0)
    34   , mConsumerStream(nullptr)
    35   , mBufferedPush(aTransaction)
    36   , mStatus(NS_OK)
    37   , mPushCompleted(false)
    38   , mDeferCleanupOnSuccess(true)
    39 {
    40   LOG3(("Http2PushedStream ctor this=%p 0x%X\n", this, aID));
    41   mStreamID = aID;
    42   MOZ_ASSERT(!(aID & 1)); // must be even to be a pushed stream
    43   mBufferedPush->SetPushStream(this);
    44   mLoadGroupCI = aAssociatedStream->LoadGroupConnectionInfo();
    45   mLastRead = TimeStamp::Now();
    46   SetPriority(aAssociatedStream->Priority() + 1);
    47 }
    49 bool
    50 Http2PushedStream::GetPushComplete()
    51 {
    52   return mPushCompleted;
    53 }
    55 nsresult
    56 Http2PushedStream::WriteSegments(nsAHttpSegmentWriter *writer,
    57                                  uint32_t count, uint32_t *countWritten)
    58 {
    59   nsresult rv = Http2Stream::WriteSegments(writer, count, countWritten);
    60   if (NS_SUCCEEDED(rv) && *countWritten) {
    61     mLastRead = TimeStamp::Now();
    62   }
    64   if (rv == NS_BASE_STREAM_CLOSED) {
    65     mPushCompleted = true;
    66     rv = NS_OK; // this is what a normal HTTP transaction would do
    67   }
    68   if (rv != NS_BASE_STREAM_WOULD_BLOCK && NS_FAILED(rv))
    69     mStatus = rv;
    70   return rv;
    71 }
    73 nsresult
    74 Http2PushedStream::ReadSegments(nsAHttpSegmentReader *,
    75                                 uint32_t, uint32_t *count)
    76 {
    77   // The request headers for this has been processed, so we need to verify
    78   // that :authority, :scheme, and :path MUST be present. :method MUST NOT be
    79   // present
    80   CreatePushHashKey(mHeaderScheme, mHeaderHost,
    81                     mSession->Serial(), mHeaderPath,
    82                     mOrigin, mHashKey);
    84   LOG3(("Http2PushStream 0x%X hash key %s\n", mStreamID, mHashKey.get()));
    86   // the write side of a pushed transaction just involves manipulating a little state
    87   SetSentFin(true);
    88   Http2Stream::mAllHeadersSent = 1;
    89   Http2Stream::ChangeState(UPSTREAM_COMPLETE);
    90   *count = 0;
    91   return NS_OK;
    92 }
    94 bool
    95 Http2PushedStream::GetHashKey(nsCString &key)
    96 {
    97   if (mHashKey.IsEmpty())
    98     return false;
   100   key = mHashKey;
   101   return true;
   102 }
   104 void
   105 Http2PushedStream::ConnectPushedStream(Http2Stream *stream)
   106 {
   107   mSession->ConnectPushedStream(stream);
   108 }
   110 bool
   111 Http2PushedStream::IsOrphaned(TimeStamp now)
   112 {
   113   MOZ_ASSERT(!now.IsNull());
   115   // if session is not transmitting, and is also not connected to a consumer
   116   // stream, and its been like that for too long then it is oprhaned
   118   if (mConsumerStream)
   119     return false;
   121   bool rv = ((now - mLastRead).ToSeconds() > 30.0);
   122   if (rv) {
   123     LOG3(("Http2PushedStream:IsOrphaned 0x%X IsOrphaned %3.2f\n",
   124           mStreamID, (now - mLastRead).ToSeconds()));
   125   }
   126   return rv;
   127 }
   129 nsresult
   130 Http2PushedStream::GetBufferedData(char *buf,
   131                                    uint32_t count, uint32_t *countWritten)
   132 {
   133   if (NS_FAILED(mStatus))
   134     return mStatus;
   136   nsresult rv = mBufferedPush->GetBufferedData(buf, count, countWritten);
   137   if (NS_FAILED(rv))
   138     return rv;
   140   if (!*countWritten)
   141     rv = GetPushComplete() ? NS_BASE_STREAM_CLOSED : NS_BASE_STREAM_WOULD_BLOCK;
   143   return rv;
   144 }
   146 //////////////////////////////////////////
   147 // Http2PushTransactionBuffer
   148 // This is the nsAHttpTransction owned by the stream when the pushed
   149 // stream has not yet been matched with a pull request
   150 //////////////////////////////////////////
   152 NS_IMPL_ISUPPORTS0(Http2PushTransactionBuffer)
   154 Http2PushTransactionBuffer::Http2PushTransactionBuffer()
   155   : mStatus(NS_OK)
   156   , mRequestHead(nullptr)
   157   , mPushStream(nullptr)
   158   , mIsDone(false)
   159   , mBufferedHTTP1Size(kDefaultBufferSize)
   160   , mBufferedHTTP1Used(0)
   161   , mBufferedHTTP1Consumed(0)
   162 {
   163   mBufferedHTTP1 = new char[mBufferedHTTP1Size];
   164 }
   166 Http2PushTransactionBuffer::~Http2PushTransactionBuffer()
   167 {
   168   delete mRequestHead;
   169 }
   171 void
   172 Http2PushTransactionBuffer::SetConnection(nsAHttpConnection *conn)
   173 {
   174 }
   176 nsAHttpConnection *
   177 Http2PushTransactionBuffer::Connection()
   178 {
   179   return nullptr;
   180 }
   182 void
   183 Http2PushTransactionBuffer::GetSecurityCallbacks(nsIInterfaceRequestor **outCB)
   184 {
   185   *outCB = nullptr;
   186 }
   188 void
   189 Http2PushTransactionBuffer::OnTransportStatus(nsITransport* transport,
   190                                               nsresult status, uint64_t progress)
   191 {
   192 }
   194 bool
   195 Http2PushTransactionBuffer::IsDone()
   196 {
   197   return mIsDone;
   198 }
   200 nsresult
   201 Http2PushTransactionBuffer::Status()
   202 {
   203   return mStatus;
   204 }
   206 uint32_t
   207 Http2PushTransactionBuffer::Caps()
   208 {
   209   return 0;
   210 }
   212 void
   213 Http2PushTransactionBuffer::SetDNSWasRefreshed()
   214 {
   215 }
   217 uint64_t
   218 Http2PushTransactionBuffer::Available()
   219 {
   220   return mBufferedHTTP1Used - mBufferedHTTP1Consumed;
   221 }
   223 nsresult
   224 Http2PushTransactionBuffer::ReadSegments(nsAHttpSegmentReader *reader,
   225                                          uint32_t count, uint32_t *countRead)
   226 {
   227   *countRead = 0;
   228   return NS_ERROR_NOT_IMPLEMENTED;
   229 }
   231 nsresult
   232 Http2PushTransactionBuffer::WriteSegments(nsAHttpSegmentWriter *writer,
   233                                           uint32_t count, uint32_t *countWritten)
   234 {
   235   if ((mBufferedHTTP1Size - mBufferedHTTP1Used) < 20480) {
   236     Http2Session::EnsureBuffer(mBufferedHTTP1,
   237                                 mBufferedHTTP1Size + kDefaultBufferSize,
   238                                 mBufferedHTTP1Used,
   239                                 mBufferedHTTP1Size);
   240   }
   242   count = std::min(count, mBufferedHTTP1Size - mBufferedHTTP1Used);
   243   nsresult rv = writer->OnWriteSegment(mBufferedHTTP1 + mBufferedHTTP1Used,
   244                                        count, countWritten);
   245   if (NS_SUCCEEDED(rv)) {
   246     mBufferedHTTP1Used += *countWritten;
   247   }
   248   else if (rv == NS_BASE_STREAM_CLOSED) {
   249     mIsDone = true;
   250   }
   252   if (Available()) {
   253     Http2Stream *consumer = mPushStream->GetConsumerStream();
   255     if (consumer) {
   256       LOG3(("Http2PushTransactionBuffer::WriteSegments notifying connection "
   257             "consumer data available 0x%X [%u]\n",
   258             mPushStream->StreamID(), Available()));
   259       mPushStream->ConnectPushedStream(consumer);
   260     }
   261   }
   263   return rv;
   264 }
   266 uint32_t
   267 Http2PushTransactionBuffer::Http1xTransactionCount()
   268 {
   269   return 0;
   270 }
   272 nsHttpRequestHead *
   273 Http2PushTransactionBuffer::RequestHead()
   274 {
   275   if (!mRequestHead)
   276     mRequestHead = new nsHttpRequestHead();
   277   return mRequestHead;
   278 }
   280 nsresult
   281 Http2PushTransactionBuffer::TakeSubTransactions(
   282   nsTArray<nsRefPtr<nsAHttpTransaction> > &outTransactions)
   283 {
   284   return NS_ERROR_NOT_IMPLEMENTED;
   285 }
   287 void
   288 Http2PushTransactionBuffer::SetProxyConnectFailed()
   289 {
   290 }
   292 void
   293 Http2PushTransactionBuffer::Close(nsresult reason)
   294 {
   295   mStatus = reason;
   296   mIsDone = true;
   297 }
   299 nsresult
   300 Http2PushTransactionBuffer::AddTransaction(nsAHttpTransaction *trans)
   301 {
   302   return NS_ERROR_NOT_IMPLEMENTED;
   303 }
   305 uint32_t
   306 Http2PushTransactionBuffer::PipelineDepth()
   307 {
   308   return 0;
   309 }
   311 nsresult
   312 Http2PushTransactionBuffer::SetPipelinePosition(int32_t position)
   313 {
   314   return NS_OK;
   315 }
   317 int32_t
   318 Http2PushTransactionBuffer::PipelinePosition()
   319 {
   320   return 1;
   321 }
   323 nsresult
   324 Http2PushTransactionBuffer::GetBufferedData(char *buf,
   325                                             uint32_t count,
   326                                             uint32_t *countWritten)
   327 {
   328   *countWritten = std::min(count, static_cast<uint32_t>(Available()));
   329   if (*countWritten) {
   330     memcpy(buf, mBufferedHTTP1 + mBufferedHTTP1Consumed, *countWritten);
   331     mBufferedHTTP1Consumed += *countWritten;
   332   }
   334   // If all the data has been consumed then reset the buffer
   335   if (mBufferedHTTP1Consumed == mBufferedHTTP1Used) {
   336     mBufferedHTTP1Consumed = 0;
   337     mBufferedHTTP1Used = 0;
   338   }
   340   return NS_OK;
   341 }
   343 } // namespace mozilla::net
   344 } // namespace mozilla

mercurial