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