httpsession.cpp
上传用户:zslianheng
上传日期:2013-04-03
资源大小:946k
文件大小:4k
源码类别:

Linux/Unix编程

开发平台:

Visual C++

  1. /***************************************************************************
  2.  *                                                                         *
  3.  *   This program is free software; you can redistribute it and/or modify  *
  4.  *   it under the terms of the GNU General Public License as published by  *
  5.  *   the Free Software Foundation; either version 2 of the License, or     *
  6.  *   (at your option) any later version.                                   *
  7.  *                                                                         *
  8.  *   copyright            : (C) 2002 by Zhang Yong                         *
  9.  *   email                : z-yong163@163.com                              *
  10.  ***************************************************************************/
  11. #include "httpsession.h"
  12. #include "sessionlistener.h"
  13. #include "icqsocket.h"
  14. #include "icqclient.h"
  15. #include "udppacket.h"
  16. #include "base64.h"
  17. #define MYICQ_HTTP_PORT 443
  18. enum {
  19. HTTP_STATUS_CONNECT,
  20. HTTP_STATUS_ESTABLISHED
  21. };
  22. HttpSession::HttpSession()
  23. {
  24. sock = -1;
  25. status = -1;
  26. listener = NULL;
  27. bufSize = 0;
  28. }
  29. HttpSession::~HttpSession()
  30. {
  31. if (sock >= 0)
  32. IcqSocket::closeSocket(sock);
  33. }
  34. bool HttpSession::start(const char *destHost, ProxyInfo &proxy)
  35. {
  36. this->destHost = destHost;
  37. bufSize = 0;
  38. if (sock >= 0)
  39. IcqSocket::closeSocket(sock);
  40. sock = IcqSocket::createSocket(SOCK_STREAM, this);
  41. sockaddr_in addr;
  42. memset(&addr, 0, sizeof(addr));
  43. addr.sin_family = AF_INET;
  44. uname = proxy.username;
  45. passwd = proxy.passwd;
  46. const char *host = proxy.host.c_str();
  47. if ((addr.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) {
  48. hostent *he = gethostbyname(host);
  49. if (!he)
  50. goto failed;
  51. addr.sin_addr = *(in_addr *) he->h_addr;
  52. }
  53. addr.sin_port = htons(proxy.port);
  54. status = HTTP_STATUS_CONNECT;
  55. if (connect(sock, (sockaddr *) &addr, sizeof(addr)) == 0)
  56. onConnect(true);
  57. else if (IcqSocket::getSocketError() != EINPROGRESS)
  58. goto failed;
  59. return true;
  60. failed:
  61. close(sock);
  62. sock = -1;
  63. listener->sessionFinished(false);
  64. return false;
  65. }
  66. void HttpSession::onConnect(bool success)
  67. {
  68. if (!success) {
  69. listener->sessionFinished(false);
  70. return;
  71. }
  72. string request = "CONNECT ";
  73. request += destHost + ":" + itoa(MYICQ_HTTP_PORT, buf, 10);
  74. request += " HTTP/1.0rn";
  75. request += "User-agent: MyICQrn";
  76. if (!uname.empty()) {
  77. string str = uname + ":" + passwd;
  78. char *code = NULL;
  79. encode_base64(str.c_str(), str.length(), &code);
  80. if (code) {
  81. request += "Proxy-authorization: Basic ";
  82. request += code;
  83. request += "rn";
  84. free(code);
  85. }
  86. }
  87. request += "rn";
  88. send(sock, request.c_str(), request.length(), 0);
  89. }
  90. bool HttpSession::onReceive()
  91. {
  92. int n;
  93. if (status == HTTP_STATUS_CONNECT) {
  94. n = recv(sock, buf, sizeof(buf), 0);
  95. if (n <= 0)
  96. goto failed;
  97. buf[n] = '';
  98. char *p1 = strchr(buf, ' ');
  99. char *p2 = strchr(buf, 'r');
  100. if (!p1 || !p2)
  101. goto failed;
  102. ++p1;
  103. if (strnicmp(p1, "200 Connection established", p2 - p1) != 0)
  104. goto failed;
  105. status = HTTP_STATUS_ESTABLISHED;
  106. listener->sessionFinished(true);
  107. } else if (status == HTTP_STATUS_ESTABLISHED)
  108. return recvPacket();
  109. return true;
  110. failed:
  111. IcqSocket::closeSocket(sock);
  112. sock = -1;
  113. listener->sessionFinished(false);
  114. return false;
  115. }
  116. void HttpSession::onClose()
  117. {
  118. }
  119. bool HttpSession::recvPacket()
  120. {
  121. int n;
  122. while ((n = recv(sock, buf + bufSize, sizeof(buf) - bufSize, 0)) > 0) {
  123. bufSize += n;
  124. char *start = buf;
  125. char *end = start + bufSize;
  126. uint16 len;
  127. while (start + sizeof(len) < end) {
  128. len = ntohs(*(uint16 *) start);
  129. if (end - start - sizeof(len) < len)
  130. break;
  131. start += sizeof(len);
  132. if (len >= sizeof(UDP_HEADER)) {
  133. UdpInPacket in(start, len);
  134. listener->onPacketReceived(in);
  135. }
  136. start += len;
  137. }
  138. bufSize = end - start;
  139. if (bufSize > 0)
  140. memcpy(buf, start, bufSize);
  141. }
  142. if (n == 0)
  143. onClose();
  144. return (n >= 0);
  145. }