• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef NET_TOOLS_FLIP_SERVER_LOADTIME_MEASUREMENT_H__
6 #define NET_TOOLS_FLIP_SERVER_LOADTIME_MEASUREMENT_H__
7 #pragma once
8 
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <stdio.h>
12 #include <sys/types.h>
13 #include <unistd.h>
14 
15 #include <map>
16 #include <string>
17 #include <vector>
18 
19 // Class to handle loadtime measure related urls, which all start with testing
20 // The in memory server has a singleton object of this class. It includes a
21 // html file containing javascript to go through a list of urls and upload the
22 // loadtime. The users can modify urls.txt to define the urls they want to
23 // measure and start with downloading the html file from browser.
24 class LoadtimeMeasurement {
25  public:
LoadtimeMeasurement(const std::string & urls_file,const std::string & pageload_html_file)26   LoadtimeMeasurement(const std::string& urls_file,
27                       const std::string& pageload_html_file)
28       : num_urls_(0), pageload_html_file_(pageload_html_file) {
29     std::string urls_string;
30     read_file_to_string(urls_file.c_str(), &urls_string);
31     split_string(urls_string, '\n', &urls_);
32     num_urls_ = urls_.size();
33   }
34 
35   // This is the entry function for all the loadtime measure related urls
36   // It handles the request to html file, get_total_iteration to get number
37   // of urls in the urls file, get each url, report the loadtime for
38   // each url, and the test is completed.
ProcessRequest(const std::string & uri,std::string & output)39   void ProcessRequest(const std::string& uri, std::string& output) {
40     // remove "/testing/" from uri to get the action
41     std::string action = uri.substr(9);
42     if (pageload_html_file_.find(action) != std::string::npos) {
43       read_file_to_string(pageload_html_file_.c_str(), &output);
44       return;
45     }
46     if (action.find("get_total_iteration") == 0) {
47       char buffer[16];
48       snprintf(buffer, 16, "%d", num_urls_);
49       output.append(buffer, strlen(buffer));
50       return;
51     }
52     if (action.find("geturl") == 0) {
53       size_t b = action.find_first_of('=');
54       if (b != std::string::npos) {
55         int num = atoi(action.substr(b + 1).c_str());
56         if (num < num_urls_) {
57           output.append(urls_[num]);
58         }
59       }
60       return;
61     }
62     if (action.find("test_complete") == 0) {
63       for (std::map<std::string, int>::const_iterator it = loadtimes_.begin();
64            it != loadtimes_.end(); ++it) {
65         LOG(INFO) << it->first << " " << it->second;
66       }
67       loadtimes_.clear();
68       output.append("OK");
69       return;
70     }
71     if (action.find("record_page_load") == 0) {
72       std::vector<std::string> query;
73       split_string(action, '?', &query);
74       std::vector<std::string> params;
75       split_string(query[1], '&', &params);
76       std::vector<std::string> url;
77       std::vector<std::string> loadtime;
78       split_string(params[1], '=', &url);
79       split_string(params[2], '=', &loadtime);
80       loadtimes_[url[1]] = atoi(loadtime[1].c_str());
81       output.append("OK");
82       return;
83     }
84   }
85 
86  private:
read_file_to_string(const char * filename,std::string * output)87   void read_file_to_string(const char* filename, std::string* output) {
88     output->clear();
89     int fd = open(filename, 0, "r");
90     if (fd == -1)
91       return;
92     char buffer[4096];
93     ssize_t read_status = read(fd, buffer, sizeof(buffer));
94     while (read_status > 0) {
95       output->append(buffer, static_cast<size_t>(read_status));
96       do {
97         read_status = read(fd, buffer, sizeof(buffer));
98       } while (read_status <= 0 && errno == EINTR);
99     }
100     close(fd);
101   }
102 
split_string(std::string & str,char sepa,std::vector<std::string> * sub_strs)103   void split_string(std::string& str, char sepa,
104                     std::vector<std::string>* sub_strs) {
105     size_t b = 0;
106     size_t e = str.find_first_of(sepa, b);
107     while (e != std::string::npos && e > b) {
108       sub_strs->push_back(str.substr(b, e - b));
109       b = e + 1;
110       e = str.find_first_of(sepa, b);
111     }
112     if (b < str.size()) {
113       sub_strs->push_back(str.substr(b));
114     }
115   }
116 
117   int num_urls_;
118   std::vector<std::string> urls_;
119   std::map<std::string, int> loadtimes_;
120   const std::string pageload_html_file_;
121 };
122 
123 #endif  // NET_TOOLS_FLIP_SERVER_LOADTIME_MEASUREMENT_H__
124 
125