ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/Smersh/Daemon.cpp
(Generate patch)

Comparing Smersh/Daemon.cpp (file contents):
Revision 174 by Douglas Thrift, 2004-06-21T20:16:43-07:00 vs.
Revision 175 by Douglas Thrift, 2004-06-25T01:10:49-07:00

# Line 6 | Line 6
6  
7   #include "Daemon.hpp"
8  
9 + string Daemon::crlf("\r\n");
10 +
11   void Daemon::serve(int port, bool fork, Daemon* self)
12   {
13          api::TcpSocket server;
# Line 40 | Line 42 | void Daemon::serve(int port, bool fork,
42          }
43   }
44  
45 + Daemon::Status Daemon::request(istream& sin, Environment& env, ostream& post,
46 +        ostream& log)
47 + {
48 +        string line;
49 +        Matcher request("^([A-Z]+) .*(\\?.+)? HTTP/(\\d+)\\.(\\d+)$");
50 +
51 +        getline(sin, line);
52 +
53 +        log << '"' << line << "\" ";
54 +
55 +        if (line == request)
56 +        {
57 +                if (lexical_cast<unsigned>(request[request.size() > 4 ? 3 : 2]) > 1)
58 +                        return version;
59 +
60 +                Matcher matcher;
61 +
62 +                if (request[1] != matcher("^GET|HEAD|POST$")) return notImplemented;
63 +
64 +                env.set("REQUEST_METHOD", matcher[0]);
65 +
66 +                if (request.size() > 4) env.set("QUERY_STRING", request[2].substr(1));
67 +
68 +                do
69 +                {
70 +                        getline(sin, line);
71 +
72 +                        if (line.empty()) break;
73 +
74 +                        istringstream input(line);
75 +                        string name, value;
76 +
77 +                        ::getline(input, name, ':');
78 +                        getline(input, value);
79 +
80 +                        for (char next(sin.peek()); next == ' ' || next == '\t'; next =
81 +                                sin.peek())
82 +                        {
83 +                                getline(sin, line);
84 +
85 +                                value += ' ' + line;
86 +                        }
87 +
88 +                        matcher("^\\s*?(.+)\\s*?$");
89 +
90 +                        if (name == "Content-Length")
91 +                        {
92 +                                if (value == matcher) env.set("CONTENT_LENGTH", matcher[1]);
93 +                        }
94 +                        else if (name == "Content-Type")
95 +                        {
96 +                                if (value == matcher) env.set("CONTENT_TYPE", matcher[1]);
97 +                        }
98 +                        else if (name == "Referer")
99 +                        {
100 +                                if (value == matcher) env.set("HTTP_REFERER", matcher[1]);
101 +                        }
102 +                        else if (name == "User-Agent")
103 +                        {
104 +                                if (value == matcher) env.set("HTTP_USER_AGENT", matcher[1]);
105 +                        }
106 +
107 +                        cerr << name << ':' << value << '\n';
108 +                }
109 +                while (sin.good());
110 +
111 +                if (request[0] == "POST")
112 +                {
113 +                        string contentLength(env.get("CONTENT_LENGTH"));
114 +                        
115 +                        if (env.get("CONTENT_TYPE") != "application/x-www-form-urlencoded")
116 +                                return mediaType;
117 +                        if (contentLength.empty()) return lengthRequired;
118 +
119 +                        streamsize length(lexical_cast<streamsize>(contentLength));
120 +                        char* content(new char[length]);
121 +
122 +                        sin.read(content, length);
123 +                        post.write(content, length);
124 +
125 +                        delete [] content;
126 +                }
127 +
128 +                return ok;
129 +        }
130 +
131 +        return notFound;
132 + }
133 +
134 + void Daemon::status(ostream& sout, Status status)
135 + {
136 +        sout << "HTTP/1.1 " << status << ' ';
137 +
138 +        switch (status)
139 +        {
140 +        case ok:
141 +                sout << "OK";
142 +                break;
143 +        case found:
144 +                sout << "Found";
145 +                break;
146 +        case seeOther:
147 +                sout << "See Other";
148 +                break;
149 +        case bad:
150 +                sout << "Bad Request";
151 +                break;
152 +        case notFound:
153 +                sout << "Not Found";
154 +                break;
155 +        case lengthRequired:
156 +                sout << "Length Required";
157 +                break;
158 +        case mediaType:
159 +                sout << "Unsupported Media Type";
160 +                break;
161 +        case error:
162 +                sout << "Internal Server Error";
163 +                break;
164 +        case notImplemented:
165 +                sout << "Not Implemented";
166 +                break;
167 +        case version:
168 +                sout << "HTTP Version not supported";
169 +        }
170 +
171 +        sout << crlf;
172 + }
173 +
174   int Daemon::handle(api::TcpSocket* client)
175   {
176          ios::InputOutputStreamBufAdapter adapter(*client);
177 <        iostream socket(&adapter);
177 >        iostream sio(&adapter);
178 >        Environment env;
179 >        stringstream post;
180 >        ostringstream log;
181 >        Status code(request(sio, env, post, log));
182 >
183 >        status(sio, code);
184 >
185 >        log << code << ' ' << 0 << " \"" << env.get("HTTP_REFERER") << "\" \""
186 >                << env.get("HTTP_USER_AGENT") << '"';
187  
188 <        //
188 >        if (debug) cerr << "log = " << log.str() << '\n';
189  
190          delete client;
191   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines