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 178 by douglas, 2003-07-05T19:13:12-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 + #ifndef _WIN32
54 + #include <unistd.h>
55 + #include <sys/types.h>
56 + #include <sys/socket.h>
57 + #include <netinet/in.h>
58 + #include <netdb.h>
59 +
60 + #define INVALID_SOCKET -1
61 + #define SOCKET_ERROR -1
62 +
63 + inline int closesocket(SOCKET s) { return close(s); }
64 + #endif
65 +
66   HttpHandler::HttpHandler()
67   {
68          buffer = new char[BUFSIZ + 1];
# Line 62 | Line 75 | HttpHandler::HttpHandler()
75          }
76   #endif // _WIN32
77  
65        begin = 0;
78          length = 0;
79          chunked = false;
80   }
# Line 76 | Line 88 | HttpHandler::~HttpHandler()
88   #endif // _WIN32
89   }
90  
91 < bool HttpHandler::handle(URL &url, bool head)
91 > bool HttpHandler::handle(URL &url, const string referer, bool head)
92   {
93          bool answer = false;
94  
# Line 133 | Line 145 | bool HttpHandler::handle(URL &url, bool
145                  delete [] port;
146          }
147  
148 +        if (referer != "")
149 +        {
150 +                putline("Referer: " + referer);
151 +        }
152 +
153          putline("Connection: close");
154          putline();
155  
# Line 151 | Line 168 | bool HttpHandler::handle(URL &url, bool
168                  unsigned dot = line.find('.');
169                  unsigned space = line.find(' ');
170  
171 <                unsigned major = strtoul(line.substr(5, dot - 5).c_str(), 0, 0);
172 <                unsigned minor = strtoul(line.substr(dot + 1, space - dot - 1).c_str(), 0,
173 <                        0);
171 >                unsigned major = strtoul(line.substr(5, dot - 5).c_str(), 0, 10);
172 >                unsigned minor = strtoul(line.substr(dot + 1, space - dot - 1).c_str(),
173 >                        0, 10);
174  
175 <                if (major > 1 || minor < 1)
175 >                if (major > 1)
176                  {
177 <                        cerr << program << ": Potentially Incompatible Server: HTTP/" << major
178 <                                << "." << minor << "\n";
177 >                        cerr << program << ": Potentially Incompatible Server: HTTP/" <<
178 >                                major << "." << minor << "\n";
179  
180                          return answer;
181                  }
182  
183 <                response = code(strtoul(line.substr(space + 1).c_str(), 0, 0));
183 >                response = code(strtoul(line.substr(space + 1).c_str(), 0, 10));
184  
185                  if (response < ok) do line = getline(); while (line != "");
186          }
# Line 182 | Line 199 | bool HttpHandler::handle(URL &url, bool
199  
200                          while (isspace(value[0])) value.erase(0, 1);
201  
202 < //                      if (field =
202 >                        if (field == "Content-Type")
203 >                        {
204 >                                type = value;
205 >                        }
206 >                        else if (field == "Content-Length")
207 >                        {
208 >                                length = strtoul(value.c_str(), 0, 10);
209 >                        }
210 >                        else if (field == "Location")
211 >                        {
212 >                                location = value;
213 >                        }
214 >                        else if (field == "Transfer-Encoding")
215 >                        {
216 >                                chunked = value == "chunked";
217 >                        }
218                  }
219          }
220          while (line != "");
# Line 217 | Line 249 | bool HttpHandler::handle(URL &url, bool
249                  break;
250          }
251  
252 +        if (!head && answer) populate();
253 +
254          return answer;
255   }
256  
257   HttpHandler& HttpHandler::getline(string& line, char endline)
258   {
259 <        int end = page.find(endline, begin);
260 <        int newline = page.find('\n', begin);
259 >        unsigned end = page.find(endline);
260 >        unsigned newline = page.find('\n');
261  
262          if (newline < end || end == string::npos)
263          {
264                  end = newline;
265          }
266  
267 <        line = page.substr(begin, end - begin);
268 <
235 <        if (end == string::npos)
236 <        {
237 <                begin = end;
238 <        }
239 <        else
240 <        {
241 <                begin = end + 1;
242 <        }
267 >        line = page.substr(0, end);
268 >        page.erase(0, (end == string::npos ? end : end + 1));
269  
270          return *this;
271   }
272  
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
273   void HttpHandler::clear()
274   {
275          closesocket(http);
# Line 267 | Line 277 | void HttpHandler::clear()
277          type = "";
278          length = 0;
279          location = "";
270        begin = 0;
280          page = "";
281          chunked = false;
282   }
283  
284 + void HttpHandler::populate()
285 + {
286 +        if (!chunked)
287 +        {
288 +                unsigned left = length;
289 +
290 +                while (left > 0)
291 +                {
292 +                        memset(buffer, 0, BUFSIZ + 1);
293 +
294 +                        unsigned bytes = left > BUFSIZ ? BUFSIZ : left;
295 +                        unsigned received;
296 +
297 +                        while (true)
298 +                        {
299 +                                if ((received = recv(http, buffer, bytes, 0)) == SOCKET_ERROR)
300 +                                {
301 +                                        error(program + ": Recv");
302 +                                        exit(1);
303 +                                }
304 +                                else if (received != bytes)
305 +                                {
306 +                                        left -= received;
307 +                                        page += buffer;
308 +
309 +                                        memset(buffer, 0, BUFSIZ + 1);
310 +
311 +                                        bytes -= received;
312 +                                }
313 +                                else
314 +                                {
315 +                                        break;
316 +                                }
317 +                        }
318 +
319 +                        page += buffer;
320 +                        left -= bytes;
321 +                }
322 +        }
323 +        else
324 +        {
325 +                unsigned chunk;
326 +
327 +                do
328 +                {
329 +                        chunk = strtoul(getline().c_str(), 0, 16);
330 +
331 +                        unsigned left = chunk;
332 +
333 +                        while (left > 0)
334 +                        {
335 +                                memset(buffer, 0, BUFSIZ + 1);
336 +
337 +                                unsigned bytes = left > BUFSIZ ? BUFSIZ : left;
338 +                                unsigned received;
339 +
340 +                                while (true)
341 +                                {
342 +                                        if ((received = recv(http, buffer, bytes, 0)) ==
343 +                                                SOCKET_ERROR)
344 +                                        {
345 +                                                error(program + ": Recv");
346 +                                                exit(1);
347 +                                        }
348 +                                        else if (received != bytes)
349 +                                        {
350 +                                                left -= received;
351 +                                                page += buffer;
352 +
353 +                                                memset(buffer, 0, BUFSIZ + 1);
354 +
355 +                                                bytes -= received;
356 +                                        }
357 +                                        else
358 +                                        {
359 +                                                break;
360 +                                        }
361 +                                }
362 +
363 +                                page += buffer;
364 +                                left -= bytes;
365 +                        }
366 +
367 +                        getline();
368 +                        length += chunk;
369 +                }
370 +                while (chunk > 0);
371 +        }
372 +
373 +        for (unsigned index = 0; index < page.length(); index++)
374 +        {
375 +                if (page[index] == '\r' && (index + 1 < page.length()) ? page[index +
376 +                        1] == '\n' : false)
377 +                {
378 +                        page.erase(index, 1);
379 +                }
380 +                else if (page[index] == '\r')
381 +                {
382 +                        page[index] = '\n';
383 +                }
384 +        }
385 + }
386 +
387   void HttpHandler::putline(const string line)
388   {
389          sprintf(buffer, "%s\r\n", line.c_str());

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines