Autor
|
Tema: Mi clase HTTP + winsock peticion HTTP ejemplo (Leído 2,996 veces)
|
patilanz
Desconectado
Mensajes: 481
555-555-0199@example.com
|
Hola acabo de hacer una clase para organizar mas o menos el header de una peticion HTTP. Como esto: HTTP/1.1 200 OK\r\n Date: Mon, 23 May 2005 22:38:34 GMT\r\n Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)\r\n Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT\r\n ETag: "3f80f-1b6-3e1cb03b"\r\n Content-Type: text/html; charset=UTF-8\r\n Content-Length: 131\r\n Connection: close\r\n \r\n HTTP_class.hpp #ifndef HTTP_CLASS_HPP #define HTTP_CLASS_HPP #include <string> #include <ctime> #include <vector> using namespace std; //CLASS STATE #define SETUP_OK 1 #define SETUP_NEED 2 #define INVALID_HEADER 3 //HTTP CODES //Informational #define H_Continue 100 #define H_Switching_Protocols 101 #define H_Processing 102 //Success #define H_OK 200 #define H_Created 201 #define H_Accepted 202 #define H_Non_Authoritative_Information 203 #define H_No_Content 204 #define H_Reset_Content 205 #define H_Partial_Content 206 #define H_Multi_Status 207 #define H_Already_Reported 208 #define H_IM_Used 226 //Redirection #define H_Multiple_Choices 300 #define H_Moved_Permanently 301 #define H_Found 302 #define H_See_Other 303 #define H_Not_Modified 304 #define H_Use_Proxy 305 #define H_Switch_Proxy 306 #define H_Temporary_Redirect 307 #define H_Permanent_Redirect 308 //Client Error #define H_Bad_Request 400 #define H_Unauthorized 401 #define H_Payment_Required 402 #define H_Forbidden 403 #define H_Not_Found 404 #define H_Method_Not_Allowed 405 #define H_Not_Acceptable 406 #define H_Proxy_Authentication_Required 407 #define H_Request_Timeout 408 #define H_Conflict 409 #define H_Gone 410 #define H_Length_Required 411 #define H_Precondition_Failed 412 #define H_Request_Entity_Too_Large 413 #define H_Request_URI_Too_Long 414 #define H_Unsupported_Media_Type 415 #define H_Requested_Range_Not_Satisfiable 416 #define H_Expectation_Failed 417 #define H_Im_a_teapot 418 #define H_Authentication_Timeout 419 #define H_Method_Failure 420 #define Enhance_Your_Calm 420 #define H_UnprocessableEntity 422 #define H_Locked 423 #define H_Failed_Dependency 424 #define H_Upgrade_Required 426 #define H_Precondition_Required 428 #define H_Too_Many_Requests 429 #define H_Request_Header_Fields_Too_Large 431 #define H_Login_Timeout 440 #define H_No_Response 444 #define H_Retry_With 449 #define H_Blocked_by_Windows_Parental_Controls 450 #define H_Unavailable_For_Legal_Reasons 451 #define H_Redirect 494 #define H_Request_Header_Too_Large 495 #define H_Cert_Error 496 #define H_No_Cert 497 #define H_HTTP_to_HTTPS 498 #define H_Token_expired_invalid 499 #define H_Client_Closed_Request 499 #define H_Token_required 499 //class ContentType{ //public: // string type; // string charset; //}; class HTTP{ public: HTTP(); HTTP(string header); bool setup(string header); int Code();//HTTP status const int State();//class status tm Date(); string Server(); tm Last_Modified(); string ETag(); string Content_Type(); int Content_Lenght(); string Connection(); string Other(string name); vector<string> Other(int i); //helpful functions double HTTPVersion(); int Size();//Size of fields private: int state;//Already setup? int code; tm date; string server; tm last_modified; string etag; string content_type; int content_length; string header; string connection; vector < vector<string> > all; //all fields //helpful data double version; //Config functions tm getDate(string date); void defaultConfig(); }; vector<string> split(string full, string part); //helpful function #endif
HTTP_class.cpp #include "http_class.hpp" #include <regex> HTTP::HTTP(){ defaultConfig(); } HTTP::HTTP(string header){ defaultConfig(); setup(header); } string HTTP::Other(string name){ for (int i = 0; i < all.size(); i++){ if (all[i][0] == name){ return all[i][1]; } } return ""; } vector<string> HTTP::Other(int i){ if (i < all.size()) return all[i]; else return vector<string>(); } bool HTTP::setup(string header){ vector<string> parts = split(header, "\r\n"); //all setup for (int i = 1; i < parts.size(); i++){ all.push_back(split(parts[i],": " )); } all.pop_back(); // remove last 2 \r\n of the end of http protocol all.pop_back(); // //end if (all.size() < 1){ //Nothing founded state = INVALID_HEADER; return false; } //http setup string v = parts[0].substr(5, 3); version = atof(v.c_str()); code = atoi(parts[0].substr(8, 4).c_str()); //end date = getDate(Other("Date")); server = Other("Server"); last_modified = getDate(Other("Last-Modified")); etag = Other("ETag"); content_type = Other("Content-Type");//Mejores en 2.0 content_length = atoi(Other("Content-Length").c_str()); connection = Other("Connection"); state = SETUP_OK; return true; } int HTTP::Code(){ return code; } const int HTTP::State(){ return state; } tm HTTP::Date(){ //Example of check if (date.tm_year != 0 && state == SETUP_OK){ // if == 0 no date in header return date; } } string HTTP::Server(){ return server; } tm HTTP::Last_Modified(){ return last_modified; } string HTTP::ETag(){ return etag; } string HTTP::Content_Type(){ return content_type; } int HTTP::Content_Lenght(){ return content_length; } string HTTP::Connection(){ return connection; } //Helpful functions double HTTP::HTTPVersion(){ return version; } int HTTP::Size(){ return all.size(); } tm HTTP::getDate(string _date){ //Get date in tm format for example in Date or Last-Modified tm date = tm(); if (_date.size() > 0){ const static string months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; smatch match; if (_date.find("GMT") != -1){ // New format if (regex_search(_date, match, regex("^\\w{3,9},\\s(\\d{2})[\\s\\-](\\w{3})[\\s\\-](\\d{2,4})\\s(\\d{2}):(\\d{2}):(\\d{2}) GMT$"))){ date.tm_mday = atoi(match[1].str().c_str()); int month; for (int i = 0; i < sizeof(months); i++){ if (months[i] == match[2].str()){ month = i; break; } } date.tm_mon = month; int year = atoi(match[3].str().c_str()); if (year > 1900) year -= 1900; date.tm_year = year; date.tm_hour = atoi(match[4].str().c_str()); date.tm_min = atoi(match[5].str().c_str()); date.tm_sec = atoi(match[6].str().c_str()); } } else{ //Old ANSI format if (regex_search(_date, match, regex("^\\w{3} (\\w{3}) (\\d{1,2}) (\\d{2}):(\\d{2}):(\\d{2}) (\\d{4})$"))){ int month; for (int i = 0; i < sizeof(months); i++){ if (months[i] == match[1].str()){ month = i; break; } } date.tm_mday = atoi(match[2].str().c_str()); date.tm_hour = atoi(match[3].str().c_str()); date.tm_min = atoi(match[4].str().c_str()); date.tm_sec = atoi(match[5].str().c_str()); date.tm_year = atoi(match[6].str().c_str()); } } } return date; } void HTTP::defaultConfig(){ //Set some values help to don't check state in every function state = SETUP_NEED; code = 0; version = 0; content_length = 0; } //split string in vector vector<string> split(string full, string part){ vector<string> parts; int last = 0; int p; while ((p = full.find(part, last)) != -1){ parts.push_back(full.substr(last, p - last)); last = p + part.size(); } parts.push_back(full.substr(last, full.size())); return parts; }
Ejemplo conexión http con win sockets #include <iostream> #include <string> #include <vector> #include <WinSock2.h> #include "http_class.hpp" #pragma comment(lib,"ws2_32.lib") using namespace std; #define SIZE 1024 int main(){ WSADATA wsadata; WSAStartup(MAKEWORD(2, 2), &wsadata); char buffer[SIZE]; vector<vector<string>>links = { //Random urls { "foro.elhacker.net", "/throw 403 error" }, { "foro.elhacker.net", "/throw_302_error" }, { "www.google.es", "/" }, { "foro.elhacker.net", "/ingenieria_inversa-b26.0/" } }; hostent * host; in_addr ip; sockaddr_in data; string request; for (int i = 0; i < links.size(); i++){ host = gethostbyname(links[i][0].c_str()); ip.s_addr = *(long * )host->h_addr_list[0]; SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == INVALID_SOCKET){ cout << "Invalid socket"; return 1; } memset(&data, 0, sizeof(sockaddr_in)); data.sin_addr = ip; data.sin_family = AF_INET; data.sin_port = htons(80); if(connect(sock, (sockaddr*)&data, sizeof(sockaddr_in))){ cout << "Connection with " << inet_ntoa(ip) << " failed."; return 1; } request = "GET " + links[i][1] + " HTTP/1.0\r\n"; request += "Host: " + links[i][0] + "\r\n"; request += "\r\n"; if (send(sock, request.c_str(), request.size(), 0) != request.size()){ cout << "Send error"; return 1; } //Accept char buffer[SIZE]; int lastBytes = SIZE - 1;//bytes recerved string response; while (lastBytes > 0){ lastBytes = recv(sock, buffer, sizeof(buffer), 0); if (lastBytes > 0) response += string(buffer).substr(0, lastBytes); } string header = response.substr(0, response.find("\r\n\r\n") + 4); HTTP http(header); // or //http.setup(header); cout << "Host: " << links[i][0] << endl; cout << "HTTP version: " << http.HTTPVersion() << endl; if (http.Code() == H_Not_Found){ cout << "Path: " << links[i][1] << " wasn't founded"; } else if (http.Code() == H_Forbidden){ cout << "Server Forbidden message"; if (http.Other("Location").size() > 0){//Location field cout << " to " << http.Other("Location"); } } else{ cout << "Status code: " << http.Code(); } cout << "\n\nAll fields: \n"; for (int i = 0; i < http.Size(); i++){ cout << http.Other(i)[0] << ": " << http.Other(i)[1] << endl; } cout << endl << endl; } fflush(stdin); getchar(); return 0; }
Descargar ejemplo: http://pruebasdephp.hol.es/things/HTTP_class.rarProbado en visual studio 2013 Si me pueden dar ideas de que puedo mejorar o si tienen alguna duda Saludos
|
|
« Última modificación: 26 Diciembre 2014, 18:11 pm por patilanz »
|
En línea
|
|
|
|
ivancea96
Desconectado
Mensajes: 3.412
ASMático
|
Ahora haz para que todo el proceso de winsock lo lleve la clase (u otra clase/función aparte) En vez de define, tal vez te interesa más hacer un enum
|
|
|
En línea
|
|
|
|
patilanz
Desconectado
Mensajes: 481
555-555-0199@example.com
|
Hola gracias por tu respuesta. Ya creo que tengo lo que me dijiste. http_class.cpp //HTTP_class v2.0 //Autor: patilanz #ifndef HTTP_CLASS_HPP #define HTTP_CLASS_HPP #include <string> #include <ctime> #include <vector> #include "http_config.hpp" using namespace std; //CLASS STATE enum class_state{ SETUP_OK, SETUP_NEED, INVALID_HEADER, INVALID_URL, SOCK_ERROR, CONNECTION_TIME_OUT, CONNECTION_REFUSED, UNKNOW_ERROR, SEND_ERROR, INVALID_RESPONSE }; //HTTP CODES //Informational #define H_Continue 100 #define H_Switching_Protocols 101 #define H_Processing 102 //... no lo pongo para no ocupar espacio en el foro. Es como antes class HTTP{ public: HTTP(); HTTP(string url, string request = "", int port = 80); HTTP(string url, HTTP_config config, int port = 80); bool get(string url, string request = "", int port = 80); bool get(string url, HTTP_config config, int port = 80); bool get(string request = "", int port = 80); bool setHeader(string header); void setContent(string content); bool setUrl(string url); const int State();//class status string Header(); string Content(); int Code();//HTTP status tm Date(); string Server(); tm Last_Modified(); string ETag(); string Content_Type(); int Content_Lenght(); string Connection(); string getHost(); string getPath(); string getUrl(); string Other(string name); vector<string> Other(int i); //helpful functions double HTTPVersion(); int Size();//Size of fields private: int state;//Already setup? int code; tm date; string server; tm last_modified; string etag; string content_type; int content_length; string connection; double version; string host; string path; string url; string header; string content; vector < vector<string> > all; //all fields const int recv_size = 1024; //helpful functions void WSAStart(); vector<string> split(string full, string part); //Config functions tm getDate(string date); void defaultConfig(); }; #endif
http_class.cpp #include "http_class.hpp" #include <regex> #include <WinSock2.h> HTTP::HTTP(){ defaultConfig(); } HTTP::HTTP(string url, string request, int port){ defaultConfig(); get(url, request, port); } HTTP::HTTP(string url, HTTP_config config, int port){ get(url, config, port); } string HTTP::Other(string name){ for (int i = 0; i < all.size(); i++){ if (all[i][0] == name){ return all[i][1]; } } return ""; } vector<string> HTTP::Other(int i){ if (i < all.size()) return all[i]; else return vector<string>(); } bool HTTP::get(string _url, string _request, int port){ smatch match; if (regex_search(_url, match, regex("(http|https)?:?(\\/\\/)?([^/]{5,})([^\\t\\n\\v\\r]*)"))){ url = _url; host = match[3]; path = match[4]; if (path.size() < 1) path = "/"; hostent * _host; in_addr ip; sockaddr_in data; string request; _host = gethostbyname(host.c_str()); ip.s_addr = *(long*)_host->h_addr_list[0]; SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == INVALID_SOCKET){ state = SOCK_ERROR; return false; } memset(&data, 0, sizeof(sockaddr_in)); data.sin_addr = ip; data.sin_family = AF_INET; data.sin_port = htons(port); if (connect(sock, (sockaddr*)&data, sizeof(sockaddr_in))){ if (WSAGetLastError() == WSAETIMEDOUT){ state = CONNECTION_TIME_OUT; } else if (WSAGetLastError() == WSAECONNREFUSED){ state = CONNECTION_REFUSED; } else{ state = UNKNOW_ERROR; } return false; } if (_request.size() > 0) request = _request; else{ request += "GET " + path + " HTTP/1.1\r\n"; request += "Host: " + host + "\r\n"; request += "Connection: close\r\n"; request += "\r\n"; } if(send(sock, request.c_str(), request.size(), 0) != request.size()){ state = SEND_ERROR; return false; } //Accept char *buffer = new char[recv_size]; // No se me ocurrio otra manera de usar una variable const int de la clase int lastBytes = recv_size - 1; string response; while (lastBytes > 0){ lastBytes = recv(sock, buffer, recv_size, 0); if (lastBytes > 0) response += string(buffer).substr(0, lastBytes); } if (response.find("\r\n\r\n") == -1){ state = INVALID_RESPONSE; return false; } setHeader(response.substr(0, response.find("\r\n\r\n") + 4)); setContent(response.substr(response.find("\r\n\r\n") + 4, response.size())); delete[recv_size] buffer; return true; }else{ state = INVALID_URL; return false; } } bool HTTP::get(string url,HTTP_config config, int port){ setUrl(url); string request = config.getGet() + "\r\n"; for (int i = 0; i < config.size(); i++){ request += config[i][0] + ": " + config[i][1] + "\r\n"; } request += "\r\n"; return get(request, port); } bool HTTP::get(string request, int port){ return get(url, request, port); } bool HTTP::setHeader(string _header){ vector<string> parts = split(_header, "\r\n"); //all setup for (int i = 1; i < parts.size(); i++){ all.push_back(split(parts[i],": " )); } all.pop_back(); // remove last 2 \r\n of the end of http protocol all.pop_back(); // //end if (all.size() < 1){ //Nothing founded state = INVALID_HEADER; return false; } header = _header; //http setup string v = parts[0].substr(5, 3); version = atof(v.c_str()); code = atoi(parts[0].substr(8, 4).c_str()); //end date = getDate(Other("Date")); server = Other("Server"); last_modified = getDate(Other("Last-Modified")); etag = Other("ETag"); content_type = Other("Content-Type");//Mejores en 2.0 content_length = atoi(Other("Content-Length").c_str()); connection = Other("Connection"); state = SETUP_OK; return true; } void HTTP::setContent(string c){ content = c; } bool HTTP::setUrl(string _url){ if (regex_match(_url, regex("(http|https)?:?(\\/\\/)?([^/]{5,})([^\\t\\n\\v\\r]*)"))){ url = _url; return true; } return false; } int HTTP::Code(){ return code; } const int HTTP::State(){ return state; } tm HTTP::Date(){ //Example of check if (date.tm_year != 0 && state == SETUP_OK){ // if == 0 no date in header return date; } } string HTTP::Server(){ return server; } tm HTTP::Last_Modified(){ return last_modified; } string HTTP::ETag(){ return etag; } string HTTP::Content_Type(){ return content_type; } int HTTP::Content_Lenght(){ return content_length; } string HTTP::Connection(){ return connection; } //Gets string HTTP::getHost(){ return host; } string HTTP::getPath(){ return path; } string HTTP::getUrl(){ return url; } string HTTP::Header(){ return header; } string HTTP::Content(){ return content; } //Helpful functions double HTTP::HTTPVersion(){ return version; } int HTTP::Size(){ return all.size(); } tm HTTP::getDate(string _date){ //Get date in tm format for example in Date or Last-Modified tm date = tm(); if (_date.size() > 0){ const static string months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; smatch match; if (_date.find("GMT") != -1){ // New format if (regex_search(_date, match, regex("^\\w{3,9},\\s(\\d{2})[\\s\\-](\\w{3})[\\s\\-](\\d{2,4})\\s(\\d{2}):(\\d{2}):(\\d{2}) GMT$"))){ date.tm_mday = atoi(match[1].str().c_str()); int month; for (int i = 0; i < sizeof(months); i++){ if (months[i] == match[2].str()){ month = i; break; } } date.tm_mon = month; int year = atoi(match[3].str().c_str()); if (year > 1900) year -= 1900; date.tm_year = year; date.tm_hour = atoi(match[4].str().c_str()); date.tm_min = atoi(match[5].str().c_str()); date.tm_sec = atoi(match[6].str().c_str()); } } else{ //Old ANSI format if (regex_search(_date, match, regex("^\\w{3} (\\w{3}) (\\d{1,2}) (\\d{2}):(\\d{2}):(\\d{2}) (\\d{4})$"))){ int month; for (int i = 0; i < sizeof(months); i++){ if (months[i] == match[1].str()){ month = i; break; } } date.tm_mday = atoi(match[2].str().c_str()); date.tm_hour = atoi(match[3].str().c_str()); date.tm_min = atoi(match[4].str().c_str()); date.tm_sec = atoi(match[5].str().c_str()); date.tm_year = atoi(match[6].str().c_str()); } } } return date; } void HTTP::defaultConfig(){ //Set some values help to don't check state in every function WSAStart(); state = SETUP_NEED; code = 0; version = 0; content_length = 0; } void HTTP::WSAStart(){ if (socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) == INVALID_SOCKET && WSAGetLastError() == WSANOTINITIALISED){ WSADATA wsadata; WSAStartup(MAKEWORD(2, 2), &wsadata); } } //split string in vector vector<string> HTTP::split(string full, string part){ vector<string> parts; int last = 0; int p; while ((p = full.find(part, last)) != -1){ parts.push_back(full.substr(last, p - last)); last = p + part.size(); } parts.push_back(full.substr(last, full.size())); return parts; }
http_config.hpp #ifndef HTTP_CONFIG_HPP #define HTTP_CONFIG_HPP #include <string> #include <vector> using namespace std; class HTTP_config{ public: HTTP_config(); HTTP_config(string get); HTTP_config(string get, vector < vector <string > >); bool add(string name, string value); bool remove(string name); bool edit(string name, string value); const int size(); void setGet(string); string getGet(); vector<string> operator [](const int); private: vector < vector<string> > data; string get; }; #endif
http_config.cpp #include "http_config.hpp" HTTP_config::HTTP_config(){} HTTP_config::HTTP_config(string _get){ get = _get; } HTTP_config::HTTP_config(string _get, vector < vector<string> > _data){ get = _get; data = _data; } bool HTTP_config::add(string name, string value){ for (int i = 0; i < data.size(); i++){ if (data[i][0] == name) return false; } vector < string > a = { name, value }; data.push_back(a); return true; } bool HTTP_config::remove(string name){ for (int i = 0; i < data.size(); i++){ if (data[i][0] == name){ data.erase(data.begin() + i); return true; } } return false; } bool HTTP_config::edit(string name, string value){ for (int i = 0; i < data.size(); i++){ if (data[i][0] == name){ data[i][1] = value; return true; } } return false; } vector<string> HTTP_config::operator[](const int i){ if (i < data.size()){ return data[i]; } else{ return vector<string>(); } } const int HTTP_config::size(){ return data.size(); } string HTTP_config::getGet(){ return get; }
main.cpp (Ejemplo) #include <iostream> #include <WinSock2.h> #include <string> #include <vector> #include <regex> #include "http_class.hpp" using namespace std; #pragma comment(lib,"ws2_32.lib") int main(){ HTTP http; http.setUrl("http://foro.elhacker.net/programacion_cc/mi_clase_http_winsock_peticion_http_ejemplo-t427014.0.html"); http.get(); cout << http.Code() << endl << endl; HTTP http2("http://www.cplusplus.com/reference/"); cout << http2.getHost() << ": HTTP/" << http2.HTTPVersion() << endl << endl; HTTP_config config("GET / HTTP/1.0", { { "Host", "www.google.es" }, { "Accept-Encoding", "gzip, deflate, sdch" }, { "Accept-Language", "es,en;q=0.8" } }); HTTP http3("www.google.es", config); cout << http3.Header(); getchar(); fflush(stdin); HTTP http4("www.google.es", "", 21); if (http4.State() == CONNECTION_TIME_OUT){ cout << "No answer from " << http4.getHost(); } getchar(); return 0; }
Descarga: http://pruebasdephp.hol.es/things/HTTP_class%20V2.0.rarCambie solo los class state por enums porque los otros eran muchos y no me apetece estar escribiendo uno a uno y mirar todos los números otra vez. Algún fallo o recomendación ? Esta bien hecha?
|
|
|
En línea
|
|
|
|
ivancea96
Desconectado
Mensajes: 3.412
ASMático
|
Sobre el envío, ten en cuenta el envío Chuncked :O
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Como enviar una peticion HTTP desde winsock
Programación Visual Basic
|
illuminat3d
|
1
|
2,591
|
5 Enero 2009, 01:07 am
por Karcrack
|
|
|
Ejemplo hacking metodo put http
Nivel Web
|
delorean
|
2
|
6,807
|
19 Febrero 2011, 19:01 pm
por delorean
|
|
|
Peticion HTTP por proxy
Hacking
|
TomaSs
|
2
|
4,923
|
23 Junio 2011, 07:36 am
por TomaSs
|
|
|
Peticion HTTP desde servidor remoto
Programación General
|
TomaSs
|
0
|
3,100
|
7 Junio 2011, 03:51 am
por TomaSs
|
|
|
Petición HTTP en C++ mediante sockets?
Programación C/C++
|
Puntoinfinito
|
5
|
5,522
|
19 Marzo 2013, 16:45 pm
por 0xDani
|
|