00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "SocketHTTPProxy.hh"
00024 #include "PrettyDebug.hh"
00025
00026 #include <cstdlib>
00027 #include <cstring>
00028 #include <cerrno>
00029
00030 namespace certi {
00031
00032 static PrettyDebug D("SOCKHTTP", "(SocketHTTPProxy) - ");
00033 static PrettyDebug G("GENDOC",__FILE__);
00034
00094
00095 SocketHTTPProxy::SocketHTTPProxy() : SocketTCP()
00096 {
00097 }
00098
00099
00100 SocketHTTPProxy::~SocketHTTPProxy()
00101 {
00102 }
00103
00104
00105 void
00106 SocketHTTPProxy::createConnection(const char *server_name, unsigned int port)
00107 throw (NetworkError)
00108 {
00109 const char *http_proxy;
00110
00111 http_proxy = getenv("CERTI_HTTP_PROXY");
00112 if (http_proxy == NULL)
00113 http_proxy = getenv("http_proxy");
00114
00115 if (http_proxy != NULL) {
00116 std::string proxy_address;
00117 in_port_t proxy_port;
00118
00119 const char *strpport = strchr(http_proxy, ':');
00120 if (strpport) {
00121 proxy_address.assign(http_proxy, strpport-http_proxy);
00122 proxy_port = atoi(strpport+1);
00123 }
00124 else {
00125 proxy_address.assign(http_proxy);
00126 proxy_port = 3128;
00127 }
00128
00129 D.Out(pdTrace, "Connect to '%s:%d' via 'http://%s:%d'.",
00130 server_name, port, proxy_address.c_str(), proxy_port);
00131 SocketTCP::createConnection(proxy_address.c_str(), proxy_port);
00132 sendHTTPConnect(server_name, port);
00133 }
00134 else {
00135 D.Out(pdTrace, "Connect to '%s:%d'.", server_name, port);
00136 SocketTCP::createConnection(server_name, port);
00137 }
00138 }
00139
00140
00141 int SocketHTTPProxy::sendHTTPConnect(const char* addr, in_port_t port)
00142 {
00143 std::stringstream request;
00144
00145 request
00146 << "CONNECT " << addr << ":" << port << " HTTP/1.0\x0D\x0A"
00147 << "Host: " << addr << ":" << port << "\x0D\x0A"
00148 << "\x0D\x0A";
00149
00150 D.Out(pdTrace, "HTTP proxy connection request\n%s<",
00151 request.str().c_str());
00152
00153 send((const unsigned char*)request.str().c_str(), request.str().length());
00154
00155 size_t received;
00156 static const size_t maxLineLength = 1024;
00157 char response[maxLineLength];
00158
00159
00160 timeoutTCP(5,0);
00161
00162 received = receiveLine(response, maxLineLength);
00163 D.Out(pdTrace, "<HTTP PROXY> %s", response);
00164
00165 char* sCode;
00166
00167 if (received < 5 || strncmp(response,"HTTP/",5) != 0 ||
00168 (sCode = strchr(response, ' ')) == NULL) {
00169 D.Out(pdDebug, "Unexpected HTTP response.");
00170 throw NetworkError("Unexpected HTTP response.");
00171 }
00172
00173 int iCode = atoi(sCode);
00174
00175 if (iCode < 200 || iCode >= 300) {
00176 std::stringstream msg;
00177 msg << "Proxy connection refused: " << response;
00178 D.Out(pdDebug, "%s", msg.str().c_str());
00179 throw NetworkError(msg.str().c_str());
00180 }
00181
00182
00183
00184 do {
00185 timeoutTCP(5,0);
00186
00187 received = receiveLine(response, maxLineLength);
00188 D.Out(pdTrace, "<HTTP PROXY> %s", response);
00189 }
00190 while (received > 0);
00191
00192 return 1;
00193 }
00194
00195
00196 size_t
00197 SocketHTTPProxy::receiveLine(char *buffer, size_t max_size)
00198 throw (NetworkError, NetworkSignal)
00199 {
00200 size_t nReceived = 0;
00201 while (nReceived < max_size-1)
00202 {
00203 int result = ::recv(SocketTCP::returnSocket(), buffer+nReceived, 1, 0);
00204 if (result < 0)
00205 {
00206 D.Out(pdExcept, "Error while receiving on TCP socket.");
00207 #ifdef _WIN32
00208 if (WSAGetLastError() == WSAEINTR)
00209 #else
00210 if (errno == EINTR)
00211 #endif
00212 throw NetworkSignal("");
00213 else {
00214 perror("TCP Socket(RecevoirTCP) ");
00215 throw NetworkError("Error while receiving TCP message.");
00216 }
00217 }
00218 else if (result == 0) {
00219 D.Out(pdExcept, "TCP connection has been closed by peer.");
00220 throw NetworkError("Connection closed by client.");
00221 }
00222
00223 nReceived += result;
00224
00225 RcvdBytesCount += result;
00226
00227 if (buffer[nReceived-1] == '\x0A') {
00228
00229 if(nReceived > 1 && buffer[nReceived-2] == '\x0D') {
00230 buffer[nReceived-2] = 0;
00231 return nReceived-2;
00232 }
00233 else {
00234 buffer[nReceived-1] = 0;
00235 return nReceived-1;
00236 }
00237 }
00238 }
00239
00240 throw NetworkError("Too large HTTP response received.");
00241 }
00242
00243 }
00244
00245