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

Unified Diff: remoting/tools/client_webserver/main.c

Issue 2690003: Copy the (early prototype of) remoting in Chrome into the public tree.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « remoting/run_all_unittests.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: remoting/tools/client_webserver/main.c
===================================================================
--- remoting/tools/client_webserver/main.c (revision 0)
+++ remoting/tools/client_webserver/main.c (revision 0)
@@ -0,0 +1,164 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Simple webserver that returns empty content with the requested mimetype.
+//
+// For example:
+// http://localhost:8080/pepper-application/x-chromoting-plugin
+// Will return empty content, but with the requested mimetype:
+// Content-Type: pepper-application/x-chromoting-plugin
+//
+// This is useful for testing the Chromoting plugin while we wait for
+// updated mimetype support to be added to Chrome.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <netinet/in.h>
+
+#define PORT 8080
+
+void error(const char *msg) {
+ fprintf(stderr, "ERROR - %s\n", msg);
+ exit(1);
+}
+
+// Read text data from a socket to a buffer.
+// Data up to the next \n char is read into the buffer.
+void read_text_data(int sock, char *buffer, int buffsize) {
+ int num_bytes;
+ *buffer = '\0';
+
+ for (num_bytes = 1; num_bytes < buffsize-1; num_bytes++) {
+ char ch;
+
+ int num_bytes_read = read(sock, &ch, 1);
+ if (num_bytes_read == 1) {
+ if (ch == '\n') {
+ break;
+ }
+ *buffer++ = ch;
+ } else if (num_bytes_read == 0) {
+ break;
+ } else {
+ error("read_text_data failed");
+ }
+ }
+ *buffer++ = '\0';
+}
+
+// Write data from a null-terminated buffer to a socket.
+void write_data(int sock, const char *buffer) {
+ int num_bytes = strlen(buffer);
+
+ while (num_bytes > 0) {
+ int num_bytes_written = write(sock, buffer, num_bytes);
+ if (num_bytes_written <= 0) {
+ error("write_data failed");
+ }
+ num_bytes -= num_bytes_written;
+ buffer += num_bytes_written;
+ }
+}
+
+void handle_request(int connection) {
+ printf("Handling request...\n");
+ char buffer[512];
+ buffer[0] = '\0';
+
+ // Read the first line of the request. This will be something like:
+ // GET /index.html HTTP/1.1
+ read_text_data(connection, buffer, 512);
+
+ char *saveptr;
+ char *request = strtok_r(buffer, " ", &saveptr);
+ char *resource = strtok_r(NULL, " ", &saveptr);
+ char *version = strtok_r(NULL, " ", &saveptr);
+
+ char mime_type[512];
+ strncpy(mime_type, &resource[1], 511);
+ mime_type[511] = '\0';
+
+ if (strcmp(request, "GET")) {
+ printf("Unknown request: 'GET %s %s'\n", request, version);
+ } else {
+ printf("Requesting '%s'\n", mime_type);
+ }
+
+ // Keep reading until we encounter a blank line.
+ // This will skip over the Host, Connection, User-Agent, ...
+ char ignore[512] = "ignore";
+ while (strspn(ignore, " \n\r\t") != strlen(ignore)) {
+ read_text_data(connection, ignore, sizeof(ignore));
+ }
+
+ // At this point, a normal webserver would verify that the requested
+ // resource exists and then return it with the appropriate mimetype.
+
+ // However, we return empty content, but with the requested plugin mimetype.
+ write_data(connection, "HTTP/1.0 200 OK\r\n");
+ write_data(connection, "Content-Type: ");
+ write_data(connection, mime_type);
+ write_data(connection, "\r\n\r\n");
+
+ // This dummy data is unused, but must be present or else the reader may hang.
+ write_data(connection, "Data\n");
+}
+
+int main(int argc, char *argv[]) {
+ printf("Chromoting client webserver: http://localhost:%d\n", PORT);
+
+ signal(SIGCHLD, SIG_IGN);
+
+ // Create socket.
+ int sock = socket(AF_INET, SOCK_STREAM, 0);
+ if (sock < 0) {
+ error("Unable to open socket");
+ }
+
+ // Initialize socket address struct.
+ struct sockaddr_in serv_addr;
+ bzero((char*)&serv_addr, sizeof(serv_addr));
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ serv_addr.sin_port = htons(PORT);
+
+ // Bind socket.
+ if (bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
+ error("Unable to bind socket");
+ }
+
+ if (listen(sock, 5) < 0) {
+ error("Unable to listen to socket");
+ }
+
+ while (1) {
+ int connection = accept(sock, NULL, NULL);
+ if (connection < 0) {
+ error("Unable to accept connection");
+ }
+
+ pid_t pid = fork();
+ if (pid == 0) {
+ // Child process.
+ if (close(sock) < 0) {
+ error("Unable to close socket in child");
+ }
+
+ // Handle the request.
+ handle_request(connection);
+
+ // Success. Exit to kill child process.
+ exit(0);
+ } else {
+ // Parent process.
+ if (close(connection) < 0) {
+ error("Unable to close connection in parent");
+ }
+ }
+ }
+
+ return 0;
+}
Property changes on: remoting/tools/client_webserver/main.c
___________________________________________________________________
Added: svn:eol-style
+ LF
« no previous file with comments | « remoting/run_all_unittests.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698