1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "services/network/throttling/throttling_upload_data_stream.h"
6
7 #include "base/bind.h"
8 #include "net/base/net_errors.h"
9
10 namespace network {
11
ThrottlingUploadDataStream(net::UploadDataStream * upload_data_stream)12 ThrottlingUploadDataStream::ThrottlingUploadDataStream(
13 net::UploadDataStream* upload_data_stream)
14 : net::UploadDataStream(upload_data_stream->is_chunked(),
15 upload_data_stream->identifier()),
16 throttle_callback_(
17 base::BindRepeating(&ThrottlingUploadDataStream::ThrottleCallback,
18 base::Unretained(this))),
19 throttled_byte_count_(0),
20 upload_data_stream_(upload_data_stream) {}
21
~ThrottlingUploadDataStream()22 ThrottlingUploadDataStream::~ThrottlingUploadDataStream() {
23 if (interceptor_)
24 interceptor_->StopThrottle(throttle_callback_);
25 }
26
SetInterceptor(ThrottlingNetworkInterceptor * interceptor)27 void ThrottlingUploadDataStream::SetInterceptor(
28 ThrottlingNetworkInterceptor* interceptor) {
29 DCHECK(!interceptor_);
30 if (interceptor)
31 interceptor_ = interceptor->GetWeakPtr();
32 }
33
IsInMemory() const34 bool ThrottlingUploadDataStream::IsInMemory() const {
35 return false;
36 }
37
InitInternal(const net::NetLogWithSource & net_log)38 int ThrottlingUploadDataStream::InitInternal(
39 const net::NetLogWithSource& net_log) {
40 throttled_byte_count_ = 0;
41 int result = upload_data_stream_->Init(
42 base::BindOnce(&ThrottlingUploadDataStream::StreamInitCallback,
43 base::Unretained(this)),
44 net_log);
45 if (result == net::OK && !is_chunked())
46 SetSize(upload_data_stream_->size());
47 return result;
48 }
49
StreamInitCallback(int result)50 void ThrottlingUploadDataStream::StreamInitCallback(int result) {
51 if (!is_chunked())
52 SetSize(upload_data_stream_->size());
53 OnInitCompleted(result);
54 }
55
ReadInternal(net::IOBuffer * buf,int buf_len)56 int ThrottlingUploadDataStream::ReadInternal(net::IOBuffer* buf, int buf_len) {
57 int result = upload_data_stream_->Read(
58 buf, buf_len,
59 base::BindOnce(&ThrottlingUploadDataStream::StreamReadCallback,
60 base::Unretained(this)));
61 return ThrottleRead(result);
62 }
63
StreamReadCallback(int result)64 void ThrottlingUploadDataStream::StreamReadCallback(int result) {
65 result = ThrottleRead(result);
66 if (result != net::ERR_IO_PENDING)
67 OnReadCompleted(result);
68 }
69
ThrottleRead(int result)70 int ThrottlingUploadDataStream::ThrottleRead(int result) {
71 if (is_chunked() && upload_data_stream_->IsEOF())
72 SetIsFinalChunk();
73
74 if (!interceptor_ || result < 0)
75 return result;
76
77 if (result > 0)
78 throttled_byte_count_ += result;
79 return interceptor_->StartThrottle(result, throttled_byte_count_,
80 base::TimeTicks(), false, true,
81 throttle_callback_);
82 }
83
ThrottleCallback(int result,int64_t bytes)84 void ThrottlingUploadDataStream::ThrottleCallback(int result, int64_t bytes) {
85 throttled_byte_count_ = bytes;
86 OnReadCompleted(result);
87 }
88
ResetInternal()89 void ThrottlingUploadDataStream::ResetInternal() {
90 upload_data_stream_->Reset();
91 throttled_byte_count_ = 0;
92 if (interceptor_)
93 interceptor_->StopThrottle(throttle_callback_);
94 }
95
96 } // namespace network
97