ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/proj/trunk/Search/HttpHandler.cpp
(Generate patch)

Comparing trunk/Search/HttpHandler.cpp (file contents):
Revision 17 by douglas, 2002-12-09T18:31:11-08:00 vs.
Revision 145 by douglas, 2003-05-31T14:31:50-07:00

# Line 1 | Line 1
1   /* ============================================================================
2   * Douglas Thrift's Search Engine License
3   *
4 < * Copyright (C) 2002, Douglas Thrift. All Rights Reserved.
4 > * Copyright (C) 2002-2003, Douglas Thrift. All Rights Reserved.
5   * Redistribution and use in source and binary forms, with or without
6   * modification, are permitted provided that the following conditions are met:
7   *
# Line 62 | Line 62 | HttpHandler::HttpHandler()
62          }
63   #endif // _WIN32
64  
65 <        begin = 0;
65 >        length = 0;
66 >        chunked = false;
67   }
68  
69   HttpHandler::~HttpHandler()
# Line 74 | Line 75 | HttpHandler::~HttpHandler()
75   #endif // _WIN32
76   }
77  
78 < bool HttpHandler::handle(URL &url, bool head)
78 > bool HttpHandler::handle(URL &url, const string referer, bool head)
79   {
80          bool answer = false;
81  
# Line 131 | Line 132 | bool HttpHandler::handle(URL &url, bool
132                  delete [] port;
133          }
134  
135 +        if (referer != "")
136 +        {
137 +                putline("Referer: " + referer);
138 +        }
139 +
140 +        putline("Connection: close");
141          putline();
142  
143 <        string line = getline();
143 >        code response;
144 >        string line;
145  
146 <        if (line.find("HTTP/") != 0)
146 >        do
147          {
148 <                return answer;
141 <        }
148 >                line = getline();
149  
150 <        unsigned dot = line.find('.');
151 <        unsigned space = line.find(' ');
150 >                if (line.find("HTTP/") != 0)
151 >                {
152 >                        return answer;
153 >                }
154  
155 <        unsigned major = strtoul(line.substr(5, dot - 5).c_str(), 0, 0);
156 <        unsigned minor = strtoul(line.substr(dot + 1, space - dot - 1).c_str(), 0,
148 <                0);
155 >                unsigned dot = line.find('.');
156 >                unsigned space = line.find(' ');
157  
158 <        if (major > 1 || minor < 1)
159 <        {
160 <                cerr << program << ": Potentially Incompatible Server: HTTP/" << major
153 <                        << "." << minor << "\n";
158 >                unsigned major = strtoul(line.substr(5, dot - 5).c_str(), 0, 10);
159 >                unsigned minor = strtoul(line.substr(dot + 1, space - dot - 1).c_str(),
160 >                        0, 10);
161  
162 <                return answer;
163 <        }
162 >                if (major > 1)
163 >                {
164 >                        cerr << program << ": Potentially Incompatible Server: HTTP/" <<
165 >                                major << "." << minor << "\n";
166  
167 <        code response = code(strtoul(line.substr(space + 1).c_str(), 0, 0));
167 >                        return answer;
168 >                }
169 >
170 >                response = code(strtoul(line.substr(space + 1).c_str(), 0, 10));
171 >
172 >                if (response < ok) do line = getline(); while (line != "");
173 >        }
174 >        while (response < ok);
175  
176          do
177          {
178                  line = getline();
179 +
180 +                if (line != "")
181 +                {
182 +                        unsigned colon = line.find(':');
183 +
184 +                        string field = line.substr(0, colon);
185 +                        string value = line.substr(colon + 1);
186 +
187 +                        while (isspace(value[0])) value.erase(0, 1);
188 +
189 +                        if (field == "Content-Type")
190 +                        {
191 +                                type = value;
192 +                        }
193 +                        else if (field == "Content-Length")
194 +                        {
195 +                                length = strtoul(value.c_str(), 0, 10);
196 +                        }
197 +                        else if (field == "Location")
198 +                        {
199 +                                location = value;
200 +                        }
201 +                        else if (field == "Transfer-Encoding")
202 +                        {
203 +                                chunked = value == "chunked";
204 +                        }
205 +                }
206          }
207          while (line != "");
208  
209          switch (response)
210          {
211          case ok:
212 +                if (debug) cerr << "response = " << response << "\n";
213                  answer = true;
214                  break;
215 <        case choices:
172 <                break;
215 >        case choices:
216          case moved:
174                break;
217          case found:
218 +                if (debug) cerr << "response = " << response << "\n"
219 +                        << "location = " << location << "\n";
220 +                location = getLink(location, url);
221                  break;
222          case notfound:
178                break;
223          case internal:
224 +                if (debug) cerr << "response = " << response << "\n";
225                  break;
226          default:
227 +                if (debug) cerr << "response = " << response << "\n";
228 +                if (response <= 299)
229 +                {
230 +                        answer = true;
231 +                }
232 +                else if (response <= 399)
233 +                {
234 +                        location = getLink(location, url);
235 +                }
236                  break;
237          }
238  
239 +        if (!head && answer) populate();
240 +
241          return answer;
242   }
243  
244   HttpHandler& HttpHandler::getline(string& line, char endline)
245   {
246 <        int end = page.find(endline, begin);
247 <        int newline = page.find('\n', begin);
246 >        unsigned end = page.find(endline);
247 >        unsigned newline = page.find('\n');
248  
249          if (newline < end || end == string::npos)
250          {
251                  end = newline;
252          }
253  
254 <        line = page.substr(begin, end - begin);
255 <
200 <        if (end == string::npos)
201 <        {
202 <                begin = end;
203 <        }
204 <        else
205 <        {
206 <                begin = end + 1;
207 <        }
254 >        line = page.substr(0, end);
255 >        page.erase(0, (end == string::npos ? end : end + 1));
256  
257          return *this;
258   }
259  
260 < bool HttpHandler::good()
260 > void HttpHandler::clear()
261   {
262 <        bool answer = true;
262 >        closesocket(http);
263 >
264 >        type = "";
265 >        length = 0;
266 >        location = "";
267 >        page = "";
268 >        chunked = false;
269 > }
270  
271 <        if (begin >= page.length())
271 > void HttpHandler::populate()
272 > {
273 >        if (!chunked)
274          {
275 <                answer = false;
275 >                unsigned left = length;
276 >
277 >                while (left > 0)
278 >                {
279 >                        memset(buffer, 0, BUFSIZ + 1);
280 >
281 >                        unsigned bytes = left > BUFSIZ ? BUFSIZ : left;
282 >                        unsigned received;
283 >
284 >                        while (true)
285 >                        {
286 >                                if ((received = recv(http, buffer, bytes, 0)) == SOCKET_ERROR)
287 >                                {
288 >                                        error(program + ": Recv");
289 >                                        exit(1);
290 >                                }
291 >                                else if (received != bytes)
292 >                                {
293 >                                        left -= received;
294 >                                        page += buffer;
295 >
296 >                                        memset(buffer, 0, BUFSIZ + 1);
297 >
298 >                                        bytes -= received;
299 >                                }
300 >                                else
301 >                                {
302 >                                        break;
303 >                                }
304 >                        }
305 >
306 >                        page += buffer;
307 >                        left -= bytes;
308 >                }
309          }
310 <        else if (begin == string::npos)
310 >        else
311          {
312 <                answer = false;
223 <        }
312 >                unsigned chunk;
313  
314 <        return answer;
315 < }
314 >                do
315 >                {
316 >                        chunk = strtoul(getline().c_str(), 0, 16);
317  
318 < void HttpHandler::clear()
319 < {
320 <        type = "";
321 <        length = 0;
322 <        location = "";
323 <        begin = 0;
324 <        page = "";
318 >                        unsigned left = chunk;
319 >
320 >                        while (left > 0)
321 >                        {
322 >                                memset(buffer, 0, BUFSIZ + 1);
323 >
324 >                                unsigned bytes = left > BUFSIZ ? BUFSIZ : left;
325 >                                unsigned received;
326 >
327 >                                while (true)
328 >                                {
329 >                                        if ((received = recv(http, buffer, bytes, 0)) ==
330 >                                                SOCKET_ERROR)
331 >                                        {
332 >                                                error(program + ": Recv");
333 >                                                exit(1);
334 >                                        }
335 >                                        else if (received != bytes)
336 >                                        {
337 >                                                left -= received;
338 >                                                page += buffer;
339 >
340 >                                                memset(buffer, 0, BUFSIZ + 1);
341 >
342 >                                                bytes -= received;
343 >                                        }
344 >                                        else
345 >                                        {
346 >                                                break;
347 >                                        }
348 >                                }
349 >
350 >                                page += buffer;
351 >                                left -= bytes;
352 >                        }
353 >
354 >                        getline();
355 >                        length += chunk;
356 >                }
357 >                while (chunk > 0);
358 >        }
359 >
360 >        for (unsigned index = 0; index < page.length(); index++)
361 >        {
362 >                if (page[index] == '\r' && (index + 1 < page.length()) ? page[index +
363 >                        1] == '\n' : false)
364 >                {
365 >                        page.erase(index, 1);
366 >                }
367 >                else if (page[index] == '\r')
368 >                {
369 >                        page[index] = '\n';
370 >                }
371 >        }
372   }
373  
374   void HttpHandler::putline(const string line)
# Line 266 | Line 403 | string HttpHandler::getline()
403          return line;
404   }
405  
406 < void HttpHandler::error(const string prefix, bool host)
406 > void HttpHandler::error(const string& prefix, bool host)
407   {
408   #ifdef _WIN32
409          string error;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines