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 18 by douglas, 2002-12-09T21:40:12-08:00 vs.
Revision 179 by douglas, 2003-07-05T19:47:23-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 50 | Line 50
50  
51   #include "HttpHandler.h"
52  
53 + // Lovely C Sockets!
54 + #ifndef _WIN32
55 + // BSD Sockets
56 + #include <unistd.h>
57 + #include <sys/types.h>
58 + #include <sys/socket.h>
59 + #include <netinet/in.h>
60 + #include <netdb.h>
61 +
62 + #define INVALID_SOCKET -1
63 + #define SOCKET_ERROR -1
64 +
65 + inline int closesocket(SOCKET s) { return close(s); }
66 + #endif
67 +
68   HttpHandler::HttpHandler()
69   {
70          buffer = new char[BUFSIZ + 1];
# Line 62 | Line 77 | HttpHandler::HttpHandler()
77          }
78   #endif // _WIN32
79  
65        begin = 0;
80          length = 0;
81          chunked = false;
82   }
# Line 76 | Line 90 | HttpHandler::~HttpHandler()
90   #endif // _WIN32
91   }
92  
93 < bool HttpHandler::handle(URL &url, bool head)
93 > bool HttpHandler::handle(URL &url, const string referer, bool head)
94   {
95          bool answer = false;
96  
# Line 133 | Line 147 | bool HttpHandler::handle(URL &url, bool
147                  delete [] port;
148          }
149  
150 +        if (referer != "")
151 +        {
152 +                putline("Referer: " + referer);
153 +        }
154 +
155          putline("Connection: close");
156          putline();
157  
# Line 151 | Line 170 | bool HttpHandler::handle(URL &url, bool
170                  unsigned dot = line.find('.');
171                  unsigned space = line.find(' ');
172  
173 <                unsigned major = strtoul(line.substr(5, dot - 5).c_str(), 0, 0);
174 <                unsigned minor = strtoul(line.substr(dot + 1, space - dot - 1).c_str(), 0,
175 <                        0);
173 >                unsigned major = strtoul(line.substr(5, dot - 5).c_str(), 0, 10);
174 >                unsigned minor = strtoul(line.substr(dot + 1, space - dot - 1).c_str(),
175 >                        0, 10);
176  
177 <                if (major > 1 || minor < 1)
177 >                if (major > 1)
178                  {
179 <                        cerr << program << ": Potentially Incompatible Server: HTTP/" << major
180 <                                << "." << minor << "\n";
179 >                        cerr << program << ": Potentially Incompatible Server: HTTP/" <<
180 >                                major << "." << minor << "\n";
181  
182                          return answer;
183                  }
184  
185 <                response = code(strtoul(line.substr(space + 1).c_str(), 0, 0));
185 >                response = code(strtoul(line.substr(space + 1).c_str(), 0, 10));
186  
187                  if (response < ok) do line = getline(); while (line != "");
188          }
# Line 182 | Line 201 | bool HttpHandler::handle(URL &url, bool
201  
202                          while (isspace(value[0])) value.erase(0, 1);
203  
204 < //                      if (field =
204 >                        if (field == "Content-Type")
205 >                        {
206 >                                type = value;
207 >                        }
208 >                        else if (field == "Content-Length")
209 >                        {
210 >                                length = strtoul(value.c_str(), 0, 10);
211 >                        }
212 >                        else if (field == "Location")
213 >                        {
214 >                                location = value;
215 >                        }
216 >                        else if (field == "Transfer-Encoding")
217 >                        {
218 >                                chunked = value == "chunked";
219 >                        }
220                  }
221          }
222          while (line != "");
# Line 217 | Line 251 | bool HttpHandler::handle(URL &url, bool
251                  break;
252          }
253  
254 +        if (!head && answer) populate();
255 +
256          return answer;
257   }
258  
259   HttpHandler& HttpHandler::getline(string& line, char endline)
260   {
261 <        int end = page.find(endline, begin);
262 <        int newline = page.find('\n', begin);
261 >        unsigned end = page.find(endline);
262 >        unsigned newline = page.find('\n');
263  
264          if (newline < end || end == string::npos)
265          {
266                  end = newline;
267          }
268  
269 <        line = page.substr(begin, end - begin);
270 <
235 <        if (end == string::npos)
236 <        {
237 <                begin = end;
238 <        }
239 <        else
240 <        {
241 <                begin = end + 1;
242 <        }
269 >        line = page.substr(0, end);
270 >        page.erase(0, (end == string::npos ? end : end + 1));
271  
272          return *this;
273   }
274  
247 bool HttpHandler::good()
248 {
249        bool answer = true;
250
251        if (begin >= page.length())
252        {
253                answer = false;
254        }
255        else if (begin == string::npos)
256        {
257                answer = false;
258        }
259
260        return answer;
261 }
262
275   void HttpHandler::clear()
276   {
277          closesocket(http);
# Line 267 | Line 279 | void HttpHandler::clear()
279          type = "";
280          length = 0;
281          location = "";
270        begin = 0;
282          page = "";
283          chunked = false;
284   }
285  
286 + void HttpHandler::populate()
287 + {
288 +        if (!chunked)
289 +        {
290 +                unsigned left = length;
291 +
292 +                while (left > 0)
293 +                {
294 +                        memset(buffer, 0, BUFSIZ + 1);
295 +
296 +                        unsigned bytes = left > BUFSIZ ? BUFSIZ : left;
297 +                        unsigned received;
298 +
299 +                        while (true)
300 +                        {
301 +                                if ((received = recv(http, buffer, bytes, 0)) == SOCKET_ERROR)
302 +                                {
303 +                                        error(program + ": Recv");
304 +                                        exit(1);
305 +                                }
306 +                                else if (received != bytes)
307 +                                {
308 +                                        left -= received;
309 +                                        page += buffer;
310 +
311 +                                        memset(buffer, 0, BUFSIZ + 1);
312 +
313 +                                        bytes -= received;
314 +                                }
315 +                                else
316 +                                {
317 +                                        break;
318 +                                }
319 +                        }
320 +
321 +                        page += buffer;
322 +                        left -= bytes;
323 +                }
324 +        }
325 +        else
326 +        {
327 +                unsigned chunk;
328 +
329 +                do
330 +                {
331 +                        chunk = strtoul(getline().c_str(), 0, 16);
332 +
333 +                        unsigned left = chunk;
334 +
335 +                        while (left > 0)
336 +                        {
337 +                                memset(buffer, 0, BUFSIZ + 1);
338 +
339 +                                unsigned bytes = left > BUFSIZ ? BUFSIZ : left;
340 +                                unsigned received;
341 +
342 +                                while (true)
343 +                                {
344 +                                        if ((received = recv(http, buffer, bytes, 0)) ==
345 +                                                SOCKET_ERROR)
346 +                                        {
347 +                                                error(program + ": Recv");
348 +                                                exit(1);
349 +                                        }
350 +                                        else if (received != bytes)
351 +                                        {
352 +                                                left -= received;
353 +                                                page += buffer;
354 +
355 +                                                memset(buffer, 0, BUFSIZ + 1);
356 +
357 +                                                bytes -= received;
358 +                                        }
359 +                                        else
360 +                                        {
361 +                                                break;
362 +                                        }
363 +                                }
364 +
365 +                                page += buffer;
366 +                                left -= bytes;
367 +                        }
368 +
369 +                        getline();
370 +                        length += chunk;
371 +                }
372 +                while (chunk > 0);
373 +        }
374 +
375 +        for (unsigned index = 0; index < page.length(); index++)
376 +        {
377 +                if (page[index] == '\r' && (index + 1 < page.length()) ? page[index +
378 +                        1] == '\n' : false)
379 +                {
380 +                        page.erase(index, 1);
381 +                }
382 +                else if (page[index] == '\r')
383 +                {
384 +                        page[index] = '\n';
385 +                }
386 +        }
387 + }
388 +
389   void HttpHandler::putline(const string line)
390   {
391          sprintf(buffer, "%s\r\n", line.c_str());
# Line 479 | Line 593 | void HttpHandler::error(const string& pr
593   #else
594          if (host)
595          {
596 <                herror(prefix.c_str());
596 >                string error;
597 >
598 >                switch (h_errno)
599 >                {
600 >                case HOST_NOT_FOUND:
601 >                        error = "Unknown host";
602 >                        break;
603 >                case TRY_AGAIN:
604 >                        error = "Host name lookup failure";
605 >                        break;
606 >                case NO_RECOVERY:
607 >                        error = "Unknown server error";
608 >                        break;
609 >                case NO_DATA:
610 >                        error = "No address associated with name";
611 >                        break;
612 >                default:
613 >                        error = "Unknown error";
614 >                        break;
615 >                }
616 >
617 >                cerr << prefix << ": " << error << "\n";
618          }
619          else
620          {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines