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 25 by douglas, 2002-12-22T23:32:58-08:00 vs.
Revision 350 by Douglas Thrift, 2004-05-27T20:29:11-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-2004, 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 46 | Line 46
46   //
47   // Douglas Thrift
48   //
49 < // HttpHandler.cpp
49 > // $Id$
50  
51 < #include "HttpHandler.h"
51 > #include "HttpHandler.hpp"
52  
53 < HttpHandler::HttpHandler()
54 < {
55 <        buffer = new char[BUFSIZ + 1];
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 > inline int closesocket(SOCKET s) { return close(s); }
63 > #endif
64  
65 + #ifndef _OpenSSL_
66 + HttpHandler::HttpHandler() : binary(false), length(0), chunked(false)
67 + #else
68 + HttpHandler::HttpHandler() : binary(false), length(0), chunked(false),
69 +        tls(false)
70 + #endif
71 + {
72   #ifdef _WIN32
73          if (WSAStartup(MAKEWORD(2, 0), &data) != 0)
74          {
# Line 61 | Line 76 | HttpHandler::HttpHandler()
76                  exit(1);
77          }
78   #endif // _WIN32
64
65        length = 0;
66        chunked = false;
79   }
80  
81   HttpHandler::~HttpHandler()
82   {
71        delete [] buffer;
72
83   #ifdef _WIN32
84          WSACleanup();
85   #endif // _WIN32
# Line 77 | Line 87 | HttpHandler::~HttpHandler()
87  
88   bool HttpHandler::handle(URL &url, const string referer, bool head)
89   {
90 <        bool answer = false;
90 >        bool answer(false);
91  
92          if ((http = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
93          {
# Line 93 | Line 103 | bool HttpHandler::handle(URL &url, const
103          if ((host = gethostbyname(url.getAddress().c_str())) == NULL)
104          {
105                  error(program + ": Host: " + url.getAddress(), true);
106 +
107                  return answer;
108          }
109  
# Line 103 | Line 114 | bool HttpHandler::handle(URL &url, const
114                  SOCKET_ERROR)
115          {
116                  error(program + ": Connect");
117 +
118                  return answer;
119          }
120  
121 + #ifdef _OpenSSL_
122 +        if (url.getTls())
123 +        {
124 +                tls = true;
125 +
126 +                if (!starttls()) return answer;
127 +        }
128 + #endif
129 +
130          if (head)
131          {
132                  putline("HEAD " + url.getPath() + " HTTP/1.1");
# Line 116 | Line 137 | bool HttpHandler::handle(URL &url, const
137          }
138  
139          putline("Accept: text/html; text/plain");
140 + #ifndef _OpenSSL_
141          putline("User-Agent: " + agent(true) + ' ' + platform());
142  
143          if (url.getPort() == 80)
144 + #else
145 +        putline("User-Agent: " + agent(true) + ' ' + platform() + ' '
146 +                + openssl(true));
147 +
148 +        if (url.getPort() == 80 && tls || url.getPort() == 443 && tls)
149 + #endif
150          {
151                  putline("Host: " + url.getAddress());
152          }
153          else
154          {
155 <                char* port = new char[1024];
128 <                sprintf(port, "%u", url.getPort());
155 >                ostringstream port;
156  
157 <                putline("Host: " + url.getAddress() + ':' + port);
157 >                port << url.getPort();
158  
159 <                delete [] port;
159 >                putline("Host: " + url.getAddress() + ':' + port.str());
160          }
161  
162          if (referer != "")
# Line 147 | Line 174 | bool HttpHandler::handle(URL &url, const
174          {
175                  line = getline();
176  
177 <                if (line.find("HTTP/") != 0)
151 <                {
152 <                        return answer;
153 <                }
177 >                if (line.find("HTTP/") != 0) return answer;
178  
179 <                unsigned dot = line.find('.');
180 <                unsigned space = line.find(' ');
179 >                unsigned dot(line.find('.')), space(line.find(' ')), major, minor;
180 >                istringstream number(line.substr(5, dot - 5) + " " + line.substr(dot
181 >                        + 1, space - dot - 1));
182  
183 <                unsigned major = strtoul(line.substr(5, dot - 5).c_str(), 0, 10);
184 <                unsigned minor = strtoul(line.substr(dot + 1, space - dot - 1).c_str(),
160 <                        0, 10);
183 >                number >> major;
184 >                number >> minor;
185  
186                  if (major > 1)
187                  {
# Line 167 | Line 191 | bool HttpHandler::handle(URL &url, const
191                          return answer;
192                  }
193  
194 <                response = code(strtoul(line.substr(space + 1).c_str(), 0, 10));
194 >                number.clear();
195 >                number.str(line.substr(space + 1, 3));
196 >
197 >                number >> response;
198  
199                  if (response < ok) do line = getline(); while (line != "");
200          }
# Line 179 | Line 206 | bool HttpHandler::handle(URL &url, const
206  
207                  if (line != "")
208                  {
209 <                        unsigned colon = line.find(':');
210 <
184 <                        string field = line.substr(0, colon);
185 <                        string value = line.substr(colon + 1);
209 >                        unsigned colon(line.find(':'));
210 >                        string field(line.substr(0, colon)), value(line.substr(colon + 1));
211  
212                          while (isspace(value[0])) value.erase(0, 1);
213  
# Line 192 | Line 217 | bool HttpHandler::handle(URL &url, const
217                          }
218                          else if (field == "Content-Length")
219                          {
220 <                                length = strtoul(value.c_str(), 0, 10);
220 >                                istringstream number(value);
221 >
222 >                                number >> length;
223                          }
224                          else if (field == "Location")
225                          {
# Line 210 | Line 237 | bool HttpHandler::handle(URL &url, const
237          {
238          case ok:
239                  if (debug) cerr << "response = " << response << "\n";
240 +
241                  answer = true;
242                  break;
243          case choices:
# Line 217 | Line 245 | bool HttpHandler::handle(URL &url, const
245          case found:
246                  if (debug) cerr << "response = " << response << "\n"
247                          << "location = " << location << "\n";
248 +
249                  location = getLink(location, url);
250                  break;
251          case notfound:
# Line 225 | Line 254 | bool HttpHandler::handle(URL &url, const
254                  break;
255          default:
256                  if (debug) cerr << "response = " << response << "\n";
257 <                if (response <= 299)
258 <                {
230 <                        answer = true;
231 <                }
232 <                else if (response <= 399)
257 >
258 >                if (response <= 299) answer = true; else if (response <= 399)
259                  {
260                          location = getLink(location, url);
261                  }
# Line 241 | Line 267 | bool HttpHandler::handle(URL &url, const
267          return answer;
268   }
269  
270 < HttpHandler& HttpHandler::getline(string& line, char endline)
270 > void HttpHandler::clear()
271   {
272 <        unsigned end = page.find(endline);
273 <        unsigned newline = page.find('\n');
248 <
249 <        if (newline < end || end == string::npos)
272 > #ifdef _OpenSSL_
273 >        if (tls)
274          {
275 <                end = newline;
275 >                SSL_shutdown(ssl);
276 >                SSL_free(ssl);
277 >                SSL_CTX_free(ctx);
278          }
279 + #endif
280  
254        line = page.substr(0, end);
255        page.erase(0, (end == string::npos ? end : end + 1));
256
257        return *this;
258 }
259
260 void HttpHandler::clear()
261 {
281          closesocket(http);
282  
283          type = "";
284          length = 0;
285          location = "";
286 <        page = "";
286 >
287 >        page.clear();
288 >        page.str("");
289 >
290          chunked = false;
291 + #ifdef _OpenSSL_
292 +        tls = false;
293 + #endif
294   }
295  
296   void HttpHandler::populate()
297   {
298          if (!chunked)
299          {
300 <                unsigned left = length;
300 >                unsigned left(length);
301  
302                  while (left > 0)
303                  {
304                          memset(buffer, 0, BUFSIZ + 1);
305  
306 <                        unsigned bytes = left > BUFSIZ ? BUFSIZ : left;
307 <                        unsigned received;
306 >                        unsigned bytes(left > BUFSIZ ? BUFSIZ : left);
307 >                        long received;
308  
309 <                        if ((received = recv(http, buffer, bytes, 0)) == SOCKET_ERROR)
285 <                        {
286 <                                error(program + ": Recv");
287 <                                exit(1);
288 <                        }
289 <                        else if (received != bytes)
309 >                        while (true)
310                          {
311 <                                left -= received;
312 <                                page += buffer;
293 <
294 <                                memset(buffer, 0, BUFSIZ + 1);
295 <
296 <                                bytes -= received;
297 <                                if (recv(http, buffer, bytes, 0) == SOCKET_ERROR)
311 > #ifndef _OpenSSL_
312 >                                if ((received = recv(http, buffer, bytes, 0)) == SOCKET_ERROR)
313                                  {
314                                          error(program + ": Recv");
315                                          exit(1);
316                                  }
317 + #else
318 +                                if ((received = !tls ? recv(http, buffer, bytes, 0) :
319 +                                        SSL_read(ssl, buffer, bytes)) <= 0)
320 +                                {
321 +                                        !tls ? error(program + ": Recv") : error(program +
322 +                                                ": SSL Read", int(received));
323 +                                }
324 + #endif
325 +                                else if (received != bytes)
326 +                                {
327 +                                        left -= received;
328 +
329 +                                        page << buffer;
330 +
331 +                                        memset(buffer, 0, BUFSIZ + 1);
332 +
333 +                                        bytes -= received;
334 +                                }
335 +                                else break;
336                          }
337  
338 <                        page += buffer;
338 >                        page << buffer;
339 >
340                          left -= bytes;
341                  }
342          }
# Line 311 | Line 346 | void HttpHandler::populate()
346  
347                  do
348                  {
349 <                        chunk = strtoul(getline().c_str(), 0, 16);
349 >                        istringstream number(getline());
350 >
351 >                        number.setf(ios_base::hex, ios_base::basefield);
352  
353 <                        unsigned left = chunk;
353 >                        number >> chunk;
354 >
355 >                        unsigned left(chunk);
356  
357                          while (left > 0)
358                          {
359                                  memset(buffer, 0, BUFSIZ + 1);
360  
361 <                                unsigned bytes = left > BUFSIZ ? BUFSIZ : left;
362 <                                unsigned received;
361 >                                unsigned bytes(left > BUFSIZ ? BUFSIZ : left);
362 >                                long received;
363  
364 <                                if ((received = recv(http, buffer, bytes, 0)) == SOCKET_ERROR)
364 >                                while (true)
365                                  {
366 <                                        error(program + ": Recv");
367 <                                        exit(1);
368 <                                }
330 <                                else if (received != bytes)
331 <                                {
332 <                                        left -= received;
333 <                                        page += buffer;
334 <
335 <                                        memset(buffer, 0, BUFSIZ + 1);
336 <
337 <                                        bytes -= received;
338 <                                        if (recv(http, buffer, bytes, 0) == SOCKET_ERROR)
366 > #ifndef _OpenSSL_
367 >                                        if ((received = recv(http, buffer, bytes, 0)) ==
368 >                                                SOCKET_ERROR)
369                                          {
370                                                  error(program + ": Recv");
371                                                  exit(1);
372                                          }
373 + #else
374 +                                        if ((received = !tls ? recv(http, buffer, bytes, 0) :
375 +                                                SSL_read(ssl, buffer, bytes)) <= 0)
376 +                                        {
377 +                                                !tls ? error(program + ": Recv") : error(program +
378 +                                                        ": SSL Read", int(received));
379 +
380 +                                                exit(1);
381 +                                        }
382 + #endif
383 +                                        else if (received != bytes)
384 +                                        {
385 +                                                left -= received;
386 +                                                page << buffer;
387 +
388 +                                                memset(buffer, 0, BUFSIZ + 1);
389 +
390 +                                                bytes -= received;
391 +                                        }
392 +                                        else break;
393                                  }
394  
395 <                                page += buffer;
395 >                                page << buffer;
396 >
397                                  left -= bytes;
398                          }
399  
400                          getline();
401 +
402                          length += chunk;
403                  }
404                  while (chunk > 0);
405          }
406  
407 <        for (unsigned index = 0; index < page.length(); index++)
407 >        if (!binary)
408          {
409 <                if (page[index] == '\r' && (index + 1 < page.length()) ? page[index +
410 <                        1] == '\n' : false)
411 <                {
360 <                        page.erase(index, 1);
361 <                }
362 <                else if (page[index] == '\r')
409 >                string page(this->page.str());
410 >
411 >                for (unsigned index(0); index < page.length(); index++)
412                  {
413 <                        page[index] = '\n';
413 >                        if (page[index] == '\r' && (index + 1 < page.length()) ?
414 >                                page[index + 1] == '\n' : false)
415 >                        {
416 >                                page.erase(index, 1);
417 >                        }
418 >                        else if (page[index] == '\r')
419 >                        {
420 >                                page[index] = '\n';
421 >                        }
422                  }
423 +
424 +                this->page.str(page);
425          }
426   }
427  
428   void HttpHandler::putline(const string line)
429   {
430          sprintf(buffer, "%s\r\n", line.c_str());
431 +
432 + #ifndef _OpenSSL_
433          if (send(http, buffer, strlen(buffer), 0) == SOCKET_ERROR)
434          {
435                  error(program + ": Send");
436                  exit(1);
437          }
438 + #else
439 +        if (!tls)
440 +        {
441 +                if (send(http, buffer, strlen(buffer), 0) == SOCKET_ERROR)
442 +                {
443 +                        error(program + ": Send");
444 +                        exit(1);
445 +                }
446 +        }
447 +        else
448 +        {
449 +                int number;
450 +
451 +                if ((number = SSL_write(ssl, buffer, strlen(buffer))) <= 0)
452 +                {
453 +                        error(program + ": SSL Write", number);
454 +                        exit(1);
455 +                }
456 +        }
457 + #endif
458   }
459  
460   string HttpHandler::getline()
# Line 383 | Line 464 | string HttpHandler::getline()
464  
465          do
466          {
467 + #ifndef _OpenSSL_
468                  if (recv(http, &byte, 1, 0) == SOCKET_ERROR)
469                  {
470                          error(program + ": Recv");
471                  }
472 + #else
473 +                if (!tls)
474 +                {
475 +                        if (recv(http, &byte, 1, 0) == SOCKET_ERROR)
476 +                        {
477 +                                error(program + ": Recv");
478 +                        }
479 +                }
480 +                else
481 +                {
482 +                        int number;
483 +
484 +                        if ((number = SSL_read(ssl, &byte, 1)) <= 0)
485 +                        {
486 +                                error(program + ": SSL Read", number);
487 +                        }
488 +                }
489 + #endif
490  
491                  if (byte != '\r' && byte != '\n')
492                  {
# Line 406 | Line 506 | void HttpHandler::error(const string& pr
506          switch (WSAGetLastError())
507          {
508          case WSAEACCES:
509 <                error = "Permission denied.";
509 >                error = "Permission denied";
510                  break;
511          case WSAEADDRINUSE:
512 <                error = "Address already in use.";
512 >                error = "Address already in use";
513                  break;
514          case WSAEADDRNOTAVAIL:
515 <                error = "Cannot assign requested address.";
515 >                error = "Cannot assign requested address";
516                  break;
517          case WSAEAFNOSUPPORT:
518 <                error = "Address family not supported by protocol family.";
518 >                error = "Address family not supported by protocol family";
519                  break;
520          case WSAEALREADY:
521 <                error = "Operation already in progress.";
521 >                error = "Operation already in progress";
522                  break;
523          case WSAECONNABORTED:
524 <                error = "Software caused connection abort.";
524 >                error = "Software caused connection abort";
525                  break;
526          case WSAECONNREFUSED:
527 <                error = "Connection refused.";
527 >                error = "Connection refused";
528                  break;
529          case WSAECONNRESET:
530 <                error = "Connection reset by peer.";
530 >                error = "Connection reset by peer";
531                  break;
532          case WSAEDESTADDRREQ:
533 <                error = "Destination address required.";
533 >                error = "Destination address required";
534                  break;
535          case WSAEFAULT:
536 <                error = "Bad address.";
536 >                error = "Bad address";
537                  break;
538          case WSAEHOSTDOWN:
539 <                error = "Host is down.";
539 >                error = "Host is down";
540                  break;
541          case WSAEHOSTUNREACH:
542 <                error = "No route to host.";
542 >                error = "No route to host";
543                  break;
544          case WSAEINPROGRESS:
545 <                error = "Operation now in progress.";
545 >                error = "Operation now in progress";
546                  break;
547          case WSAEINTR:
548 <                error = "Interrupted function call.";
548 >                error = "Interrupted function call";
549                  break;
550          case WSAEINVAL:
551 <                error = "Invalid argument.";
551 >                error = "Invalid argument";
552                  break;
553          case WSAEISCONN:
554 <                error = "Socket is already connected.";
554 >                error = "Socket is already connected";
555                  break;
556          case WSAEMFILE:
557 <                error = "Too many open files.";
557 >                error = "Too many open files";
558                  break;
559          case WSAEMSGSIZE:
560 <                error = "Message too long.";
560 >                error = "Message too long";
561                  break;
562          case WSAENETDOWN:
563 <                error = "Network is down.";
563 >                error = "Network is down";
564                  break;
565          case WSAENETRESET:
566 <                error = "Network dropped connection on reset.";
566 >                error = "Network dropped connection on reset";
567                  break;
568          case WSAENETUNREACH:
569 <                error = "Network is unreachable.";
569 >                error = "Network is unreachable";
570                  break;
571          case WSAENOBUFS:
572 <                error = "No buffer space available.";
572 >                error = "No buffer space available";
573                  break;
574          case WSAENOPROTOOPT:
575 <                error = "Bad protocol option.";
575 >                error = "Bad protocol option";
576                  break;
577          case WSAENOTCONN:
578 <                error = "Socket is not connected.";
578 >                error = "Socket is not connected";
579                  break;
580          case WSAENOTSOCK:
581 <                error = "Socket operation on non-socket.";
581 >                error = "Socket operation on non-socket";
582                  break;
583          case WSAEOPNOTSUPP:
584 <                error = "Operation not supported.";
584 >                error = "Operation not supported";
585                  break;
586          case WSAEPFNOSUPPORT:
587 <                error = "Protocol family not supported.";
587 >                error = "Protocol family not supported";
588                  break;
589          case WSAEPROCLIM:
590 <                error = "Too many processes.";
590 >                error = "Too many processes";
591                  break;
592          case WSAEPROTONOSUPPORT:
593 <                error = "Protocol not supported.";
593 >                error = "Protocol not supported";
594                  break;
595          case WSAEPROTOTYPE:
596 <                error = "Protocol wrong type for socket.";
596 >                error = "Protocol wrong type for socket";
597                  break;
598          case WSAESHUTDOWN:
599 <                error = "Cannot send after socket shutdown.";
599 >                error = "Cannot send after socket shutdown";
600                  break;
601          case WSAESOCKTNOSUPPORT:
602 <                error = "Socket type not supported.";
602 >                error = "Socket type not supported";
603                  break;
604          case WSAETIMEDOUT:
605 <                error = "Connection timed out.";
605 >                error = "Connection timed out";
606                  break;
607          case WSATYPE_NOT_FOUND:
608 <                error = "Class type not found.";
608 >                error = "Class type not found";
609                  break;
610          case WSAEWOULDBLOCK:
611 <                error = "Resource temporarily unavailable.";
611 >                error = "Resource temporarily unavailable";
612                  break;
613          case WSAHOST_NOT_FOUND:
614 <                error = "Host not found.";
614 >                error = "Host not found";
615                  break;
616          case WSA_INVALID_HANDLE:
617 <                error = "Specified event object handle is invalid.";
617 >                error = "Specified event object handle is invalid";
618                  break;
619          case WSA_INVALID_PARAMETER:
620 <                error = "One or more parameters are invalid.";
620 >                error = "One or more parameters are invalid";
621                  break;
622   //      case WSAINVALIDPROCTABLE:
623 < //              error = "Invalid procedure table from service provider.";
623 > //              error = "Invalid procedure table from service provider";
624   //              break;
625   //      case WSAINVALIDPROVIDER:
626 < //              error = "Invalid service provider version number.";
626 > //              error = "Invalid service provider version number";
627   //              break;
628          case WSA_IO_INCOMPLETE:
629 <                error = "Overlapped I/O event object not in signaled state.";
629 >                error = "Overlapped I/O event object not in signaled state";
630                  break;
631          case WSA_IO_PENDING:
632 <                error = "Overlapped operations will complete later.";
632 >                error = "Overlapped operations will complete later";
633                  break;
634          case WSA_NOT_ENOUGH_MEMORY:
635 <                error = "Insufficient memory available.";
635 >                error = "Insufficient memory available";
636                  break;
637          case WSANOTINITIALISED:
638 <                error = "Successful WSAStartup not yet performed.";
638 >                error = "Successful WSAStartup not yet performed";
639                  break;
640          case WSANO_DATA:
641 <                error = "Valid name, no data record of requested type.";
641 >                error = "Valid name, no data record of requested type";
642                  break;
643          case WSANO_RECOVERY:
644 <                error = "This is a non-recoverable error.";
644 >                error = "This is a non-recoverable error";
645                  break;
646   //      case WSAPROVIDERFAILEDINIT:
647 < //              error = "Unable to initialize a service provider.";
647 > //              error = "Unable to initialize a service provider";
648   //              break;
649          case WSASYSCALLFAILURE:
650 <                error = "System call failure.";
650 >                error = "System call failure";
651                  break;
652          case WSASYSNOTREADY:
653 <                error = "Network subsystem is unavailable.";
653 >                error = "Network subsystem is unavailable";
654                  break;
655          case WSATRY_AGAIN:
656 <                error = "Non-authoritative host not found.";
656 >                error = "Non-authoritative host not found";
657                  break;
658          case WSAVERNOTSUPPORTED:
659 <                error = "WINSOCK.DLL version out of range.";
659 >                error = "WINSOCK.DLL version out of range";
660                  break;
661          case WSAEDISCON:
662 <                error = "Graceful shutdown in progress.";
662 >                error = "Graceful shutdown in progress";
663                  break;
664          case WSA_OPERATION_ABORTED:
665 <                error = "Overlapped operation aborted.";
665 >                error = "Overlapped operation aborted";
666                  break;
667          default:
668 <                error = "Unknown error.";
668 >                error = "Unknown error";
669                  break;
670          }
671  
# Line 573 | Line 673 | void HttpHandler::error(const string& pr
673   #else
674          if (host)
675          {
676 <                herror(prefix.c_str());
676 >                string error;
677 >
678 >                switch (h_errno)
679 >                {
680 >                case HOST_NOT_FOUND:
681 >                        error = "Unknown host";
682 >                        break;
683 >                case TRY_AGAIN:
684 >                        error = "Host name lookup failure";
685 >                        break;
686 >                case NO_RECOVERY:
687 >                        error = "Unknown server error";
688 >                        break;
689 >                case NO_DATA:
690 >                        error = "No address associated with name";
691 >                        break;
692 >                default:
693 >                        error = "Unknown error";
694 >                        break;
695 >                }
696 >
697 >                cerr << prefix << ": " << error << "\n";
698          }
699          else
700          {
# Line 581 | Line 702 | void HttpHandler::error(const string& pr
702          }
703   #endif // _WIN32
704   }
705 +
706 + #ifdef _OpenSSL_
707 + void HttpHandler::error(const string& prefix, int number)
708 + {
709 +        string error;
710 +
711 +        switch (SSL_get_error(ssl, number))
712 +        {
713 +        case SSL_ERROR_NONE:
714 +                error = "The TLS/SSL I/O operation completed";
715 +                break;
716 +        case SSL_ERROR_ZERO_RETURN:
717 +                error = "The TLS/SSL connection has been closed";
718 +                break;
719 +        case SSL_ERROR_WANT_READ:
720 +        case SSL_ERROR_WANT_WRITE:
721 +        case SSL_ERROR_WANT_CONNECT:
722 + //      case SSL_ERROR_WANT_ACCEPT:
723 +        case SSL_ERROR_WANT_X509_LOOKUP:
724 +                error = "The operation did not complete";
725 +                break;
726 +        case SSL_ERROR_SYSCALL:
727 +                if (int err = ERR_get_error() != 0)
728 +                {
729 +                        error = ERR_reason_error_string(err);
730 +                }
731 +                else
732 +                {
733 +                        switch (number)
734 +                        {
735 +                        case 0:
736 +                                error = "An EOF was observed that violates the protocol";
737 +                                break;
738 +                        case -1:
739 +                                this->error(prefix);
740 +                                return;
741 +                        default:
742 +                                error = "Unknown error";
743 +                                break;
744 +                        }
745 +                }
746 +                break;
747 +        case SSL_ERROR_SSL:
748 +                error = ERR_reason_error_string(ERR_get_error());
749 +                break;
750 +        default:
751 +                error = "Unknown error";
752 +                break;
753 +        }
754 +
755 +        cerr << prefix << ": " << error << "\n";
756 + }
757 +
758 + bool HttpHandler::starttls()
759 + {
760 +        SSL_load_error_strings();
761 +        SSL_library_init();
762 +
763 + #ifndef _urandomdev_
764 +        int pid(getpid()), now(time(NULL));
765 +        unsigned seed(now > pid ? now - pid : pid - now);
766 +        char* junk = new char[seed % 30 + 2];
767 +
768 +        junk[0] = pid;
769 +        junk[seed % 30 + 1] = now;
770 +
771 +        srand(seed);
772 +
773 +        for (size_t index = 1; index < seed % 30 + 1; index++)
774 +        {
775 +                junk[index] = rand();
776 +        }
777 +
778 +        if (debug)
779 +        {
780 +                cerr << "junk = {\n";
781 +
782 +                for (size_t index = 1; index < seed % 30 + 2; index++)
783 +                {
784 +                        cerr << "   [" << index << "] = " << unsigned(junk[index]) << "\n";
785 +                }
786 +
787 +                cerr << "}\n";
788 +        }
789 +
790 +        RAND_seed(junk, seed % 30 + 2);
791 +
792 +        delete junk;
793 + #else
794 +        if (debug) cerr << "junk = /dev/urandom\n";
795 + #endif
796 +
797 +        ctx = SSL_CTX_new(TLSv1_client_method());
798 +
799 +        if (ctx == NULL)
800 +        {
801 +                cerr << program << ": SSL CTX New: "
802 +                        << ERR_reason_error_string(ERR_get_error()) << "\n";
803 +
804 +                return false;
805 +        }
806 +
807 +        ssl = SSL_new(ctx);
808 +
809 +        if (SSL_set_fd(ssl, http) == 0)
810 +        {
811 +                cerr << program << ": SSL Set FD: "
812 +                        << ERR_reason_error_string(ERR_get_error()) << "\n";
813 +
814 +                return false;
815 +        }
816 +
817 +        int number;
818 +
819 +        if ((number = SSL_connect(ssl)) <= 0)
820 +        {
821 +                error(program + ": SSL Connect", number);
822 +
823 +                return false;
824 +        }
825 +
826 +        return true;
827 + }
828 + #endif

Comparing trunk/Search/HttpHandler.cpp (property svn:eol-style):
Revision 25 by douglas, 2002-12-22T23:32:58-08:00 vs.
Revision 350 by Douglas Thrift, 2004-05-27T20:29:11-07:00

# Line 0 | Line 1
1 + native

Comparing trunk/Search/HttpHandler.cpp (property svn:keywords):
Revision 25 by douglas, 2002-12-22T23:32:58-08:00 vs.
Revision 350 by Douglas Thrift, 2004-05-27T20:29:11-07:00

# Line 0 | Line 1
1 + Id

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines