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

Side by Side Diff: runtime/bin/vmstats_impl.cc

Issue 12377099: Added support for "bin-ified" vmstats web app source files (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 9 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
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "bin/vmstats_impl.h" 5 #include "bin/vmstats_impl.h"
6 6
7 #include <sstream> 7 #include <sstream>
8 8
9 #include "bin/file.h" 9 #include "bin/file.h"
10 #include "bin/log.h" 10 #include "bin/log.h"
11 #include "bin/platform.h" 11 #include "bin/platform.h"
12 #include "bin/resources.h"
12 #include "bin/socket.h" 13 #include "bin/socket.h"
13 #include "bin/thread.h" 14 #include "bin/thread.h"
14 #include "bin/utils.h" 15 #include "bin/utils.h"
15 #include "include/dart_debugger_api.h" 16 #include "include/dart_debugger_api.h"
16 #include "platform/json.h" 17 #include "platform/json.h"
17 18
18 #define BUFSIZE 8192 19 #define BUFSIZE 8192
19 #define RETRY_PAUSE 100 // milliseconds 20 #define RETRY_PAUSE 100 // milliseconds
20 21
21 static const char* INDEX_HTML = "index.html"; 22 static const char* INDEX_HTML = "index.html";
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 return "image/png"; 126 return "image/png";
126 } 127 }
127 if (!strcmp(suffix, ".jpg") || !strcmp(suffix, ".jpeg")) { 128 if (!strcmp(suffix, ".jpg") || !strcmp(suffix, ".jpeg")) {
128 return "image/jpeg"; 129 return "image/jpeg";
129 } 130 }
130 } 131 }
131 return "text/plain"; 132 return "text/plain";
132 } 133 }
133 134
134 135
136 void writeResponse(intptr_t socket, const char* content_type,
137 const char* data, size_t length) {
138 char buffer[BUFSIZE + 1];
139 snprintf(buffer, BUFSIZE,
140 "HTTP/1.1 200 OK\nContent-Type: %s\nContent-Length: %"Pu"\n\n",
141 content_type, length);
142 Socket::Write(socket, buffer, strlen(buffer));
143 Socket::Write(socket, data, length);
144 Socket::Write(socket, "\n", 1);
145 }
146
147
148 void writeErrorResponse(intptr_t socket, int error_num, const char* error,
149 const char* description) {
150 char buffer[BUFSIZE + 1];
151 if (description != NULL) {
152 // Create body first, so its length is known when creating the header.
153 int body_len = snprintf(buffer, BUFSIZE,
154 "<html><head><title>%d %s</title></head>\n"
155 "<body><h1>%s</h1>\n%s\n</body></html>\n",
156 error_num, error, error, description);
157 char* body = strdup(buffer);
158 int len = snprintf(buffer, BUFSIZE,
159 "HTTP/1.1 %d %s\n"
160 "Content-Length: %d\n"
161 "Connection: close\n"
162 "Content-Type: text/html\n\n",
163 error_num, error, body_len);
164 Socket::Write(socket, buffer, len);
165 Socket::Write(socket, body, body_len);
166 free(body);
167 } else {
168 int len = snprintf(buffer, BUFSIZE, "HTTP/1.1 %d %s\n\n",
169 error_num, error);
170 Socket::Write(socket, buffer, len);
171 }
172 }
173
174
135 void VmStats::WebServer(uword bind_address) { 175 void VmStats::WebServer(uword bind_address) {
136 while (true) { 176 while (true) {
137 intptr_t socket = ServerSocket::Accept(bind_address); 177 intptr_t socket = ServerSocket::Accept(bind_address);
138 if (socket == ServerSocket::kTemporaryFailure) { 178 if (socket == ServerSocket::kTemporaryFailure) {
139 // Not a real failure, woke up but no connection available. 179 // Not a real failure, woke up but no connection available.
140 180
141 // Use MonitorLocker.Wait(), since it has finer granularity than sleep(). 181 // Use MonitorLocker.Wait(), since it has finer granularity than sleep().
142 dart::Monitor m; 182 dart::Monitor m;
143 MonitorLocker ml(&m); 183 MonitorLocker ml(&m);
144 ml.Wait(RETRY_PAUSE); 184 ml.Wait(RETRY_PAUSE);
(...skipping 15 matching lines...) Expand all
160 if (len <= 0) { 200 if (len <= 0) {
161 // Invalid HTTP request, ignore. 201 // Invalid HTTP request, ignore.
162 continue; 202 continue;
163 } 203 }
164 buffer[len] = '\0'; 204 buffer[len] = '\0';
165 205
166 // Verify it's a GET request. 206 // Verify it's a GET request.
167 // TODO(tball): support POST requests. 207 // TODO(tball): support POST requests.
168 if (strncmp("GET ", buffer, 4) != 0 && strncmp("get ", buffer, 4) != 0) { 208 if (strncmp("GET ", buffer, 4) != 0 && strncmp("get ", buffer, 4) != 0) {
169 Log::PrintErr("Unsupported HTTP request type"); 209 Log::PrintErr("Unsupported HTTP request type");
170 const char* response = "HTTP/1.1 403 Forbidden\n" 210 writeErrorResponse(socket, 403, "Forbidden",
171 "Content-Length: 120\n" 211 "Unsupported HTTP request type");
172 "Connection: close\n"
173 "Content-Type: text/html\n\n"
174 "<html><head>\n<title>403 Forbidden</title>\n</head>"
175 "<body>\n<h1>Forbidden</h1>\nUnsupported HTTP request type\n</body>"
176 "</html>\n";
177 Socket::Write(socket, response, strlen(response));
178 Socket::Close(socket); 212 Socket::Close(socket);
179 continue; 213 continue;
180 } 214 }
181 215
182 // Extract GET URL, and null-terminate URL in case request line has 216 // Extract GET URL, and null-terminate URL in case request line has
183 // HTTP version. 217 // HTTP version.
184 for (int i = 4; i < len; i++) { 218 for (int i = 4; i < len; i++) {
185 if (buffer[i] == ' ') { 219 if (buffer[i] == ' ') {
186 buffer[i] = '\0'; 220 buffer[i] = '\0';
187 } 221 }
188 } 222 }
189 char* url = &buffer[4]; 223 char* url = strdup(&buffer[4]);
190 224
191 Log::Print("vmstats: %s requested\n", url); 225 Log::Print("vmstats: %s requested\n", url);
192 char* content = NULL; 226 char* content = NULL;
193 227
194 // Check for VmStats-specific URLs. 228 // Check for VmStats-specific URLs.
195 if (strcmp(url, "/isolates") == 0) { 229 if (strcmp(url, "/isolates") == 0) {
196 content = instance_->IsolatesStatus(); 230 content = instance_->IsolatesStatus();
197 } else { 231 } else {
198 // Check plug-ins. 232 // Check plug-ins.
199 content = VmStatusService::GetVmStatus(url); 233 content = VmStatusService::GetVmStatus(url);
200 } 234 }
201 235
202 if (content != NULL) { 236 if (content != NULL) {
203 size_t content_len = strlen(content); 237 writeResponse(socket, "application/json", content, strlen(content));
204 len = snprintf(buffer, BUFSIZE,
205 "HTTP/1.1 200 OK\nContent-Type: application/json; charset=UTF-8\n"
206 "Content-Length: %"Pu"\n\n",
207 content_len);
208 Socket::Write(socket, buffer, strlen(buffer));
209 Socket::Write(socket, content, content_len);
210 Socket::Write(socket, "\n", 1);
211 Socket::Write(socket, buffer, strlen(buffer));
212 free(content); 238 free(content);
213 } else { 239 } else {
214 // No status content with this URL, return file or resource content. 240 // No status content with this URL, return file or resource content.
215 std::string path(instance_->root_directory_); 241 std::string path(instance_->root_directory_);
216 path.append(url); 242 path.append(url);
217 243
218 // Expand directory URLs. 244 // Expand directory URLs.
219 if (strcmp(url, "/") == 0) { 245 if (strcmp(url, "/") == 0) {
220 path.append(VMSTATS_HTML); 246 path.append(VMSTATS_HTML);
221 } else if (url[strlen(url) - 1] == '/') { 247 } else if (url[strlen(url) - 1] == '/') {
222 path.append(INDEX_HTML); 248 path.append(INDEX_HTML);
223 } 249 }
224 250
225 bool success = false; 251 bool success = false;
252 char* text_buffer = NULL;
253 const char* content_type = ContentType(path.c_str());
226 if (File::Exists(path.c_str())) { 254 if (File::Exists(path.c_str())) {
227 File* f = File::Open(path.c_str(), File::kRead); 255 File* f = File::Open(path.c_str(), File::kRead);
228 if (f != NULL) { 256 if (f != NULL) {
229 intptr_t len = f->Length(); 257 intptr_t len = f->Length();
230 char* text_buffer = reinterpret_cast<char*>(malloc(len)); 258 text_buffer = reinterpret_cast<char*>(malloc(len));
231 if (f->ReadFully(text_buffer, len)) { 259 if (f->ReadFully(text_buffer, len)) {
232 const char* content_type = ContentType(path.c_str()); 260 writeResponse(socket, content_type, text_buffer, len);
233 snprintf(buffer, BUFSIZE,
234 "HTTP/1.1 200 OK\nContent-Type: %s\n"
235 "Content-Length: %"Pu"\n\n",
236 content_type, len);
237 Socket::Write(socket, buffer, strlen(buffer));
238 Socket::Write(socket, text_buffer, len);
239 Socket::Write(socket, "\n", 1);
240 success = true; 261 success = true;
241 } 262 }
242 free(text_buffer); 263 free(text_buffer);
243 delete f; 264 delete f;
244 } 265 }
245 } else { 266 } else {
246 // TODO(tball): look up linked in resource. 267 const char* resource;
268 intptr_t len = Resources::ResourceLookup(path.c_str(), &resource);
269 if (len != Resources::kNoSuchInstance) {
270 ASSERT(len >= 0);
271 writeResponse(socket, content_type, resource, len);
272 success = true;
273 }
247 } 274 }
248 if (!success) { 275 if (!success) {
249 const char* response = "HTTP/1.1 404 Not Found\n\n"; 276 snprintf(buffer, BUFSIZE,
250 Socket::Write(socket, response, strlen(response)); 277 "URL <a href=\"%s\">%s</a> not found.", url, url);
278 writeErrorResponse(socket, 404, "Not Found", buffer);
251 } 279 }
252 } 280 }
253 Socket::Close(socket); 281 Socket::Close(socket);
282 free(url);
254 } 283 }
255 284
256 Shutdown(); 285 Shutdown();
257 } 286 }
258 287
259 288
260 char* VmStats::IsolatesStatus() { 289 char* VmStats::IsolatesStatus() {
261 std::ostringstream stream; 290 std::ostringstream stream;
262 stream << '{' << std::endl; 291 stream << '{' << std::endl;
263 stream << "\"isolates\": [" << std::endl; 292 stream << "\"isolates\": [" << std::endl;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 VmStatusPlugin* plugin = instance_->registered_plugin_list_; 352 VmStatusPlugin* plugin = instance_->registered_plugin_list_;
324 while (plugin != NULL) { 353 while (plugin != NULL) {
325 char* result = (plugin->callback())(request); 354 char* result = (plugin->callback())(request);
326 if (result != NULL) { 355 if (result != NULL) {
327 return result; 356 return result;
328 } 357 }
329 plugin = plugin->next(); 358 plugin = plugin->next();
330 } 359 }
331 return NULL; 360 return NULL;
332 } 361 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698