00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 struct URL
00039 {
00040 URL(const char* url)
00041 {
00042 parse_url(url);
00043 }
00044
00045 string _scheme;
00046 string _hostname;
00047 string _port;
00048 string _path;
00049
00050 bool parse_url(const char* str, const char* default_port="80")
00051 {
00052 if (!str || !*str)
00053 return false;
00054
00055 const char* p1 = strstr(str, "://");
00056
00057 if (p1) {
00058 _scheme.assign(str, p1-str);
00059 p1 += 3;
00060 } else
00061 p1 = str;
00062
00063 const char* p2 = strchr(p1, ':');
00064 const char* p3 = p2? strchr(p2+1, '/'): p2;
00065
00066 if (p2) {
00067 _hostname.assign(p1, p2-p1);
00068 _port.assign(p2+1, p3-(p2+1));
00069 _path = p3;
00070 } else {
00071 _hostname = p1;
00072 _port = default_port;
00073 _path.erase();
00074 }
00075
00076 if (_path.empty())
00077 _path = "/";
00078
00079 return true;
00080 }
00081 };
00082
00083
00084 #ifdef _WIN32
00085
00086
00087 struct WinSockInit : public WSADATA
00088 {
00089 WinSockInit(WORD version=MAKEWORD(2,2))
00090 {
00091 _error = WSAStartup(version, this);
00092
00093 if (!_error && wVersion!=version) {
00094 _error = WSAVERNOTSUPPORTED;
00095 WSACleanup();
00096 }
00097 }
00098
00099 WinSockInit::~WinSockInit()
00100 {
00101 if (!_error)
00102 WSACleanup();
00103 }
00104
00105 int _error;
00106 };
00107
00108 #define S_ADDR(a) (a.S_un.S_addr)
00109
00110 #else // _WIN32
00111
00112 #include <unistd.h>
00113 #include <sys/socket.h>
00114
00115 typedef u_int SOCKET;
00116 #define SOCKET_ERROR (-1)
00117 #define INVALID_SOCKET (SOCKET)(~0)
00118
00119 #define S_ADDR(a) (a.s_addr)
00120
00121 typedef struct sockaddr_in SOCKADDR_IN;
00122
00123 #define closesocket(fd) close(fd)
00124 #define WSAGetLastError() errno
00125 #define WSAEWOULDBLOCK EWOULDBLOCK
00126
00127 #endif // _WIN32
00128
00129
00130 #ifndef SD_SEND
00131 #define SD_RECEIVE 0x00
00132 #define SD_SEND 0x01
00133 #define SD_BOTH 0x02
00134 #endif
00135
00136
00137 #ifndef socklen_t
00138 #ifdef _WIN32
00139 typedef int socklen_t;
00140 #else
00141 typedef unsigned int socklen_t;
00142 #endif
00143 #endif
00144
00145
00146 struct AddressList
00147 {
00148 AddressList()
00149 : _paddr_info(NULL)
00150 {
00151 }
00152
00153 ~AddressList()
00154 {
00155 clear();
00156 }
00157
00158 void clear()
00159 {
00160 if (_paddr_info) {
00161 freeaddrinfo(_paddr_info);
00162 _paddr_info = NULL;
00163 }
00164 }
00165
00166 void resolve(const char* hostname, const char* service, int flags, int family=PF_INET)
00167 {
00168 addrinfo hints = {flags, family, SOCK_STREAM};
00169
00170 int ret = getaddrinfo(hostname, service, &hints, &_paddr_info);
00171
00172 if (ret != 0) {
00173 #ifdef _WIN32
00174 throw WE(ret);
00175 #else
00176 throw Exception(gai_strerror(ret));
00177 #endif
00178 }
00179
00180
00181 }
00182
00183 const addrinfo* get_first() const
00184 {
00185 assert(_paddr_info!=NULL);
00186 return _paddr_info;
00187 }
00188
00189 private:
00190 addrinfo* _paddr_info;
00191 };
00192
00193
00194
00195 struct Socket
00196 {
00197 Socket()
00198 : _sock(INVALID_SOCKET)
00199 {
00200 }
00201
00202 Socket(SOCKET socket)
00203 {
00204 init(socket);
00205 }
00206
00207 void init(SOCKET socket)
00208 {
00209 _sock = socket;
00210 }
00211
00212 ~Socket()
00213 {
00214 close();
00215 }
00216
00217 operator SOCKET() {return _sock;}
00218
00219 void connect(const AddressList& addr)
00220 {
00221 assert(_sock==INVALID_SOCKET);
00222
00223
00224 for(const addrinfo*pai=addr.get_first(); pai; pai=pai->ai_next) {
00225 _sock = socket(pai->ai_family, pai->ai_socktype, pai->ai_protocol);
00226
00227 if (_sock != INVALID_SOCKET)
00228 if (::connect(_sock, pai->ai_addr, pai->ai_addrlen) != SOCKET_ERROR)
00229 return;
00230 else
00231 ::closesocket(_sock);
00232 }
00233
00234 throw LWSE();
00235 }
00236
00237 void bind(const AddressList& addr)
00238 {
00239 assert(_sock==INVALID_SOCKET);
00240
00241
00242 for(const addrinfo*pai=addr.get_first(); pai; pai=pai->ai_next) {
00243 _sock = socket(pai->ai_family, pai->ai_socktype, pai->ai_protocol);
00244
00245 if (_sock != INVALID_SOCKET)
00246 if (::bind(_sock, pai->ai_addr, pai->ai_addrlen) != SOCKET_ERROR)
00247 return;
00248 else
00249 ::closesocket(_sock);
00250 }
00251
00252 throw LWSE();
00253 }
00254
00255 void close()
00256 {
00257 if (_sock != INVALID_SOCKET) {
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 ::closesocket(_sock);
00269
00270 _sock = INVALID_SOCKET;
00271 }
00272 }
00273
00274
00275 int receive(char* buffer, size_t len, int flags=0)
00276 {
00277 int sum = 0;
00278
00279 while(len > 0) {
00280 int rcvd = receive_fragmented(buffer, len, flags);
00281 if (rcvd <= 0)
00282 break;
00283
00284 buffer += rcvd;
00285 len -= rcvd;
00286 sum += rcvd;
00287 }
00288
00289 return sum;
00290 }
00291
00292
00293 int receive_fragmented(char* buffer, int len, int flags=0)
00294 {
00295 int ret = ::recv(_sock, (char*)buffer, len, flags);
00296
00297 if (ret == SOCKET_ERROR) {
00298 int error = WSAGetLastError();
00299
00300 if (error == WSAEWOULDBLOCK)
00301 ret = 0;
00302 else
00303 throw LWSE();
00304 }
00305
00306 return ret;
00307 }
00308
00309
00310 int send(const char* buffer, size_t len, int flags=0)
00311 {
00312 int ret = ::send(_sock, buffer, len, flags);
00313
00314 if (ret == SOCKET_ERROR)
00315 throw LWSE();
00316
00317 return ret;
00318 }
00319
00320 protected:
00321 SOCKET _sock;
00322 };
00323
00324
00325 struct SocketReader
00326 {
00327 SocketReader(Socket& socket)
00328 : _socket(socket),
00329 _state(0),
00330 _g_ptr(_buffer),
00331 _e_ptr(_buffer)
00332 {
00333 *_buffer = '\0';
00334 }
00335
00336 int get_state()
00337 {
00338 return _state;
00339 }
00340
00341 int peek()
00342 {
00343 if (_g_ptr == _e_ptr)
00344 fetch();
00345
00346 if (_g_ptr != _e_ptr)
00347 return *_g_ptr;
00348 else
00349 return EOF;
00350 }
00351
00352 void next()
00353 {
00354 if (_g_ptr != _e_ptr)
00355 ++_g_ptr;
00356 }
00357
00358
00359 int read_line(char* line, size_t len)
00360 {
00361 char* p = NULL;
00362 char* end = line + (len-1);
00363
00364 for(;;) {
00365 if (p && p>=end)
00366 break;
00367
00368 int c = peek();
00369
00370 if (c == EOF) {
00371 _state |= ios_base::eofbit;
00372
00373 if (p == line)
00374 _state |= ios_base::failbit;
00375 break;
00376 }
00377
00378 if (!p)
00379 p = line;
00380
00381 if (c == '\n') {
00382 next();
00383
00384 break;
00385 } else if (c == '\r') {
00386 next();
00387
00388 if (peek() == '\n')
00389 next();
00390
00391 break;
00392 } else
00393 *p++ = (char)c;
00394
00395 next();
00396 }
00397
00398 if (!p)
00399 p = line;
00400
00401 *p = '\0';
00402
00403 return p - line;
00404 }
00405
00406
00407 int read(char* buffer, size_t len)
00408 {
00409 int sum = 0;
00410
00411
00412 size_t avail = _e_ptr - _g_ptr;
00413
00414 if (avail > 0) {
00415 size_t read = min(avail, len);
00416 memcpy(buffer, _g_ptr, read);
00417 _g_ptr += read;
00418
00419 buffer += read;
00420 len -= read;
00421 }
00422
00423
00424 if (len > 0)
00425 sum += _socket.receive(buffer, len);
00426
00427 return sum;
00428 }
00429
00430
00431 string receive_all()
00432 {
00433 ostringstream ret;
00434 char buffer[BUFFER_LEN];
00435
00436
00437 int avail = _e_ptr - _g_ptr;
00438
00439 if (avail > 0) {
00440 ret.write(_g_ptr, avail);
00441 _g_ptr = _e_ptr;
00442 }
00443
00444
00445 for(;;) {
00446 int read = _socket.receive_fragmented(buffer, BUFFER_LEN);
00447
00448 if (read <= 0)
00449 break;
00450
00451 ret.write(buffer, read);
00452 }
00453
00454 return ret.str();
00455 }
00456
00457 private:
00458 Socket& _socket;
00459 int _state;
00460
00461 char _buffer[BUFFER_LEN];
00462 char* _g_ptr;
00463 char* _e_ptr;
00464
00465 void fetch()
00466 {
00467 int read = _socket.receive_fragmented(_buffer, BUFFER_LEN);
00468
00469 if (read >= 0) {
00470 _g_ptr = _buffer;
00471 _e_ptr = _buffer + read;
00472 }
00473 }
00474 };
00475
00476
00477 struct INConnect : public Socket
00478 {
00479 INConnect(const AddressList& addr)
00480 {
00481 Socket::connect(addr);
00482 }
00483 };