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

Side by Side Diff: test_http_server.cc

Issue 3036005: AU: HTTP success is not just 200, but anything in the 2xx range (Closed) Base URL: ssh://git@chromiumos-git/update_engine.git
Patch Set: Created 10 years, 5 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
« no previous file with comments | « libcurl_http_fetcher.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // This file implements a simple HTTP server. It can exhibit odd behavior 5 // This file implements a simple HTTP server. It can exhibit odd behavior
6 // that's useful for testing. For example, it's useful to test that 6 // that's useful for testing. For example, it's useful to test that
7 // the updater can continue a connection if it's dropped, or that it 7 // the updater can continue a connection if it's dropped, or that it
8 // handles very slow data transfers. 8 // handles very slow data transfers.
9 9
10 // To use this, simply make an HTTP connection to localhost:port and 10 // To use this, simply make an HTTP connection to localhost:port and
(...skipping 13 matching lines...) Expand all
24 #include <vector> 24 #include <vector>
25 #include "chromeos/obsolete_logging.h" 25 #include "chromeos/obsolete_logging.h"
26 26
27 using std::min; 27 using std::min;
28 using std::string; 28 using std::string;
29 using std::vector; 29 using std::vector;
30 30
31 namespace chromeos_update_engine { 31 namespace chromeos_update_engine {
32 32
33 struct HttpRequest { 33 struct HttpRequest {
34 HttpRequest() : offset(0), return_code(200) {}
34 string url; 35 string url;
35 off_t offset; 36 off_t offset;
37 int return_code;
36 }; 38 };
37 39
38 namespace { 40 namespace {
39 const int kPort = 8080; // hardcoded to 8080 for now 41 const int kPort = 8080; // hardcoded to 8080 for now
40 const int kBigLength = 100000; 42 const int kBigLength = 100000;
41 } 43 }
42 44
43 bool ParseRequest(int fd, HttpRequest* request) { 45 bool ParseRequest(int fd, HttpRequest* request) {
44 string headers; 46 string headers;
45 while(headers.find("\r\n\r\n") == string::npos) { 47 while(headers.find("\r\n\r\n") == string::npos) {
(...skipping 23 matching lines...) Expand all
69 request->offset = 0; 71 request->offset = 0;
70 } else { 72 } else {
71 range_start = headers.find("\r\nRange: ") + strlen("\r\nRange: "); 73 range_start = headers.find("\r\nRange: ") + strlen("\r\nRange: ");
72 range_end = headers.find('\r', range_start); 74 range_end = headers.find('\r', range_start);
73 CHECK_NE(string::npos, range_end); 75 CHECK_NE(string::npos, range_end);
74 string range_header = headers.substr(range_start, range_end - range_start); 76 string range_header = headers.substr(range_start, range_end - range_start);
75 77
76 LOG(INFO) << "Range: " << range_header; 78 LOG(INFO) << "Range: " << range_header;
77 CHECK(*range_header.rbegin() == '-'); 79 CHECK(*range_header.rbegin() == '-');
78 request->offset = atoll(range_header.c_str() + strlen("bytes=")); 80 request->offset = atoll(range_header.c_str() + strlen("bytes="));
81 request->return_code = 206; // Success for Range: request
79 LOG(INFO) << "Offset: " << request->offset; 82 LOG(INFO) << "Offset: " << request->offset;
80 } 83 }
81 request->url = url; 84 request->url = url;
82 return true; 85 return true;
83 } 86 }
84 87
85 void WriteString(int fd, const string& str) { 88 void WriteString(int fd, const string& str) {
86 unsigned int bytes_written = 0; 89 unsigned int bytes_written = 0;
87 while (bytes_written < str.size()) { 90 while (bytes_written < str.size()) {
88 ssize_t r = write(fd, str.c_str() + bytes_written, 91 ssize_t r = write(fd, str.c_str() + bytes_written,
89 str.size() - bytes_written); 92 str.size() - bytes_written);
90 LOG(INFO) << "write() wrote " << r << " bytes"; 93 LOG(INFO) << "write() wrote " << r << " bytes";
91 if (r < 0) { 94 if (r < 0) {
92 perror("write"); 95 perror("write");
93 return; 96 return;
94 } 97 }
95 bytes_written += r; 98 bytes_written += r;
96 } 99 }
97 LOG(INFO) << "WriteString wrote " << bytes_written << " bytes"; 100 LOG(INFO) << "WriteString wrote " << bytes_written << " bytes";
98 } 101 }
99 102
100 string Itoa(off_t num) { 103 string Itoa(off_t num) {
101 char buf[100] = {0}; 104 char buf[100] = {0};
102 snprintf(buf, sizeof(buf), "%" PRIi64, num); 105 snprintf(buf, sizeof(buf), "%" PRIi64, num);
103 return buf; 106 return buf;
104 } 107 }
105 108
106 void WriteHeaders(int fd, bool support_range, off_t full_size, 109 void WriteHeaders(int fd, bool support_range, off_t full_size,
107 off_t start_offset) { 110 off_t start_offset, int return_code) {
108 LOG(INFO) << "writing headers"; 111 LOG(INFO) << "writing headers";
109 WriteString(fd, "HTTP/1.1 200 OK\r\n"); 112 WriteString(fd, string("HTTP/1.1 ") + Itoa(return_code) + " OK\r\n");
110 WriteString(fd, "Content-Type: application/octet-stream\r\n"); 113 WriteString(fd, "Content-Type: application/octet-stream\r\n");
111 if (support_range) { 114 if (support_range) {
112 WriteString(fd, "Accept-Ranges: bytes\r\n"); 115 WriteString(fd, "Accept-Ranges: bytes\r\n");
113 WriteString(fd, string("Content-Range: bytes ") + Itoa(start_offset) + 116 WriteString(fd, string("Content-Range: bytes ") + Itoa(start_offset) +
114 "-" + Itoa(full_size - 1) + "/" + Itoa(full_size) + "\r\n"); 117 "-" + Itoa(full_size - 1) + "/" + Itoa(full_size) + "\r\n");
115 } 118 }
116 off_t content_length = full_size; 119 off_t content_length = full_size;
117 if (support_range) 120 if (support_range)
118 content_length -= start_offset; 121 content_length -= start_offset;
119 WriteString(fd, string("Content-Length: ") + Itoa(content_length) + "\r\n"); 122 WriteString(fd, string("Content-Length: ") + Itoa(content_length) + "\r\n");
120 WriteString(fd, "\r\n"); 123 WriteString(fd, "\r\n");
121 } 124 }
122 125
123 void HandleQuitQuitQuit(int fd) { 126 void HandleQuitQuitQuit(int fd) {
124 WriteHeaders(fd, true, 0, 0); 127 WriteHeaders(fd, true, 0, 0, 200);
125 exit(0); 128 exit(0);
126 } 129 }
127 130
128 void HandleBig(int fd, const HttpRequest& request) { 131 void HandleBig(int fd, const HttpRequest& request) {
129 const off_t full_length = kBigLength; 132 const off_t full_length = kBigLength;
130 WriteHeaders(fd, true, full_length, request.offset); 133 WriteHeaders(fd, true, full_length, request.offset, request.return_code);
131 const off_t content_length = full_length - request.offset; 134 const off_t content_length = full_length - request.offset;
132 int i = request.offset; 135 int i = request.offset;
133 for (; i % 10; i++) 136 for (; i % 10; i++)
134 WriteString(fd, string(1, 'a' + (i % 10))); 137 WriteString(fd, string(1, 'a' + (i % 10)));
135 CHECK_EQ(i % 10, 0); 138 CHECK_EQ(i % 10, 0);
136 for (; i < content_length; i += 10) 139 for (; i < content_length; i += 10)
137 WriteString(fd, "abcdefghij"); 140 WriteString(fd, "abcdefghij");
138 CHECK_EQ(i, full_length); 141 CHECK_EQ(i, full_length);
139 } 142 }
140 143
141 // This is like /big, but it writes at most 9000 bytes. Also, 144 // This is like /big, but it writes at most 9000 bytes. Also,
142 // half way through it sleeps for 70 seconds 145 // half way through it sleeps for 70 seconds
143 // (technically, when (offset % (9000 * 7)) == 0). 146 // (technically, when (offset % (9000 * 7)) == 0).
144 void HandleFlaky(int fd, const HttpRequest& request) { 147 void HandleFlaky(int fd, const HttpRequest& request) {
145 const off_t full_length = kBigLength; 148 const off_t full_length = kBigLength;
146 WriteHeaders(fd, true, full_length, request.offset); 149 WriteHeaders(fd, true, full_length, request.offset, request.return_code);
147 const off_t content_length = 150 const off_t content_length =
148 min(static_cast<off_t>(9000), full_length - request.offset); 151 min(static_cast<off_t>(9000), full_length - request.offset);
149 const bool should_sleep = (request.offset % (9000 * 7)) == 0; 152 const bool should_sleep = (request.offset % (9000 * 7)) == 0;
150 153
151 string buf; 154 string buf;
152 155
153 for (int i = request.offset; i % 10; i++) 156 for (int i = request.offset; i % 10; i++)
154 buf.append(1, 'a' + (i % 10)); 157 buf.append(1, 'a' + (i % 10));
155 while (static_cast<off_t>(buf.size()) < content_length) 158 while (static_cast<off_t>(buf.size()) < content_length)
156 buf.append("abcdefghij"); 159 buf.append("abcdefghij");
157 buf.resize(content_length); 160 buf.resize(content_length);
158 161
159 if (!should_sleep) { 162 if (!should_sleep) {
160 LOG(INFO) << "writing data blob of size " << buf.size(); 163 LOG(INFO) << "writing data blob of size " << buf.size();
161 WriteString(fd, buf); 164 WriteString(fd, buf);
162 } else { 165 } else {
163 string::size_type half_way_point = buf.size() / 2; 166 string::size_type half_way_point = buf.size() / 2;
164 LOG(INFO) << "writing small data blob of size " << half_way_point; 167 LOG(INFO) << "writing small data blob of size " << half_way_point;
165 WriteString(fd, buf.substr(0, half_way_point)); 168 WriteString(fd, buf.substr(0, half_way_point));
166 sleep(10); 169 sleep(10);
167 LOG(INFO) << "writing small data blob of size " 170 LOG(INFO) << "writing small data blob of size "
168 << (buf.size() - half_way_point); 171 << (buf.size() - half_way_point);
169 WriteString(fd, buf.substr(half_way_point, buf.size() - half_way_point)); 172 WriteString(fd, buf.substr(half_way_point, buf.size() - half_way_point));
170 } 173 }
171 } 174 }
172 175
173 void HandleDefault(int fd, const HttpRequest& request) { 176 void HandleDefault(int fd, const HttpRequest& request) {
174 const string data("unhandled path"); 177 const string data("unhandled path");
175 WriteHeaders(fd, true, data.size(), request.offset); 178 WriteHeaders(fd, true, data.size(), request.offset, request.return_code);
176 const string data_to_write(data.substr(request.offset, 179 const string data_to_write(data.substr(request.offset,
177 data.size() - request.offset)); 180 data.size() - request.offset));
178 WriteString(fd, data_to_write); 181 WriteString(fd, data_to_write);
179 } 182 }
180 183
181 void HandleConnection(int fd) { 184 void HandleConnection(int fd) {
182 HttpRequest request; 185 HttpRequest request;
183 ParseRequest(fd, &request); 186 ParseRequest(fd, &request);
184 187
185 if (request.url == "/quitquitquit") 188 if (request.url == "/quitquitquit")
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 int client_fd = accept(listen_fd, 237 int client_fd = accept(listen_fd,
235 (struct sockaddr *) &client_addr, 238 (struct sockaddr *) &client_addr,
236 &clilen); 239 &clilen);
237 LOG(INFO) << "got past accept"; 240 LOG(INFO) << "got past accept";
238 if (client_fd < 0) 241 if (client_fd < 0)
239 LOG(FATAL) << "ERROR on accept"; 242 LOG(FATAL) << "ERROR on accept";
240 HandleConnection(client_fd); 243 HandleConnection(client_fd);
241 } 244 }
242 return 0; 245 return 0;
243 } 246 }
OLDNEW
« no previous file with comments | « libcurl_http_fetcher.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698