diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/socket_stream/socket_stream.cc | 12 | ||||
-rw-r--r-- | net/url_request/request_tracker.h | 62 | ||||
-rw-r--r-- | net/url_request/request_tracker_unittest.cc | 75 | ||||
-rw-r--r-- | net/url_request/url_request.cc | 15 | ||||
-rw-r--r-- | net/url_request/url_request_view_net_internals_job.cc | 58 |
5 files changed, 204 insertions, 18 deletions
diff --git a/net/socket_stream/socket_stream.cc b/net/socket_stream/socket_stream.cc index 9d60a9e..402b8ec 100644 --- a/net/socket_stream/socket_stream.cc +++ b/net/socket_stream/socket_stream.cc @@ -29,7 +29,6 @@ #include "net/socket_stream/socket_stream_throttle.h" #include "net/url_request/url_request.h" -static const int kMaxNumLoadLogEntries = 50; static const int kMaxPendingSendAllowed = 32768; // 32 kilobytes. static const int kReadBufferSize = 4096; @@ -40,8 +39,7 @@ void SocketStream::ResponseHeaders::Realloc(size_t new_size) { } SocketStream::SocketStream(const GURL& url, Delegate* delegate) - : load_log_(new net::LoadLog(kMaxNumLoadLogEntries)), - url_(url), + : url_(url), delegate_(delegate), max_pending_send_allowed_(kMaxPendingSendAllowed), next_state_(STATE_NONE), @@ -99,8 +97,14 @@ void SocketStream::set_context(URLRequestContext* context) { if (prev_context != context) { if (prev_context) prev_context->socket_stream_tracker()->Remove(this); - if (context) + if (context) { + if (!load_log_) { + // Create the LoadLog -- we waited until now to create it so we know + // what constraints the URLRequestContext is enforcing on log levels. + load_log_ = context->socket_stream_tracker()->CreateLoadLog(); + } context->socket_stream_tracker()->Add(this); + } } if (context_) diff --git a/net/url_request/request_tracker.h b/net/url_request/request_tracker.h index abfdf4b..3202e60 100644 --- a/net/url_request/request_tracker.h +++ b/net/url_request/request_tracker.h @@ -40,13 +40,22 @@ class RequestTracker { typedef std::vector<RecentRequestInfo> RecentRequestInfoList; typedef bool (*RecentRequestsFilterFunc)(const GURL&); - // The maximum number of entries for |graveyard_|. + // The maximum number of entries for |graveyard_|, when in bounded mode. static const size_t kMaxGraveyardSize; - // The maximum size of URLs to stuff into RecentRequestInfo. + // The maximum size of URLs to stuff into RecentRequestInfo, when in bounded + // mode. static const size_t kMaxGraveyardURLSize; - RequestTracker() : next_graveyard_index_(0), graveyard_filter_func_(NULL) {} + // The maximum number of entries to use for LoadLogs when in bounded mode. + static const size_t kBoundedLoadLogMaxEntries; + + RequestTracker() + : next_graveyard_index_(0), + graveyard_filter_func_(NULL), + is_unbounded_(false) { + } + ~RequestTracker() {} // Returns a list of Requests that are alive. @@ -90,10 +99,13 @@ class RequestTracker { RecentRequestInfo info; request->GetInfoForTracker(&info); - // Paranoia check: truncate |info.original_url| if it is really big. - const std::string& spec = info.original_url.possibly_invalid_spec(); - if (spec.size() > kMaxGraveyardURLSize) - info.original_url = GURL(spec.substr(0, kMaxGraveyardURLSize)); + + if (!is_unbounded_) { + // Paranoia check: truncate |info.original_url| if it is really big. + const std::string& spec = info.original_url.possibly_invalid_spec(); + if (spec.size() > kMaxGraveyardURLSize) + info.original_url = GURL(spec.substr(0, kMaxGraveyardURLSize)); + } if (ShouldInsertIntoGraveyard(info)) { // Add into |graveyard_|. @@ -109,6 +121,31 @@ class RequestTracker { graveyard_filter_func_ = filter_func; } + bool IsUnbounded() const { + return is_unbounded_; + } + + void SetUnbounded(bool unbounded) { + // No change. + if (is_unbounded_ == unbounded) + return; + + // If we are going from unbounded to bounded, we need to trim the + // graveyard. For simplicity we will simply clear it. + if (is_unbounded_ && !unbounded) + ClearRecentlyDeceased(); + + is_unbounded_ = unbounded; + } + + // Creates a LoadLog using the unbounded/bounded constraints that + // apply to this tracker. + net::LoadLog* CreateLoadLog() { + if (IsUnbounded()) + return new net::LoadLog(net::LoadLog::kUnbounded); + return new net::LoadLog(kBoundedLoadLogMaxEntries); + } + private: bool ShouldInsertIntoGraveyard(const RecentRequestInfo& info) { if (!graveyard_filter_func_) @@ -117,6 +154,13 @@ class RequestTracker { } void InsertIntoGraveyard(const RecentRequestInfo& info) { + if (is_unbounded_) { + graveyard_.push_back(info); + return; + } + + // Otherwise enforce a bound on the graveyard size, by treating it as a + // circular buffer. if (graveyard_.size() < kMaxGraveyardSize) { // Still growing to maximum capacity. DCHECK_EQ(next_graveyard_index_, graveyard_.size()); @@ -133,6 +177,7 @@ class RequestTracker { size_t next_graveyard_index_; RecentRequestInfoList graveyard_; RecentRequestsFilterFunc graveyard_filter_func_; + bool is_unbounded_; }; template<typename Request> @@ -141,4 +186,7 @@ const size_t RequestTracker<Request>::kMaxGraveyardSize = 25; template<typename Request> const size_t RequestTracker<Request>::kMaxGraveyardURLSize = 1000; +template<typename Request> +const size_t RequestTracker<Request>::kBoundedLoadLogMaxEntries = 50; + #endif // NET_URL_REQUEST_REQUEST_TRACKER_H_ diff --git a/net/url_request/request_tracker_unittest.cc b/net/url_request/request_tracker_unittest.cc index e603129..d31587c 100644 --- a/net/url_request/request_tracker_unittest.cc +++ b/net/url_request/request_tracker_unittest.cc @@ -44,8 +44,9 @@ class TestRequest { }; -TEST(RequestTrackerTest, Basic) { +TEST(RequestTrackerTest, BasicBounded) { RequestTracker<TestRequest> tracker; + EXPECT_FALSE(tracker.IsUnbounded()); EXPECT_EQ(0u, tracker.GetLiveRequests().size()); EXPECT_EQ(0u, tracker.GetRecentlyDeceased().size()); @@ -85,6 +86,7 @@ TEST(RequestTrackerTest, Basic) { TEST(RequestTrackerTest, GraveyardBounded) { RequestTracker<TestRequest> tracker; + EXPECT_FALSE(tracker.IsUnbounded()); EXPECT_EQ(0u, tracker.GetLiveRequests().size()); EXPECT_EQ(0u, tracker.GetRecentlyDeceased().size()); @@ -111,9 +113,42 @@ TEST(RequestTrackerTest, GraveyardBounded) { } } +TEST(RequestTrackerTest, GraveyardUnbounded) { + RequestTracker<TestRequest> tracker; + EXPECT_FALSE(tracker.IsUnbounded()); + EXPECT_EQ(0u, tracker.GetLiveRequests().size()); + EXPECT_EQ(0u, tracker.GetRecentlyDeceased().size()); + + tracker.SetUnbounded(true); + + EXPECT_TRUE(tracker.IsUnbounded()); + + // Add twice as many requests as would fit in the bounded graveyard. + + size_t kMaxSize = RequestTracker<TestRequest>::kMaxGraveyardSize * 2; + for (size_t i = 0; i < kMaxSize; ++i) { + TestRequest req(GURL(StringPrintf("http://req%" PRIuS, i).c_str())); + tracker.Add(&req); + tracker.Remove(&req); + } + + // Check that all of them got saved. + + RequestTracker<TestRequest>::RecentRequestInfoList recent_reqs = + tracker.GetRecentlyDeceased(); + + ASSERT_EQ(kMaxSize, recent_reqs.size()); + + for (size_t i = 0; i < kMaxSize; ++i) { + GURL url(StringPrintf("http://req%" PRIuS, i).c_str()); + EXPECT_EQ(url, recent_reqs[i].original_url); + } +} + // Check that very long URLs are truncated. TEST(RequestTrackerTest, GraveyardURLBounded) { RequestTracker<TestRequest> tracker; + EXPECT_FALSE(tracker.IsUnbounded()); std::string big_url_spec("http://"); big_url_spec.resize(2 * RequestTracker<TestRequest>::kMaxGraveyardURLSize, @@ -134,6 +169,7 @@ TEST(RequestTrackerTest, GraveyardURLBounded) { // Test the doesn't fail if the URL was invalid. http://crbug.com/21423. TEST(URLRequestTrackerTest, TrackingInvalidURL) { RequestTracker<TestRequest> tracker; + EXPECT_FALSE(tracker.IsUnbounded()); EXPECT_EQ(0u, tracker.GetLiveRequests().size()); EXPECT_EQ(0u, tracker.GetRecentlyDeceased().size()); @@ -158,6 +194,7 @@ bool ShouldRequestBeAddedToGraveyard(const GURL& url) { // saved into the recent requests list (graveyard), by using a filter. TEST(RequestTrackerTest, GraveyardCanBeFiltered) { RequestTracker<TestRequest> tracker; + EXPECT_FALSE(tracker.IsUnbounded()); tracker.SetGraveyardFilter(ShouldRequestBeAddedToGraveyard); @@ -188,4 +225,40 @@ TEST(RequestTrackerTest, GraveyardCanBeFiltered) { tracker.GetRecentlyDeceased()[1].original_url.spec()); } +// Convert an unbounded tracker back to being bounded. +TEST(RequestTrackerTest, ConvertUnboundedToBounded) { + RequestTracker<TestRequest> tracker; + EXPECT_FALSE(tracker.IsUnbounded()); + EXPECT_EQ(0u, tracker.GetLiveRequests().size()); + EXPECT_EQ(0u, tracker.GetRecentlyDeceased().size()); + + tracker.SetUnbounded(true); + EXPECT_TRUE(tracker.IsUnbounded()); + + // Add twice as many requests as would fit in the bounded graveyard. + + size_t kMaxSize = RequestTracker<TestRequest>::kMaxGraveyardSize * 2; + for (size_t i = 0; i < kMaxSize; ++i) { + TestRequest req(GURL(StringPrintf("http://req%" PRIuS, i).c_str())); + tracker.Add(&req); + tracker.Remove(&req); + } + + // Check that all of them got saved. + ASSERT_EQ(kMaxSize, tracker.GetRecentlyDeceased().size()); + + // Now make the tracker bounded, and add more entries to its graveyard. + tracker.SetUnbounded(false); + + kMaxSize = RequestTracker<TestRequest>::kMaxGraveyardSize; + for (size_t i = 0; i < kMaxSize; ++i) { + TestRequest req(GURL(StringPrintf("http://req%" PRIuS, i).c_str())); + tracker.Add(&req); + tracker.Remove(&req); + } + + // We should only have kMaxGraveyardSize entries now. + ASSERT_EQ(kMaxSize, tracker.GetRecentlyDeceased().size()); +} + } // namespace diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc index e85b055..ec2eace 100644 --- a/net/url_request/url_request.cc +++ b/net/url_request/url_request.cc @@ -27,9 +27,6 @@ using std::wstring; // Max number of http redirects to follow. Same number as gecko. static const int kMaxRedirects = 20; -// The maximum size of the passive LoadLog associated with each request. -static const int kMaxNumLoadLogEntries = 50; - static URLRequestJobManager* GetJobManager() { return Singleton<URLRequestJobManager>::get(); } @@ -38,8 +35,7 @@ static URLRequestJobManager* GetJobManager() { // URLRequest URLRequest::URLRequest(const GURL& url, Delegate* delegate) - : load_log_(new net::LoadLog(kMaxNumLoadLogEntries)), - url_(url), + : url_(url), original_url_(url), method_("GET"), load_flags_(net::LOAD_NORMAL), @@ -500,8 +496,15 @@ void URLRequest::set_context(URLRequestContext* context) { if (prev_context != context) { if (prev_context) prev_context->url_request_tracker()->Remove(this); - if (context) + if (context) { + if (!load_log_) { + // Create the LoadLog -- we waited until now to create it so we know + // what constraints the URLRequestContext is enforcing on log levels. + load_log_ = context->url_request_tracker()->CreateLoadLog(); + } + context->url_request_tracker()->Add(this); + } } } diff --git a/net/url_request/url_request_view_net_internals_job.cc b/net/url_request/url_request_view_net_internals_job.cc index 3c74d5b..e3759eb 100644 --- a/net/url_request/url_request_view_net_internals_job.cc +++ b/net/url_request/url_request_view_net_internals_job.cc @@ -480,6 +480,51 @@ bool GetViewCacheKeyFromPath(const std::string path, return true; } +// Process any query strings in the request (for actions like toggling +// full logging. As a side-effect, also append some status text to the HTML +// describing what we did. +void ProcessQueryStringCommands(URLRequestContext* context, + const std::string& query, + std::string* data) { + if (StartsWithASCII(query, "logging=", true)) { + bool enable_unbounded = StartsWithASCII(query, "logging=E", true); + context->url_request_tracker()->SetUnbounded(enable_unbounded); + context->socket_stream_tracker()->SetUnbounded(enable_unbounded); + + if (enable_unbounded) + data->append("<i>Enabled full logging</i>\n"); + else + data->append("<i>Disabled full logging, and cleared the recent " + "requests</i>\n"); + + } else if (StartsWithASCII(query, "data=Clear", true)) { + context->url_request_tracker()->ClearRecentlyDeceased(); + context->socket_stream_tracker()->ClearRecentlyDeceased(); + + data->append("<i>Cleared the recent request logs</i>\n"); + } +} + +// Append some HTML controls to |data| that allow the user to enable full +// logging, and clear some of the already logged data. +void DrawControlsHeader(URLRequestContext* context, std::string* data) { + bool is_full_logging_enabled = + context->url_request_tracker()->IsUnbounded() && + context->socket_stream_tracker()->IsUnbounded(); + + data->append("<form action='' method=GET style='margin-bottom: 10px'>\n"); + if (is_full_logging_enabled) { + data->append( + "<input type=submit name=logging value='Disable full logging' />"); + } else { + data->append( + "<input type=submit name=logging value='Enable full logging' />"); + } + + data->append("<input type=submit name=data value='Clear recent requests' />"); + data->append("</form>\n"); +} + } // namespace bool URLRequestViewNetInternalsJob::GetData(std::string* mime_type, @@ -491,6 +536,16 @@ bool URLRequestViewNetInternalsJob::GetData(std::string* mime_type, URLRequestContext* context = request_->context(); std::string details = url_format_->GetDetails(request_->url()); + std::string query; + + // Split out the query parameters. + std::string::size_type query_start = details.find('?'); + if (query_start != std::string::npos) { + if (query_start + 1 < details.size()) + query = details.substr(query_start + 1); + details = details.substr(0, query_start); + } + data->clear(); // Use a different handler for "view-cache/*" subpaths. @@ -514,6 +569,9 @@ bool URLRequestViewNetInternalsJob::GetData(std::string* mime_type, "developers/design-documents/view-net-internals'>" "Help: how do I use this?</a></p>"); + ProcessQueryStringCommands(context, query, data); + DrawControlsHeader(context, data); + SubSection* all = Singleton<AllSubSections>::get(); SubSection* section = all; |