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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « remoting/run_all_unittests.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')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2010 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 // Simple webserver that returns empty content with the requested mimetype.
6 //
7 // For example:
8 // http://localhost:8080/pepper-application/x-chromoting-plugin
9 // Will return empty content, but with the requested mimetype:
10 // Content-Type: pepper-application/x-chromoting-plugin
11 //
12 // This is useful for testing the Chromoting plugin while we wait for
13 // updated mimetype support to be added to Chrome.
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <sys/wait.h>
19 #include <netinet/in.h>
20
21 #define PORT 8080
22
23 void error(const char *msg) {
24 fprintf(stderr, "ERROR - %s\n", msg);
25 exit(1);
26 }
27
28 // Read text data from a socket to a buffer.
29 // Data up to the next \n char is read into the buffer.
30 void read_text_data(int sock, char *buffer, int buffsize) {
31 int num_bytes;
32 *buffer = '\0';
33
34 for (num_bytes = 1; num_bytes < buffsize-1; num_bytes++) {
35 char ch;
36
37 int num_bytes_read = read(sock, &ch, 1);
38 if (num_bytes_read == 1) {
39 if (ch == '\n') {
40 break;
41 }
42 *buffer++ = ch;
43 } else if (num_bytes_read == 0) {
44 break;
45 } else {
46 error("read_text_data failed");
47 }
48 }
49 *buffer++ = '\0';
50 }
51
52 // Write data from a null-terminated buffer to a socket.
53 void write_data(int sock, const char *buffer) {
54 int num_bytes = strlen(buffer);
55
56 while (num_bytes > 0) {
57 int num_bytes_written = write(sock, buffer, num_bytes);
58 if (num_bytes_written <= 0) {
59 error("write_data failed");
60 }
61 num_bytes -= num_bytes_written;
62 buffer += num_bytes_written;
63 }
64 }
65
66 void handle_request(int connection) {
67 printf("Handling request...\n");
68 char buffer[512];
69 buffer[0] = '\0';
70
71 // Read the first line of the request. This will be something like:
72 // GET /index.html HTTP/1.1
73 read_text_data(connection, buffer, 512);
74
75 char *saveptr;
76 char *request = strtok_r(buffer, " ", &saveptr);
77 char *resource = strtok_r(NULL, " ", &saveptr);
78 char *version = strtok_r(NULL, " ", &saveptr);
79
80 char mime_type[512];
81 strncpy(mime_type, &resource[1], 511);
82 mime_type[511] = '\0';
83
84 if (strcmp(request, "GET")) {
85 printf("Unknown request: 'GET %s %s'\n", request, version);
86 } else {
87 printf("Requesting '%s'\n", mime_type);
88 }
89
90 // Keep reading until we encounter a blank line.
91 // This will skip over the Host, Connection, User-Agent, ...
92 char ignore[512] = "ignore";
93 while (strspn(ignore, " \n\r\t") != strlen(ignore)) {
94 read_text_data(connection, ignore, sizeof(ignore));
95 }
96
97 // At this point, a normal webserver would verify that the requested
98 // resource exists and then return it with the appropriate mimetype.
99
100 // However, we return empty content, but with the requested plugin mimetype.
101 write_data(connection, "HTTP/1.0 200 OK\r\n");
102 write_data(connection, "Content-Type: ");
103 write_data(connection, mime_type);
104 write_data(connection, "\r\n\r\n");
105
106 // This dummy data is unused, but must be present or else the reader may hang.
107 write_data(connection, "Data\n");
108 }
109
110 int main(int argc, char *argv[]) {
111 printf("Chromoting client webserver: http://localhost:%d\n", PORT);
112
113 signal(SIGCHLD, SIG_IGN);
114
115 // Create socket.
116 int sock = socket(AF_INET, SOCK_STREAM, 0);
117 if (sock < 0) {
118 error("Unable to open socket");
119 }
120
121 // Initialize socket address struct.
122 struct sockaddr_in serv_addr;
123 bzero((char*)&serv_addr, sizeof(serv_addr));
124 serv_addr.sin_family = AF_INET;
125 serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
126 serv_addr.sin_port = htons(PORT);
127
128 // Bind socket.
129 if (bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
130 error("Unable to bind socket");
131 }
132
133 if (listen(sock, 5) < 0) {
134 error("Unable to listen to socket");
135 }
136
137 while (1) {
138 int connection = accept(sock, NULL, NULL);
139 if (connection < 0) {
140 error("Unable to accept connection");
141 }
142
143 pid_t pid = fork();
144 if (pid == 0) {
145 // Child process.
146 if (close(sock) < 0) {
147 error("Unable to close socket in child");
148 }
149
150 // Handle the request.
151 handle_request(connection);
152
153 // Success. Exit to kill child process.
154 exit(0);
155 } else {
156 // Parent process.
157 if (close(connection) < 0) {
158 error("Unable to close connection in parent");
159 }
160 }
161 }
162
163 return 0;
164 }
OLDNEW
« 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