netwerk/protocol/http/SpdyPush31.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.)

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

mercurial