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 175 by Douglas Thrift, 2004-06-25T01:10:49-07:00 vs.
Revision 176 by Douglas Thrift, 2004-06-25T20:32:24-07:00

# Line 46 | Line 46 | Daemon::Status Daemon::request(istream&
46          ostream& log)
47   {
48          string line;
49 <        Matcher request("^([A-Z]+) .*(\\?.+)? HTTP/(\\d+)\\.(\\d+)$");
49 >        Matcher request("^([A-Z]+) .*?(\\?.+)? HTTP/(\\d+)\\.(\\d+)$");
50  
51          getline(sin, line);
52  
53          log << '"' << line << "\" ";
54  
55 +        env.put("HTTP_REFERER=-");
56 +        env.put("HTTP_USER_AGENT=-");
57 +
58          if (line == request)
59          {
60 <                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);
60 >                if (lexical_cast<unsigned>(request[3]) > 1) return version;
61  
62 <                        if (line.empty()) break;
62 >                Matcher method("^GET|HEAD|POST$");
63  
64 <                        istringstream input(line);
75 <                        string name, value;
64 >                if (request[1] != method) return notImplemented;
65  
66 <                        ::getline(input, name, ':');
78 <                        getline(input, value);
66 >                env.set("REQUEST_METHOD", method);
67  
68 <                        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 <                        }
68 >                if (!request[2].empty()) env.set("QUERY_STRING", request[2].substr(1));
69  
70 <                        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;
70 >                headers(sin, env);
71  
72 <                        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 <                }
72 >                if (method[0] == "POST") return message(sin, env, post);
73  
74                  return ok;
75          }
# Line 131 | Line 77 | Daemon::Status Daemon::request(istream&
77          return notFound;
78   }
79  
80 < void Daemon::status(ostream& sout, Status status)
80 > void Daemon::response(ostream& sout, Status status)
81   {
82          sout << "HTTP/1.1 " << status << ' ';
83  
# Line 158 | Line 104 | void Daemon::status(ostream& sout, Statu
104          case mediaType:
105                  sout << "Unsupported Media Type";
106                  break;
107 <        case error:
107 >        case serverError:
108                  sout << "Internal Server Error";
109                  break;
110          case notImplemented:
# Line 168 | Line 114 | void Daemon::status(ostream& sout, Statu
114                  sout << "HTTP Version not supported";
115          }
116  
117 +        sout << crlf << "Date: " << date() << crlf << "Server: Smersh/0.9" << crlf
118 +                << "Connection: close" << crlf;
119 + }
120 +
121 + void Daemon::error(ostream& sout, Status status)
122 + {
123          sout << crlf;
124   }
125  
126 + string Daemon::date(bool log)
127 + {
128 +        time_t now(time(NULL));
129 +        tm time;
130 +
131 +        if (log) localtime_r(&now, &time); else gmtime_r(&now, &time);
132 +
133 +        const char* format(log ? "[%m/%d/%Y:%T %z]" : "%a, %d %b %Y %T GMT");
134 +        char when[log ? 29 : 30];
135 +
136 +        strftime(when, log ? 29 : 30, format, &time);
137 +
138 +        return when;
139 + }
140 +
141   int Daemon::handle(api::TcpSocket* client)
142   {
143          ios::InputOutputStreamBufAdapter adapter(*client);
# Line 180 | Line 147 | int Daemon::handle(api::TcpSocket* clien
147          ostringstream log;
148          Status code(request(sio, env, post, log));
149  
150 <        status(sio, code);
150 >        response(sio, code);
151 >
152 >        if (code == ok)
153 >        {
154 >                ostringstream output;
155 >                Smersh smersh(post, output, env);
156 >                string content(output.str().substr(40));
157 >
158 >                sio << "Content-Length: " << content.length() << crlf
159 >                        << "Content-Type: text/html; charset=UTF-8" << crlf << crlf;
160 >
161 >                sio.write(content.data(), content.size());
162 >        }
163 >        else if (env.get("REQUEST_METHOD") != "HEAD") error(sio, code);
164 >        else sio << "Content-Type: text/html; charset=UTF-8" << crlf << crlf;
165  
166          log << code << ' ' << 0 << " \"" << env.get("HTTP_REFERER") << "\" \""
167                  << env.get("HTTP_USER_AGENT") << '"';
168  
169 <        if (debug) cerr << "log = " << log.str() << '\n';
169 >        if (debug) cerr << date(true) << ' ' << log.str() << '\n';
170  
171          delete client;
172   }
173 +
174 + void Daemon::headers(istream& sin, Environment& env)
175 + {
176 +        do
177 +        {
178 +                string line;
179 +
180 +                getline(sin, line);
181 +
182 +                if (line.empty()) break;
183 +
184 +                istringstream input(line);
185 +                string name, value;
186 +
187 +                ::getline(input, name, ':');
188 +                getline(input, value);
189 +
190 +                for (char next(sin.peek()); next == ' ' || next == '\t'; next =
191 +                        sin.peek())
192 +                {
193 +                        getline(sin, line);
194 +
195 +                        value += ' ' + line;
196 +                }
197 +
198 +                Matcher matcher("^\\s*(.+)\\s*$");
199 +
200 +                if (name == "Content-Length")
201 +                {
202 +                        if (value == matcher) env.set("CONTENT_LENGTH", matcher[1]);
203 +                }
204 +                else if (name == "Content-Type")
205 +                {
206 +                        if (value == matcher) env.set("CONTENT_TYPE", matcher[1]);
207 +                }
208 +                else if (name == "Referer")
209 +                {
210 +                        if (value == matcher) env.set("HTTP_REFERER", matcher[1]);
211 +                }
212 +                else if (name == "User-Agent")
213 +                {
214 +                        if (value == matcher) env.set("HTTP_USER_AGENT", matcher[1]);
215 +                }
216 +        }
217 +        while (sin.good());
218 + }
219 +
220 + Daemon::Status Daemon::message(istream& sin, Environment& env, ostream& post)
221 + {
222 +        string contentLength(env.get("CONTENT_LENGTH"));
223 +                        
224 +        if (env.get("CONTENT_TYPE") != "application/x-www-form-urlencoded") return
225 +                mediaType;
226 +        if (contentLength.empty()) return lengthRequired;
227 +
228 +        streamsize length(lexical_cast<streamsize>(contentLength));
229 +        char* content(new char[length]);
230 +
231 +        sin.read(content, length);
232 +        post.write(content, length);
233 +
234 +        delete [] content;
235 +
236 +        return ok;
237 + }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines