Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(378)

Side by Side Diff: net/tools/fetch/fetch_client.cc

Issue 99333: A utility driver for doing client/server HTTP transaction... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/net.gyp ('k') | net/tools/fetch/fetch_server.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2009 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 "base/at_exit.h"
6 #include "base/command_line.h"
7 #include "base/message_loop.h"
8 #include "base/singleton.h"
9 #include "base/stats_counters.h"
10 #include "base/string_util.h"
11 #include "net/base/completion_callback.h"
12 #include "net/base/io_buffer.h"
13 #include "net/base/net_errors.h"
14 #include "net/http/http_cache.h"
15 #include "net/http/http_network_layer.h"
16 #include "net/http/http_request_info.h"
17 #include "net/http/http_transaction.h"
18 #include "net/proxy/proxy_service.h"
19
20 void usage(const char* program_name) {
21 printf("usage: %s --url=<url> [--n=<clients>] [--stats] [--use_cache]\n",
22 program_name);
23 exit(1);
24 }
25
26 // Test Driver
27 class Driver {
28 public:
29 Driver()
30 : clients_(0) {}
31
32 void ClientStarted() { clients_++; }
33 void ClientStopped() {
34 if (!--clients_) {
35 MessageLoop::current()->Quit();
36 }
37 }
38
39 private:
40 int clients_;
41 };
42
43 // A network client
44 class Client {
45 public:
46 Client(net::HttpTransactionFactory* factory, const std::string& url) :
47 url_(url),
48 transaction_(factory->CreateTransaction()),
49 buffer_(new net::IOBuffer(kBufferSize)),
50 ALLOW_THIS_IN_INITIALIZER_LIST(
51 connect_callback_(this, &Client::OnConnectComplete)),
52 ALLOW_THIS_IN_INITIALIZER_LIST(
53 read_callback_(this, &Client::OnReadComplete)) {
54 buffer_->AddRef();
55 driver_->ClientStarted();
56 request_info_.url = url_;
57 request_info_.method = "GET";
58 int state = transaction_->Start(&request_info_, &connect_callback_);
59 DCHECK(state == net::ERR_IO_PENDING);
60 };
61
62 private:
63 void OnConnectComplete(int result) {
64 // Do work here.
65 int state = transaction_->Read(buffer_.get(), kBufferSize, &read_callback_);
66 if (state == net::ERR_IO_PENDING)
67 return; // IO has started.
68 if (state < 0)
69 return; // ERROR!
70 OnReadComplete(state);
71 }
72
73 void OnReadComplete(int result) {
74 if (result == 0) {
75 OnRequestComplete(result);
76 return;
77 }
78
79 // Deal with received data here.
80 static StatsCounter bytes_read("FetchClient.bytes_read");
81 bytes_read.Add(result);
82
83 // Issue a read for more data.
84 int state = transaction_->Read(buffer_.get(), kBufferSize, &read_callback_);
85 if (state == net::ERR_IO_PENDING)
86 return; // IO has started.
87 if (state < 0)
88 return; // ERROR!
89 OnReadComplete(state);
90 }
91
92 void OnRequestComplete(int result) {
93 static StatsCounter requests("FetchClient.requests");
94 requests.Increment();
95 driver_->ClientStopped();
96 printf(".");
97 }
98
99 static const int kBufferSize = (16 * 1024);
100 GURL url_;
101 net::HttpRequestInfo request_info_;
102 scoped_ptr<net::HttpTransaction> transaction_;
103 scoped_ptr<net::IOBuffer> buffer_;
104 net::CompletionCallbackImpl<Client> connect_callback_;
105 net::CompletionCallbackImpl<Client> read_callback_;
106 Singleton<Driver> driver_;
107 };
108
109 int main(int argc, char**argv) {
110 base::AtExitManager exit;
111 StatsTable table("fetchclient", 50, 1000);
112 table.set_current(&table);
113
114 CommandLine::Init(0, NULL);
115 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
116 std::string url = WideToASCII(parsed_command_line.GetSwitchValue(L"url"));
117 if (!url.length())
118 usage(argv[0]);
119 int client_limit = 1;
120 if (parsed_command_line.HasSwitch(L"n"))
121 StringToInt(WideToASCII(parsed_command_line.GetSwitchValue(L"n")),
122 &client_limit);
123 bool use_cache = parsed_command_line.HasSwitch(L"use-cache");
124
125 // Do work here.
126 MessageLoop loop;
127
128 scoped_ptr<net::ProxyService> proxy_service(net::ProxyService::CreateNull());
129 net::HttpTransactionFactory* factory = NULL;
130 if (use_cache)
131 factory = new net::HttpCache(proxy_service.get(), 0);
132 else
133 factory = new net::HttpNetworkLayer(proxy_service.get());
134
135 {
136 StatsCounterTimer driver_time("FetchClient.total_time");
137 StatsScope<StatsCounterTimer> scope(driver_time);
138
139 Client** clients = new Client*[client_limit];
140 for (int i = 0; i < client_limit; i++)
141 clients[i] = new Client(factory, url);
142
143 MessageLoop::current()->Run();
144 }
145
146 // Print Statistics here.
147 int num_clients = table.GetCounterValue("c:FetchClient.requests");
148 int test_time = table.GetCounterValue("t:FetchClient.total_time");
149 int bytes_read = table.GetCounterValue("c:FetchClient.bytes_read");
150
151 printf("\n");
152 printf("Clients : %d\n", num_clients);
153 printf("Time : %dms\n", test_time);
154 printf("Bytes Read : %d\n", bytes_read);
155 if (test_time > 0) {
156 const char *units = "bps";
157 double bps = static_cast<float>(bytes_read * 8) /
158 (static_cast<float>(test_time) / 1000.0);
159
160 if (bps > (1024*1024)) {
161 bps /= (1024*1024);
162 units = "Mbps";
163 } else if (bps > 1024) {
164 bps /= 1024;
165 units = "Kbps";
166 }
167 printf("Bandwidth : %.2f%s\n", bps, units);
168 }
169
170 if (parsed_command_line.HasSwitch(L"stats")) {
171 // Dump the stats table.
172 printf("<stats>\n");
173 int counter_max = table.GetMaxCounters();
174 for (int index=0; index < counter_max; index++) {
175 std::string name(table.GetRowName(index));
176 if (name.length() > 0) {
177 int value = table.GetRowValue(index);
178 printf("%s:\t%d\n", name.c_str(), value);
179
180 }
181 }
182 printf("</stats>\n");
183 }
184 return 0;
185 }
OLDNEW
« no previous file with comments | « net/net.gyp ('k') | net/tools/fetch/fetch_server.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698