daily pastebin goal
90%
SHARE
TWEET

SyncHTTP Sources

Hauke Aug 11th, 2013 149 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* all files copied together */
  2. #ifndef SOCKET_H
  3. #define SOCKET_H
  4.  
  5. #include <WinSock2.h>
  6.  
  7. #include <string>
  8.  
  9. enum TypeSocket {BlockingSocket, NonBlockingSocket};
  10.  
  11. class Socket {
  12. public:
  13.  
  14.   virtual ~Socket();
  15.   Socket(const Socket&);
  16.   Socket& operator=(Socket&);
  17.  
  18.   std::string ReceiveLine();
  19.   int Socket::ReceiveContent(std::string & result);
  20.   std::string ReceiveBytes();
  21.  
  22.   void   Close();
  23.   void   SendLine (std::string);
  24.   void   SendBytes(const std::string&);
  25.  
  26. protected:
  27.   friend class SocketServer;
  28.   friend class SocketSelect;
  29.  
  30.   Socket(SOCKET s);
  31.   Socket();
  32.  
  33.  
  34.   SOCKET s_;
  35.  
  36.   int* refCounter_;
  37.  
  38. private:
  39.   static void Start();
  40.   static void End();
  41.   static int  nofSockets_;
  42. };
  43.  
  44. class SocketClient : public Socket {
  45. public:
  46.   SocketClient(const std::string& host, int port);
  47. };
  48.  
  49. class SocketServer : public Socket {
  50. public:
  51.   SocketServer(int port, int connections, TypeSocket type=BlockingSocket);
  52.  
  53.   Socket* Accept();
  54. };
  55.  
  56. class SocketSelect {
  57.   public:
  58.     SocketSelect(Socket const * const s1, Socket const * const s2=NULL, TypeSocket type=BlockingSocket);
  59.  
  60.     bool Readable(Socket const * const s);
  61.  
  62.   private:
  63.     fd_set fds_;
  64. };
  65. #endif
  66.  
  67.  
  68.  
  69. #include "socket.h"
  70. #include <iostream>
  71.  
  72. using namespace std;
  73.  
  74. int Socket::nofSockets_= 0;
  75.  
  76. void Socket::Start() {
  77.   if (!nofSockets_) {
  78.     WSADATA info;
  79.     if (WSAStartup(MAKEWORD(2,0), &info)) {
  80.       throw "Could not start WSA";
  81.     }
  82.   }
  83.   ++nofSockets_;
  84. }
  85.  
  86. void Socket::End() {
  87.   WSACleanup();
  88. }
  89.  
  90. Socket::Socket() : s_(0) {
  91.   Start();
  92.   s_ = socket(AF_INET,SOCK_STREAM,0);
  93.  
  94.   if (s_ == INVALID_SOCKET) {
  95.           return;
  96.   }
  97.  
  98.   refCounter_ = new int(1);
  99. }
  100.  
  101. Socket::Socket(SOCKET s) : s_(s) {
  102.   Start();
  103.   refCounter_ = new int(1);
  104. };
  105.  
  106. Socket::~Socket() {
  107.   if (! --(*refCounter_)) {
  108.     Close();
  109.     delete refCounter_;
  110.   }
  111.  
  112.   --nofSockets_;
  113.   if (!nofSockets_) End();
  114. }
  115.  
  116. Socket::Socket(const Socket& o) {
  117.   refCounter_=o.refCounter_;
  118.   (*refCounter_)++;
  119.   s_         =o.s_;
  120.  
  121.   nofSockets_++;
  122. }
  123.  
  124. Socket& Socket::operator=(Socket& o) {
  125.   (*o.refCounter_)++;
  126.  
  127.   refCounter_=o.refCounter_;
  128.   s_         =o.s_;
  129.  
  130.   nofSockets_++;
  131.  
  132.   return *this;
  133. }
  134.  
  135. void Socket::Close() {
  136.   closesocket(s_);
  137. }
  138.  
  139. std::string Socket::ReceiveBytes() {
  140.   std::string ret;
  141.   char buf[1024];
  142.  
  143.   while (1) {
  144.     u_long arg = 0;
  145.     if (ioctlsocket(s_, FIONREAD, &arg) != 0)
  146.       break;
  147.  
  148.     if (arg == 0)
  149.       break;
  150.  
  151.     if (arg > 1024) arg = 1024;
  152.  
  153.     int rv = recv (s_, buf, arg, 0);
  154.     if (rv <= 0) break;
  155.  
  156.     std::string t;
  157.  
  158.     t.assign (buf, rv);
  159.     ret += t;
  160.   }
  161.  
  162.   return ret;
  163. }
  164.  
  165.  
  166. int Socket::ReceiveContent(std::string & result) {
  167.         std::string firstLine = Socket::ReceiveLine();
  168.         if (firstLine.find("302 Found") != std::string::npos)   //redirect
  169.         {
  170.                 std::string lineBytes;
  171.                 while(true)
  172.                 {
  173.                         while (true)
  174.                         {
  175.                                 char r;
  176.                                 if(!recv(s_, &r, 1, 0))
  177.                                         break;
  178.                                 lineBytes += r;
  179.                                 if (r == '\n')
  180.                                         break;
  181.                         }
  182.                         if(lineBytes.empty())
  183.                         {
  184.                                 result = "";
  185.                                 return 302;
  186.                         }
  187.                         if (lineBytes.find("Location:") != std::string::npos)
  188.                                 break;
  189.                 }
  190.                 result = lineBytes.substr(10);
  191.                 return 302;
  192.         }
  193.         else if (firstLine.find("200 OK") != std::string::npos)
  194.         {
  195.                 while(true)
  196.                 {
  197.                         std::string lineBytes;
  198.                         while (true)
  199.                         {
  200.                                 char r;
  201.                                 if(!recv(s_, &r, 1, 0))
  202.                                         break;
  203.                                 lineBytes += r;
  204.                                 if (r == '\n')
  205.                                         break;
  206.                         }
  207.                         if(lineBytes.empty())
  208.                                 break;
  209.                         if(lineBytes.find("wbb_resp:") != std::string::npos)
  210.                         {
  211.                                 result = lineBytes.substr(10);
  212.                                 break;
  213.                         }
  214.                 }
  215.                 return 200;
  216.         }
  217.         else
  218.         {
  219.                 result = "none";
  220.                 return 0;
  221.         }
  222. }
  223.  
  224. std::string Socket::ReceiveLine() {
  225.   std::string ret;
  226.   while (1) {
  227.     char r;
  228.  
  229.     switch(recv(s_, &r, 1, 0)) {
  230.       case 0:
  231.         return ret;
  232.       case -1:
  233.         return "";
  234.     }
  235.  
  236.     ret += r;
  237.     if (r == '\n')
  238.                 return ret;
  239.   }
  240. }
  241.  
  242. void Socket::SendLine(std::string s) {
  243.   s += '\n';
  244.   send(s_,s.c_str(),s.length(),0);
  245. }
  246.  
  247. void Socket::SendBytes(const std::string& s) {
  248.   send(s_,s.c_str(),s.length(),0);
  249. }
  250.  
  251. SocketServer::SocketServer(int port, int connections, TypeSocket type) {
  252.   sockaddr_in sa;
  253.  
  254.   memset(&sa, 0, sizeof(sa));
  255.  
  256.   sa.sin_family = PF_INET;            
  257.   sa.sin_port = htons(port);          
  258.   s_ = socket(AF_INET, SOCK_STREAM, 0);
  259.   if (s_ == INVALID_SOCKET) {
  260.     return;
  261.   }
  262.  
  263.   if(type==NonBlockingSocket) {
  264.     u_long arg = 1;
  265.     ioctlsocket(s_, FIONBIO, &arg);
  266.   }
  267.  
  268.   if (bind(s_, (sockaddr *)&sa, sizeof(sockaddr_in)) == SOCKET_ERROR) {
  269.     closesocket(s_);
  270.     return;
  271.   }
  272.  
  273.   listen(s_, connections);                              
  274. }
  275.  
  276. Socket* SocketServer::Accept() {
  277.   SOCKET new_sock = accept(s_, 0, 0);
  278.   if (new_sock == INVALID_SOCKET) {
  279.     int rc = WSAGetLastError();
  280.     if(rc==WSAEWOULDBLOCK) {
  281.       return 0;
  282.     }
  283.     else {
  284.       throw "Invalid Socket";
  285.     }
  286.   }
  287.  
  288.   Socket* r = new Socket(new_sock);
  289.   return r;
  290. }
  291.  
  292. SocketClient::SocketClient(const std::string& host, int port) : Socket() {
  293.   std::string error;
  294.  
  295.   hostent *he;
  296.   if ((he = gethostbyname(host.c_str())) == 0) {
  297.     error = strerror(errno);
  298.     throw error;
  299.   }
  300.  
  301.   sockaddr_in addr;
  302.   addr.sin_family = AF_INET;
  303.   addr.sin_port = htons(port);
  304.   addr.sin_addr = *((in_addr *)he->h_addr);
  305.   memset(&(addr.sin_zero), 0, 8);
  306.  
  307.   if (::connect(s_, (sockaddr *) &addr, sizeof(sockaddr))) {
  308.     error = strerror(WSAGetLastError());
  309.     throw error;
  310.   }
  311. }
  312.  
  313. SocketSelect::SocketSelect(Socket const * const s1, Socket const * const s2, TypeSocket type) {
  314.   FD_ZERO(&fds_);
  315.   FD_SET(const_cast<Socket*>(s1)->s_,&fds_);
  316.   if(s2) {
  317.     FD_SET(const_cast<Socket*>(s2)->s_,&fds_);
  318.   }    
  319.  
  320.   TIMEVAL tval;
  321.   tval.tv_sec  = 0;
  322.   tval.tv_usec = 1;
  323.  
  324.   TIMEVAL *ptval;
  325.   if(type==NonBlockingSocket) {
  326.     ptval = &tval;
  327.   }
  328.   else {
  329.     ptval = 0;
  330.   }
  331.  
  332.   if (select (0, &fds_, (fd_set*) 0, (fd_set*) 0, ptval) == SOCKET_ERROR)
  333.     return;
  334. }
  335.  
  336. bool SocketSelect::Readable(Socket const* const s) {
  337.   if (FD_ISSET(s->s_,&fds_)) return true;
  338.   return false;
  339. }
  340.  
  341.  
  342.  
  343.  
  344. static cell AMX_NATIVE_CALL n_SynchronizedHTTP( AMX* amx, cell* params )
  345. {
  346.         /*
  347.         params[1]               char array                      URL
  348.         params[2]               char array                      Post data
  349.         params[3]               ref char array          Result string
  350.         params[4]               int                                     Result string lenght
  351.         params[5]               int                                     Method (1 = GET, 2 = POST)
  352.         params[6]               int                                     Timeout in seconds
  353.         params[7]               bool                            Debug
  354.         */
  355.  
  356.         std::string
  357.                 paramURL = GetAMXString(amx, params[1]),
  358.                 paramData = GetAMXString(amx, params[2]);
  359.  
  360.         int
  361.                 method = params[5],
  362.                 timeout = params[6];
  363.  
  364.         bool
  365.                 debug = params[7];
  366.  
  367.         if(paramURL.length() < 3)
  368.                 return 0;
  369.  
  370.         if(paramURL.find("http://") != 0)
  371.                 paramURL = "http://" + paramURL;
  372.  
  373.         CURL *curlSession;
  374.         clock_t timeBegin, timeEnd;
  375.         double timeSpent;
  376.         curlSession = curl_easy_init();
  377.         if(curlSession)
  378.         {
  379.                 CURLcode response;
  380.                 std::string readBuffer;
  381.                 long httpCode = 0;
  382.                 timeBegin = clock();
  383.  
  384.                 if(method == 1)
  385.                 {
  386.                         if(!paramData.empty())
  387.                         {
  388.                                 if(paramURL.find("?"))
  389.                                         paramURL.append("&");
  390.                                 else
  391.                                         paramURL.append("?");
  392.                         }
  393.                         paramURL.append(paramData.data());
  394.                         curl_easy_setopt(curlSession, CURLOPT_URL, paramURL);
  395.                 }
  396.                 else if(method == 2)
  397.                 {
  398.                         curl_easy_setopt(curlSession, CURLOPT_URL, paramURL.data());
  399.                         curl_easy_setopt(curlSession, CURLOPT_POST, 1);
  400.                         curl_easy_setopt(curlSession, CURLOPT_POSTFIELDS, paramData.data());
  401.                 }
  402.                 else
  403.                 {
  404.                         if(debug)
  405.                                 logprintf(">> SyncHTTP Plugin Error: Unknown method");
  406.                         return -1;
  407.                 }
  408.  
  409.                 curl_easy_setopt(curlSession, CURLOPT_WRITEFUNCTION, WriteCallback);
  410.                 curl_easy_setopt(curlSession, CURLOPT_WRITEDATA, &readBuffer);
  411.                 curl_easy_setopt(curlSession, CURLOPT_FORBID_REUSE, false);
  412.                 curl_easy_setopt(curlSession, CURLOPT_TIMEOUT, timeout);
  413.                 curl_easy_setopt(curlSession, CURLOPT_FOLLOWLOCATION, true);
  414.                 curl_easy_setopt(curlSession, CURLOPT_MAXREDIRS, 50);
  415.                
  416.                 response = curl_easy_perform(curlSession);
  417.  
  418.                 curl_easy_getinfo (curlSession, CURLINFO_RESPONSE_CODE, &httpCode);
  419.                
  420.                 if(response != CURLE_OK)
  421.                 {
  422.                         if(debug)
  423.                                 logprintf(">> SyncHTTP Plugin Error: %s", curl_easy_strerror(response));
  424.                         return -1;
  425.                 }
  426.                 if(debug)
  427.                 {
  428.                         timeEnd = clock();
  429.                         timeSpent = (double)(timeEnd - timeBegin) / CLOCKS_PER_SEC;
  430.                         logprintf(">> SyncHTTP Plugin\nRequest sent to: \"%s\"\nStatus: %d\nPost: \"%s\"\nTime spent to perform request: %f sec\nResponse: \"%s\"", paramURL.c_str(), (int)httpCode, method == 2 ? paramData.c_str() : "", timeSpent, readBuffer.c_str());
  431.                 }
  432.  
  433.                 SetAMXString(amx, params[3], (int)params[4], readBuffer);
  434.  
  435.                 curl_easy_cleanup(curlSession);
  436.                 return (int)httpCode;
  437.         }
  438.         return -1;
  439. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top