Unexpected DSI Exception with C++ August 24, 2009 01:58PM | Registered: 15 years ago Posts: 161 |
#ifndef _NETWORKREQUEST_H_ #define _NETWORKREQUEST_H_ #include#include "NetworkResponse.h" #include #define NETWORK_BLOCK_SIZE 1000 #define NETWORK_PORT 80 class NetworkRequest { private: s32 _sockfd; std::string _request; std::string _hostName; std::string _path; void Connect(); void Disconnect(); static void Init(); u32 Read(void *buffer, u32 len); void Write(const void *buffer, u32 len); u32 GetResponseLength(); public: NetworkRequest(const std::string &request); ~NetworkRequest(); NetworkResponse GetResponse(); }; #endif
#include "header/NetworkRequest.h" #include#include #include #include #include #include "header/Exception.h" using namespace std; void NetworkRequest::Init() { static bool isInitialized = false; s32 ret; /* if is already initialized, we do nothing */ if(isInitialized) return; /* Initialize network */ static char _hostip[16]; ret = if_config(_hostip, NULL, NULL, true); if (ret < 0) throw new Exception("Can't initialize network!",ret); isInitialized = true; return; } NetworkRequest::NetworkRequest(const string &request) { /* ensure that the network is initialized */ Init(); /* store local variables */ _sockfd = -1; _request = request; _hostName = _request.substr(7,_request.find_first_of('/',7) - 7); _path = request.substr(_hostName.size() + 7,string::npos); } void NetworkRequest::Connect() { struct hostent *he; struct sockaddr_in sa; s32 ret; /* Ensure that the socket is disconnected */ Disconnect(); /* Create socket */ _sockfd = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP); if (_sockfd < 0) throw new Exception("Error creating a socket!",_sockfd); /* Get host by name */ he = net_gethostbyname(_hostName.c_str()); if (!he) throw new Exception("Can't find the host!",-1); /* Setup socket */ memcpy(&sa.sin_addr, he->h_addr_list[0], he->h_length); sa.sin_family = AF_INET; sa.sin_port = htons(80); ret = net_connect(_sockfd, (struct sockaddr *)&sa, sizeof(sa)); if (ret < 0) throw new Exception("Can't connect to the socket!",ret); } void NetworkRequest::Disconnect() { if (_sockfd >= 0) { net_close(_sockfd); _sockfd = -1; } } NetworkRequest::~NetworkRequest() { Disconnect(); } u32 NetworkRequest::Read(void *buffer, u32 len) { u32 read = 0, ret = 0; /* Data to be read */ for (read = 0; read < len; read += ret) { u32 size; /* Size to read */ size = len - read; if (size > NETWORK_BLOCK_SIZE) size = NETWORK_BLOCK_SIZE; /* Read network data */ ret = net_recv(_sockfd, (char*)buffer + read, size, 0); if (ret < 0) throw new Exception("Can't read from the net socket!",ret); /* Read finished */ if (!ret) break; } return read; } void NetworkRequest::Write(const void *buffer, u32 len) { u32 ret = 0, written = 0; /* Data to be written */ for (written = 0; written < len; written += ret) { u32 size; /* Size to read */ size = len - written; if (size > NETWORK_BLOCK_SIZE) size = NETWORK_BLOCK_SIZE; /* Write network data */ ret = net_send(_sockfd, (char*)buffer + written, size, 0); if (ret < 0) throw new Exception("Can't write into the net socket!",ret); /* Write finished */ if (!ret) break; } } u32 NetworkRequest::GetResponseLength() { char buf[1024], *ptr = NULL; u32 len; s32 ret; string totalRequest = "GET " + _path + " HTTP/1.1\r\nHost: " + _hostName + "\r\nConnection: close\r\n\r\n"; /* send request */ ret = net_send(_sockfd, totalRequest.c_str(), totalRequest.length(), 0); if(ret < 0) throw new Exception("Impossible to send the request to the host!",ret); /* Clear buffer */ memset(buf, 0, sizeof(buf)); /* Read HTTP header */ for (u32 cnt = 0; !strstr(buf, "\r\n\r\n"); cnt++) if (net_recv(_sockfd, buf + cnt, 1, 0) <= 0) throw new Exception("Invalid header response!",-1); /* HTTP request OK? */ if (!strstr(buf, "HTTP/1.1 200 OK")) throw new Exception("The response status is not OK!",-1); /* Retrieve content size */ ptr = strstr(buf, "Content-Length:"); if (!ptr) throw new Exception("Can't find the response length!",-1); sscanf(ptr, "Content-Length: %u", &len); return len; } NetworkResponse NetworkRequest::GetResponse() { u32 len; void* buffer = NULL; Connect(); len = GetResponseLength(); /* Allocate response memory */ buffer = malloc(len); if (!buffer) throw Exception("Not enough memory!",-1); /* Download file */ try { Read(buffer, len); } catch(Exception * ex) { free(buffer); throw; } NetworkResponse response(buffer, len); Disconnect(); free(buffer); return response; }
#ifndef _NETWORKRESPONSE_H_ #define _NETWORKRESPONSE_H_ #include#include class NetworkResponse { private: void *_buffer; u64 _size; public: NetworkResponse(void *buffer = NULL, const u64 &size = 0); NetworkResponse(const NetworkResponse &src); NetworkResponse& operator=(const NetworkResponse &src); ~NetworkResponse(); u64 Size() const; void* Content() const; }; #endif
#include "header/NetworkResponse.h" #includeusing namespace std; NetworkResponse::NetworkResponse(void *buffer, const u64 &size) { _size = size; if(buffer != NULL && _size > 0) { _buffer = (void*)new char; memcpy(_buffer,buffer, size); } else _buffer = NULL; } NetworkResponse::NetworkResponse(const NetworkResponse &src) { _size = src.Size(); _buffer = (void*)new char[_size]; memcpy(_buffer,src.Content(), _size); } NetworkResponse& NetworkResponse::operator=(const NetworkResponse &src) { if(_buffer != NULL) { delete[] (char*)_buffer; _buffer = NULL; } _buffer = (void*)new char[src.Size()]; memcpy(_buffer,src.Content(), src.Size()); _size = src.Size(); return *this; } NetworkResponse::~NetworkResponse() { if(_buffer != NULL) { delete[] (char*)_buffer; _buffer = NULL; } } u64 NetworkResponse::Size() const { return _size; } void* NetworkResponse::Content() const { return _buffer; }