Chromium Code Reviews| Index: runtime/bin/vmstats_impl.cc |
| =================================================================== |
| --- runtime/bin/vmstats_impl.cc (revision 19518) |
| +++ runtime/bin/vmstats_impl.cc (working copy) |
| @@ -9,6 +9,7 @@ |
| #include "bin/file.h" |
| #include "bin/log.h" |
| #include "bin/platform.h" |
| +#include "bin/resources.h" |
| #include "bin/socket.h" |
| #include "bin/thread.h" |
| #include "bin/utils.h" |
| @@ -132,6 +133,45 @@ |
| } |
| +void writeResponse(intptr_t socket, const char* content_type, |
| + const char* data, size_t length) { |
| + char buffer[BUFSIZE + 1]; |
| + snprintf(buffer, BUFSIZE, |
| + "HTTP/1.1 200 OK\nContent-Type: %s\nContent-Length: %"Pu"\n\n", |
| + content_type, length); |
| + Socket::Write(socket, buffer, strlen(buffer)); |
| + Socket::Write(socket, data, length); |
| + Socket::Write(socket, "\n", 1); |
| +} |
| + |
| + |
| +void writeErrorResponse(intptr_t socket, int error_num, const char* error, |
| + const char* description) { |
| + char buffer[BUFSIZE + 1]; |
|
siva
2013/03/06 06:32:20
Do you really need 8k of stack space to write send
Tom Ball
2013/03/06 17:47:17
Added printf function that malloc's the necessary
|
| + if (description != NULL) { |
| + // Create body first, so its length is known when creating the header. |
| + int body_len = snprintf(buffer, BUFSIZE, |
|
srdjan
2013/03/06 01:14:37
s/int/intptr_t/
(also below for len).
Tom Ball
2013/03/06 17:47:17
Done.
|
| + "<html><head><title>%d %s</title></head>\n" |
| + "<body><h1>%s</h1>\n%s\n</body></html>\n", |
| + error_num, error, error, description); |
| + char* body = strdup(buffer); |
| + int len = snprintf(buffer, BUFSIZE, |
| + "HTTP/1.1 %d %s\n" |
| + "Content-Length: %d\n" |
| + "Connection: close\n" |
| + "Content-Type: text/html\n\n", |
| + error_num, error, body_len); |
| + Socket::Write(socket, buffer, len); |
| + Socket::Write(socket, body, body_len); |
| + free(body); |
| + } else { |
| + int len = snprintf(buffer, BUFSIZE, "HTTP/1.1 %d %s\n\n", |
| + error_num, error); |
| + Socket::Write(socket, buffer, len); |
| + } |
| +} |
| + |
| + |
| void VmStats::WebServer(uword bind_address) { |
| while (true) { |
| intptr_t socket = ServerSocket::Accept(bind_address); |
| @@ -167,14 +207,8 @@ |
| // TODO(tball): support POST requests. |
| if (strncmp("GET ", buffer, 4) != 0 && strncmp("get ", buffer, 4) != 0) { |
| Log::PrintErr("Unsupported HTTP request type"); |
| - const char* response = "HTTP/1.1 403 Forbidden\n" |
| - "Content-Length: 120\n" |
| - "Connection: close\n" |
| - "Content-Type: text/html\n\n" |
| - "<html><head>\n<title>403 Forbidden</title>\n</head>" |
| - "<body>\n<h1>Forbidden</h1>\nUnsupported HTTP request type\n</body>" |
| - "</html>\n"; |
| - Socket::Write(socket, response, strlen(response)); |
| + writeErrorResponse(socket, 403, "Forbidden", |
| + "Unsupported HTTP request type"); |
| Socket::Close(socket); |
| continue; |
| } |
| @@ -186,7 +220,7 @@ |
| buffer[i] = '\0'; |
| } |
| } |
| - char* url = &buffer[4]; |
| + char* url = strdup(&buffer[4]); |
| Log::Print("vmstats: %s requested\n", url); |
| char* content = NULL; |
| @@ -200,15 +234,7 @@ |
| } |
| if (content != NULL) { |
| - size_t content_len = strlen(content); |
| - len = snprintf(buffer, BUFSIZE, |
| - "HTTP/1.1 200 OK\nContent-Type: application/json; charset=UTF-8\n" |
| - "Content-Length: %"Pu"\n\n", |
| - content_len); |
| - Socket::Write(socket, buffer, strlen(buffer)); |
| - Socket::Write(socket, content, content_len); |
| - Socket::Write(socket, "\n", 1); |
| - Socket::Write(socket, buffer, strlen(buffer)); |
| + writeResponse(socket, "application/json", content, strlen(content)); |
| free(content); |
| } else { |
| // No status content with this URL, return file or resource content. |
| @@ -223,34 +249,37 @@ |
| } |
| bool success = false; |
| + char* text_buffer = NULL; |
| + const char* content_type = ContentType(path.c_str()); |
| if (File::Exists(path.c_str())) { |
| File* f = File::Open(path.c_str(), File::kRead); |
| if (f != NULL) { |
| intptr_t len = f->Length(); |
| - char* text_buffer = reinterpret_cast<char*>(malloc(len)); |
| + text_buffer = reinterpret_cast<char*>(malloc(len)); |
| if (f->ReadFully(text_buffer, len)) { |
| - const char* content_type = ContentType(path.c_str()); |
| - snprintf(buffer, BUFSIZE, |
| - "HTTP/1.1 200 OK\nContent-Type: %s\n" |
| - "Content-Length: %"Pu"\n\n", |
| - content_type, len); |
| - Socket::Write(socket, buffer, strlen(buffer)); |
| - Socket::Write(socket, text_buffer, len); |
| - Socket::Write(socket, "\n", 1); |
| + writeResponse(socket, content_type, text_buffer, len); |
| success = true; |
| } |
| free(text_buffer); |
| delete f; |
| } |
| } else { |
| - // TODO(tball): look up linked in resource. |
| + const char* resource; |
| + intptr_t len = Resources::ResourceLookup(path.c_str(), &resource); |
| + if (len != Resources::kNoSuchInstance) { |
| + ASSERT(len >= 0); |
| + writeResponse(socket, content_type, resource, len); |
| + success = true; |
| + } |
| } |
| if (!success) { |
| - const char* response = "HTTP/1.1 404 Not Found\n\n"; |
| - Socket::Write(socket, response, strlen(response)); |
| + snprintf(buffer, BUFSIZE, |
| + "URL <a href=\"%s\">%s</a> not found.", url, url); |
| + writeErrorResponse(socket, 404, "Not Found", buffer); |
| } |
| } |
| Socket::Close(socket); |
| + free(url); |
| } |
| Shutdown(); |