PlaintextConnection.cpp 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #include "config.h"
  2. #include <cstring>
  3. #ifndef HTTPS_USE_WINSOCK
  4. # include <netdb.h>
  5. # include <unistd.h>
  6. # include <sys/types.h>
  7. # include <sys/socket.h>
  8. #else
  9. # include <winsock2.h>
  10. # include <ws2tcpip.h>
  11. #endif // HTTPS_USE_WINSOCK
  12. #include "PlaintextConnection.h"
  13. #ifdef HTTPS_USE_WINSOCK
  14. static void close(int fd)
  15. {
  16. closesocket(fd);
  17. }
  18. #endif // HTTPS_USE_WINSOCK
  19. PlaintextConnection::PlaintextConnection()
  20. : fd(-1)
  21. {
  22. #ifdef HTTPS_USE_WINSOCK
  23. static bool wsaInit = false;
  24. if (!wsaInit)
  25. {
  26. WSADATA data;
  27. WSAStartup(MAKEWORD(2, 2), &data);
  28. }
  29. #endif // HTTPS_USE_WINSOCK
  30. }
  31. PlaintextConnection::~PlaintextConnection()
  32. {
  33. if (fd != -1)
  34. ::close(fd);
  35. }
  36. bool PlaintextConnection::connect(const std::string &hostname, uint16_t port)
  37. {
  38. addrinfo hints;
  39. std::memset(&hints, 0, sizeof(hints));
  40. hints.ai_flags = hints.ai_protocol = 0;
  41. hints.ai_family = AF_UNSPEC;
  42. hints.ai_socktype = SOCK_STREAM;
  43. addrinfo *addrs = nullptr;
  44. std::string portString = std::to_string(port);
  45. getaddrinfo(hostname.c_str(), portString.c_str(), &hints, &addrs);
  46. // Try all addresses returned
  47. bool connected = false;
  48. for (addrinfo *addr = addrs; !connected && addr; addr = addr->ai_next)
  49. {
  50. fd = socket(addr->ai_family, SOCK_STREAM, 0);
  51. connected = ::connect(fd, addr->ai_addr, addr->ai_addrlen) == 0;
  52. if (!connected)
  53. ::close(fd);
  54. }
  55. freeaddrinfo(addrs);
  56. if (!connected)
  57. {
  58. fd = -1;
  59. return false;
  60. }
  61. return true;
  62. }
  63. size_t PlaintextConnection::read(char *buffer, size_t size)
  64. {
  65. auto read = ::recv(fd, buffer, size, 0);
  66. if (read < 0)
  67. read = 0;
  68. return static_cast<size_t>(read);
  69. }
  70. size_t PlaintextConnection::write(const char *buffer, size_t size)
  71. {
  72. auto written = ::send(fd, buffer, size, 0);
  73. if (written < 0)
  74. written = 0;
  75. return static_cast<size_t>(written);
  76. }
  77. void PlaintextConnection::close()
  78. {
  79. ::close(fd);
  80. fd = -1;
  81. }
  82. int PlaintextConnection::getFd() const
  83. {
  84. return fd;
  85. }