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 201 by douglas, 2003-07-15T01:01:00-07:00 vs.
Revision 211 by douglas, 2003-07-19T18:46:12-07:00

# Line 46 | Line 46
46   //
47   // Douglas Thrift
48   //
49 < // $Id: HttpHandler.cpp,v 1.19 2003/07/15 08:01:00 douglas Exp $
49 > // $Id: HttpHandler.cpp,v 1.22 2003/07/20 01:46:12 douglas Exp $
50  
51   #include "HttpHandler.h"
52  
# Line 58 | Line 58
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); }
61   #endif
62  
63   HttpHandler::HttpHandler()
# Line 77 | Line 72 | HttpHandler::HttpHandler()
72          }
73   #endif // _WIN32
74  
75 +        binary = false;
76          length = 0;
77          chunked = false;
78   #ifdef _OpenSSL_
# Line 124 | Line 120 | bool HttpHandler::handle(URL &url, const
120                  return answer;
121          }
122  
123 + #ifdef _OpenSSL_
124 +        if (url.getTls())
125 +        {
126 +                tls = true;
127 +
128 +                if (!starttls()) return answer;
129 +        }
130 + #endif
131 +
132          if (head)
133          {
134                  putline("HEAD " + url.getPath() + " HTTP/1.1");
# Line 136 | Line 141 | bool HttpHandler::handle(URL &url, const
141          putline("Accept: text/html; text/plain");
142   #ifndef _OpenSSL_
143          putline("User-Agent: " + agent(true) + ' ' + platform());
144 +
145 +        if (url.getPort() == 80)
146   #else
147          putline("User-Agent: " + agent(true) + ' ' + platform() + ' '
148                  + openssl(true));
142 #endif
149  
150 <        if (url.getPort() == 80)
150 >        if (url.getPort() == 80 && tls || url.getPort() == 443 && tls)
151 > #endif
152          {
153                  putline("Host: " + url.getAddress());
154          }
155          else
156          {
157 <                char* port = new char[1024];
151 <                sprintf(port, "%u", url.getPort());
157 >                ostringstream port;
158  
159 <                putline("Host: " + url.getAddress() + ':' + port);
159 >                port << url.getPort();
160  
161 <                delete [] port;
161 >                putline("Host: " + url.getAddress() + ':' + port.str());
162          }
163  
164          if (referer != "")
# Line 264 | Line 270 | bool HttpHandler::handle(URL &url, const
270          return answer;
271   }
272  
273 < HttpHandler& HttpHandler::getline(string& line, char endline)
273 > void HttpHandler::clear()
274   {
275 <        unsigned end = page.find(endline);
270 <        unsigned newline = page.find('\n');
271 <
272 <        if (newline < end || end == string::npos)
275 >        if (tls)
276          {
277 <                end = newline;
277 >                SSL_shutdown(ssl);
278 >                SSL_free(ssl);
279 >                SSL_CTX_free(ctx);
280          }
281  
277        line = page.substr(0, end);
278        page.erase(0, (end == string::npos ? end : end + 1));
279
280        return *this;
281 }
282
283 void HttpHandler::clear()
284 {
282          closesocket(http);
283  
284          type = "";
285          length = 0;
286          location = "";
287 <        page = "";
287 >        page.clear();
288 >        page.str("");
289          chunked = false;
290   #ifdef _OpenSSL_
291          tls = false;
# Line 305 | Line 303 | void HttpHandler::populate()
303                          memset(buffer, 0, BUFSIZ + 1);
304  
305                          unsigned bytes = left > BUFSIZ ? BUFSIZ : left;
306 <                        unsigned received;
306 >                        long received;
307  
308                          while (true)
309                          {
310 + #ifndef _OpenSSL_
311                                  if ((received = recv(http, buffer, bytes, 0)) == SOCKET_ERROR)
312                                  {
313                                          error(program + ": Recv");
314                                          exit(1);
315                                  }
316 + #else
317 +                                if ((received = !tls ? recv(http, buffer, bytes, 0) :
318 +                                        SSL_read(ssl, buffer, bytes)) <= 0)
319 +                                {
320 +                                        !tls ? error(program + ": Recv") : error(program +
321 +                                                ": SSL Read", int(received));
322 +                                }
323 + #endif
324                                  else if (received != bytes)
325                                  {
326                                          left -= received;
327 <                                        page += buffer;
327 >                                        page << buffer;
328  
329                                          memset(buffer, 0, BUFSIZ + 1);
330  
# Line 329 | Line 336 | void HttpHandler::populate()
336                                  }
337                          }
338  
339 <                        page += buffer;
339 >                        page << buffer;
340                          left -= bytes;
341                  }
342          }
# Line 348 | Line 355 | void HttpHandler::populate()
355                                  memset(buffer, 0, BUFSIZ + 1);
356  
357                                  unsigned bytes = left > BUFSIZ ? BUFSIZ : left;
358 <                                unsigned received;
358 >                                long received;
359  
360                                  while (true)
361                                  {
362 + #ifndef _OpenSSL_
363                                          if ((received = recv(http, buffer, bytes, 0)) ==
364                                                  SOCKET_ERROR)
365                                          {
366                                                  error(program + ": Recv");
367                                                  exit(1);
368                                          }
369 + #else
370 +                                        if ((received = !tls ? recv(http, buffer, bytes, 0) :
371 +                                                SSL_read(ssl, buffer, bytes)) <= 0)
372 +                                        {
373 +                                                !tls ? error(program + ": Recv") : error(program +
374 +                                                        ": SSL Read", int(received));
375 +                                                exit(1);
376 +                                        }
377 + #endif
378                                          else if (received != bytes)
379                                          {
380                                                  left -= received;
381 <                                                page += buffer;
381 >                                                page << buffer;
382  
383                                                  memset(buffer, 0, BUFSIZ + 1);
384  
# Line 373 | Line 390 | void HttpHandler::populate()
390                                          }
391                                  }
392  
393 <                                page += buffer;
393 >                                page << buffer;
394                                  left -= bytes;
395                          }
396  
# Line 383 | Line 400 | void HttpHandler::populate()
400                  while (chunk > 0);
401          }
402  
403 <        for (unsigned index = 0; index < page.length(); index++)
403 >        if (!binary)
404          {
405 <                if (page[index] == '\r' && (index + 1 < page.length()) ? page[index +
406 <                        1] == '\n' : false)
407 <                {
391 <                        page.erase(index, 1);
392 <                }
393 <                else if (page[index] == '\r')
405 >                string page = this->page.str();
406 >
407 >                for (unsigned index = 0; index < page.length(); index++)
408                  {
409 <                        page[index] = '\n';
409 >                        if (page[index] == '\r' && (index + 1 < page.length()) ? page[index +
410 >                                1] == '\n' : false)
411 >                        {
412 >                                page.erase(index, 1);
413 >                        }
414 >                        else if (page[index] == '\r')
415 >                        {
416 >                                page[index] = '\n';
417 >                        }
418                  }
419 +
420 +                this->page.str(page);
421          }
422   }
423  
424   void HttpHandler::putline(const string line)
425   {
426          sprintf(buffer, "%s\r\n", line.c_str());
427 +
428 + #ifndef _OpenSSL_
429          if (send(http, buffer, strlen(buffer), 0) == SOCKET_ERROR)
430          {
431                  error(program + ": Send");
432                  exit(1);
433          }
434 + #else
435 +        if (!tls)
436 +        {
437 +                if (send(http, buffer, strlen(buffer), 0) == SOCKET_ERROR)
438 +                {
439 +                        error(program + ": Send");
440 +                        exit(1);
441 +                }
442 +        }
443 +        else
444 +        {
445 +                int number;
446 +
447 +                if ((number = SSL_write(ssl, buffer, strlen(buffer))) <= 0)
448 +                {
449 +                        error(program + ": SSL Write", number);
450 +                        exit(1);
451 +                }
452 +        }
453 + #endif
454   }
455  
456   string HttpHandler::getline()
# Line 414 | Line 460 | string HttpHandler::getline()
460  
461          do
462          {
463 + #ifndef _OpenSSL_
464                  if (recv(http, &byte, 1, 0) == SOCKET_ERROR)
465                  {
466                          error(program + ": Recv");
467                  }
468 + #else
469 +                if (!tls)
470 +                {
471 +                        if (recv(http, &byte, 1, 0) == SOCKET_ERROR)
472 +                        {
473 +                                error(program + ": Recv");
474 +                        }
475 +                }
476 +                else
477 +                {
478 +                        int number;
479 +
480 +                        if ((number = SSL_read(ssl, &byte, 1)) <= 0)
481 +                        {
482 +                                error(program + ": SSL Read", number);
483 +                        }
484 +                }
485 + #endif
486  
487                  if (byte != '\r' && byte != '\n')
488                  {
# Line 633 | Line 698 | void HttpHandler::error(const string& pr
698          }
699   #endif // _WIN32
700   }
701 +
702 + #ifdef _OpenSSL_
703 + void HttpHandler::error(const string& prefix, int number)
704 + {
705 +        string error;
706 +
707 +        switch (SSL_get_error(ssl, number))
708 +        {
709 +        case SSL_ERROR_NONE:
710 +                error = "The TLS/SSL I/O operation completed";
711 +                break;
712 +        case SSL_ERROR_ZERO_RETURN:
713 +                error = "The TLS/SSL connection has been closed";
714 +                break;
715 +        case SSL_ERROR_WANT_READ:
716 +        case SSL_ERROR_WANT_WRITE:
717 +        case SSL_ERROR_WANT_CONNECT:
718 + //      case SSL_ERROR_WANT_ACCEPT:
719 +        case SSL_ERROR_WANT_X509_LOOKUP:
720 +                error = "The operation did not complete";
721 +                break;
722 +        case SSL_ERROR_SYSCALL:
723 +                if (int err = ERR_get_error() != 0)
724 +                {
725 +                        error = ERR_reason_error_string(err);
726 +                }
727 +                else
728 +                {
729 +                        switch (number)
730 +                        {
731 +                        case 0:
732 +                                error = "An EOF was observed that violates the protocol";
733 +                                break;
734 +                        case -1:
735 +                                this->error(prefix);
736 +                                return;
737 +                        default:
738 +                                error = "Unknown error";
739 +                                break;
740 +                        }
741 +                }
742 +                break;
743 +        case SSL_ERROR_SSL:
744 +                error = ERR_reason_error_string(ERR_get_error());
745 +                break;
746 +        default:
747 +                error = "Unknown error";
748 +                break;
749 +        }
750 +
751 +        cerr << prefix << ": " << error << "\n";
752 + }
753 +
754 + bool HttpHandler::starttls()
755 + {
756 +        SSL_load_error_strings();
757 +        SSL_library_init();
758 +
759 + #ifndef _urandomdev_
760 +        int pid = getpid();
761 +        int now = time(NULL);
762 +
763 +        unsigned seed = now > pid ? now - pid : pid - now;
764 +
765 +        char* junk = new char[seed % 30 + 2];
766 +        junk[0] = pid;
767 +        junk[seed % 30 + 1] = now;
768 +
769 +        srand(seed);
770 +
771 +        for (int index = 1; index < seed % 30 + 1; index++)
772 +        {
773 +                junk[index] = rand();
774 +        }
775 +
776 +        if (debug)
777 +        {
778 +                cerr << "junk = {\n";
779 +
780 +                for (int index = 1; index < seed % 30 + 2; index++)
781 +                {
782 +                        cerr << "   [" << index << "] = " << int(junk[index]) << "\n";
783 +                }
784 +
785 +                cerr << "}\n";
786 +        }
787 +
788 +        RAND_seed(junk, seed % 30 + 2);
789 +
790 +        delete junk;
791 + #endif
792 +
793 +        ctx = SSL_CTX_new(TLSv1_client_method());
794 +
795 +        if (ctx == NULL)
796 +        {
797 +                cerr << program << ": SSL CTX New: "
798 +                        << ERR_reason_error_string(ERR_get_error()) << "\n";
799 +                return false;
800 +        }
801 +
802 +        ssl = SSL_new(ctx);
803 +
804 +        if (SSL_set_fd(ssl, http) == 0)
805 +        {
806 +                cerr << program << ": SSL Set FD: "
807 +                        << ERR_reason_error_string(ERR_get_error()) << "\n";
808 +                return false;
809 +        }
810 +
811 +        int number;
812 +
813 +        if ((number = SSL_connect(ssl)) <= 0)
814 +        {
815 +                error(program + ": SSL Connect", number);
816 +                return false;
817 +        }
818 +
819 +        return true;
820 + }
821 + #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines