We got nominated! Help us out and vote for GitHub as Best Bootstrapped Startup of 2008. (You can vote once a day.) [ hide ]

public
Description: Phusion Passenger (mod_rails)
Homepage: http://www.modrails.com/
Clone URL: git://github.com/FooBarWidget/passenger.git
Click here to lend your support to: passenger and make a donation at www.pledgie.com !
Update DummyRequestHandler and DummySpawnManager with the previously made 
architectural changes.
Hongli Lai (Phusion) (author)
Sun Feb 03 13:47:49 -0800 2008
commit  99b0dd9a9343ae0b619cadf421f8c91d4a675a4c
tree    7f8b9acc2293a7c66143543dbd64785cc8d44bda
parent  84440709d56b6a5a6ef64fb8eafbf1868bf63118
...
1
2
3
 
 
4
5
6
7
8
9
10
 
11
12
13
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
18
19
20
21
22
23
24
25
26
27
 
 
 
 
 
 
28
29
30
31
32
 
33
34
35
36
37
38
39
40
41
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
44
45
46
47
48
49
50
51
52
53
 
54
55
56
...
1
2
3
4
5
6
7
8
9
 
 
 
10
11
 
 
 
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
 
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
 
 
 
 
 
 
 
64
65
66
67
68
69
70
71
72
73
 
74
75
 
 
 
 
 
 
 
 
 
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
 
 
106
107
108
 
109
110
111
112
0
@@ -1,56 +1,112 @@
0
 #include "MessageChannel.h"
0
 #include "Utils.cpp"
0
 #include <vector>
0
+#include <unistd.h>
0
+#include <errno.h>
0
 
0
 using namespace std;
0
 using namespace Passenger;
0
 
0
-static bool
0
-handleRequest(MessageChannel &reader, MessageChannel &writer) {
0
- vector<string> headers;
0
+typedef vector< pair<string, string> > HeaderSet;
0
 
0
- P_TRACE("Reading request headers");
0
- if (!reader.read(headers)) {
0
- return true;
0
+static void
0
+readHeaders(int reader, HeaderSet &headers) {
0
+ string buffer;
0
+ char buffer2[1024 * 32];
0
+ buffer.reserve(1024 * 32);
0
+ while (true) {
0
+ ssize_t ret = read(reader, buffer2, sizeof(buffer2));
0
+ if (ret == 0) {
0
+ break;
0
+ } else {
0
+ buffer.append(buffer2, ret);
0
+ }
0
+ }
0
+
0
+ string::size_type start = 0;
0
+ string::size_type pos;
0
+ while (true) {
0
+ pos = buffer.find('\0', start);
0
+ if (pos != string::npos) {
0
+ string name(buffer.substr(start, pos - start));
0
+ start = pos + 1;
0
+ pos = buffer.find('\0', start);
0
+ string value(buffer.substr(start, pos - start));
0
+ start = pos + 1;
0
+ headers.push_back(make_pair(name, value));
0
+ } else {
0
+ break;
0
+ }
0
   }
0
- P_TRACE("Done reading request headers");
0
+}
0
+
0
+static void
0
+writeString(int writer, const string &str) {
0
+ ssize_t ret;
0
+ unsigned int written = 0;
0
+ do {
0
+ do {
0
+ ret = write(writer, str.c_str() + written, str.size() - written);
0
+ } while (ret == -1 && errno == EINTR);
0
+ written += ret;
0
+ } while (written < str.size());
0
+}
0
+
0
+static void
0
+processRequest(int reader, int writer) {
0
+ HeaderSet headers;
0
+ readHeaders(reader, headers);
0
+ close(reader);
0
   
0
   string content;
0
   content.reserve(1024 * 7);
0
   content += "<b>Using C++ DummyRequestHandler</b><br>\n";
0
- unsigned int i;
0
- for (i = 0; i < headers.size(); i += 2) {
0
- content += "<tt>";
0
- content += headers[i];
0
- content += " = ";
0
- content += headers[i + 1];
0
- content += "</tt><br>\n";
0
+ for (HeaderSet::const_iterator it(headers.begin()); it != headers.end(); it++) {
0
+ content.append("<tt>");
0
+ content.append(it->first);
0
+ content.append(" = ");
0
+ content.append(it->second);
0
+ content.append("</tt><br>\n");
0
   }
0
   
0
   string header;
0
   header.reserve(512);
0
- header += "Status: 200 OK\r\n"
0
+ header.append("Status: 200 OK\r\n"
0
     "Content-Type: text/html\r\n"
0
- "Content-Length: ";
0
- header += toString(content.size());
0
- header += "\r\n\r\n";
0
- P_TRACE("Sending response header");
0
- writer.writeScalar(header);
0
- P_TRACE("Sending response content");
0
- writer.writeScalar(content);
0
- P_TRACE("All done");
0
- writer.writeScalar("", 0);
0
+ "Content-Length: ");
0
+ header.append(toString(content.size()));
0
+ header.append("\r\n\r\n");
0
+
0
+ writeString(writer, header);
0
+ writeString(writer, content);
0
+ close(writer);
0
+}
0
+
0
+static bool
0
+acceptNextRequest(int fd) {
0
+ char c;
0
+ if (read(fd, &c, 1) == 0) {
0
+ return true;
0
+ }
0
+
0
+ MessageChannel listener(fd);
0
+ int fd1[2], fd2[2];
0
+ pipe(fd1);
0
+ pipe(fd2);
0
+ listener.writeFileDescriptor(fd1[0]);
0
+ listener.writeFileDescriptor(fd2[1]);
0
+ close(fd1[0]);
0
+ close(fd2[1]);
0
+ processRequest(fd2[0], fd1[1]);
0
   return false;
0
 }
0
 
0
 int
0
 main() {
0
- MessageChannel reader(STDIN_FILENO);
0
- MessageChannel writer(STDOUT_FILENO);
0
   bool done = false;
0
   initDebugging();
0
   while (!done) {
0
- done = handleRequest(reader, writer);
0
+ done = acceptNextRequest(STDIN_FILENO);
0
   }
0
   return 0;
0
 }
...
34
35
36
37
 
38
39
40
41
42
43
44
45
46
 
 
47
48
49
50
51
52
53
54
55
56
57
 
 
 
58
59
60
...
68
69
70
71
72
73
74
 
 
75
76
77
78
79
80
81
82
 
83
84
 
85
86
87
...
34
35
36
 
37
38
39
 
 
 
 
 
 
 
40
41
42
43
44
45
46
 
 
 
 
 
 
47
48
49
50
51
52
...
60
61
62
 
 
 
 
63
64
65
66
 
 
 
 
 
 
67
68
 
69
70
71
72
0
@@ -34,27 +34,19 @@ using namespace std;
0
 class DummySpawnManager {
0
 public:
0
   ApplicationPtr spawn(const string &appRoot, const string &user = "", const string &group = "") {
0
- int fd1[2], fd2[2];
0
+ int fds[2];
0
     pid_t pid;
0
     
0
- if (pipe(fd1) == -1) {
0
- throw SystemException("Cannot create a pipe", errno);
0
- }
0
- if (pipe(fd2) == -1) {
0
- close(fd1[0]);
0
- close(fd1[1]);
0
- throw SystemException("Cannot create a pipe", errno);
0
+ if(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == -1) {
0
+ throw SystemException("Cannot create a Unix socket", errno);
0
     }
0
     pid = fork();
0
     if (pid == 0) {
0
       pid = fork();
0
       if (pid == 0) {
0
- dup2(fd1[0], 0);
0
- dup2(fd2[1], 1);
0
- close(fd1[0]);
0
- close(fd1[1]);
0
- close(fd2[0]);
0
- close(fd2[1]);
0
+ dup2(fds[0], STDIN_FILENO);
0
+ close(fds[0]);
0
+ close(fds[1]);
0
         execlp(DUMMY_REQUEST_HANDLER_EXECUTABLE, DUMMY_REQUEST_HANDLER_EXECUTABLE, NULL);
0
         int e = errno;
0
         fprintf(stderr, "Unable to run %s: %s\n", DUMMY_REQUEST_HANDLER_EXECUTABLE, strerror(e));
0
@@ -68,20 +60,13 @@ public:
0
         _exit(0);
0
       }
0
     } else if (pid == -1) {
0
- close(fd1[0]);
0
- close(fd1[1]);
0
- close(fd2[0]);
0
- close(fd2[1]);
0
+ close(fds[0]);
0
+ close(fds[1]);
0
       throw SystemException("Cannot fork a new process", errno);
0
     } else {
0
- int reader, writer;
0
-
0
- close(fd1[0]);
0
- close(fd2[1]);
0
- reader = fd2[0];
0
- writer = fd1[1];
0
+ close(fds[0]);
0
       waitpid(pid, NULL, 0);
0
- return ApplicationPtr(new Application(appRoot, pid, reader, writer));
0
+ return ApplicationPtr(new Application(appRoot, pid, fds[1]));
0
     }
0
   }
0
 };
...
1
2
3
4
 
5
6
7
...
1
2
3
 
4
5
6
7
0
@@ -1,7 +1,7 @@
0
 APXS=apxs2
0
 APACHECTL=apache2ctl
0
 CXX=g++
0
-CXXFLAGS=-Wall -fPIC -g -DPASSENGER_DEBUG `pkg-config --cflags apr-1 apr-util-1` `$(APXS) -q CFLAGS` -I`$(APXS) -q INCLUDEDIR`
0
+CXXFLAGS=-Wall -fPIC -g -DPASSENGER_DEBUG -DPASSENGER_USE_DUMMY_SPAWN_MANAGER `pkg-config --cflags apr-1 apr-util-1` `$(APXS) -q CFLAGS` -I`$(APXS) -q INCLUDEDIR`
0
 OBJECTS=Configuration.o Hooks.o Utils.o
0
 LIBTOOL_OBJECTS=Configuration.o,Hooks.o,Utils.o
0
 

Comments

    No one has commented yet.