diff --git a/lib/w.pro b/lib/w.pro index 356b72fb..3a6ec1df 100644 --- a/lib/w.pro +++ b/lib/w.pro @@ -40,7 +40,7 @@ HEADERS += \ ../src/net/wrtm.h \ ../src/net/wrtmentry.h \ ../src/net/wscan.h \ - ../src/net/wwritable.h + ../src/net/wwritable.h SOURCES += \ ../src/base/gtrace.cpp \ diff --git a/src/proxy/http.h b/src/proxy/http.h new file mode 100644 index 00000000..12a59390 --- /dev/null +++ b/src/proxy/http.h @@ -0,0 +1,10 @@ +#pragma once + +typedef enum {GET, PUT, HEAD, POST, NOT_IMPLEMENTED} Method; +//we can add more +typedef enum {HTTP1_0, HTTP1_1, HTTP_UNSUPPORTED} Protocol; +//we can add more + +#define CR '\r' +#define LF '\n' +#define CRLF "\r\n" \ No newline at end of file diff --git a/src/proxy/httprequest.cpp b/src/proxy/httprequest.cpp new file mode 100644 index 00000000..b2173bc4 --- /dev/null +++ b/src/proxy/httprequest.cpp @@ -0,0 +1,256 @@ +#include "httprequest.h" + +HTTPRequest::HTTPRequest() +{ + body = ""; + request_packet = ""; +} + +HTTPRequest::~HTTPRequest() +{ +} + +void HTTPRequest::printRequest(void ) +{ + cout << " ===Request Begin===" << endl; + cout << request_packet << endl; + cout << " ====Request End====" << endl; +} + +void HTTPRequest::addRequestPacket(char* buf, int& len) +{ + request_packet.append(buf, len); +} + +void HTTPRequest::addRequestBody(string& str) +{ + body += str; +} + +//set, get func begin + +int HTTPRequest::setMethod(Method arg_method) +{ + method = arg_method; + return 0; +} + +Method HTTPRequest::getMethod() +{ + return method; +} + +int HTTPRequest::setURL(string arg_url) +{ + url = arg_url; + return 0; +} + +string HTTPRequest::getURL() +{ + return url; +} + +int HTTPRequest::setProtocol(Protocol arg_protocol) +{ + protocol = arg_protocol; + return 0; +} + +Protocol HTTPRequest::getProtocol() +{ + return protocol; +} + +int HTTPRequest::setUserAgent(string arg_useragent) +{ + useragent = arg_useragent; + return 0; +} + +string HTTPRequest::getUserAgent() +{ + return useragent; +} + +int HTTPRequest::setHTTPHeader(string name, string content) +{ + headers.push_back(make_pair(name, content)); + return 0; +} + +string HTTPRequest::getHTTPHeader(string name) +{ + vector>::iterator iter; + for(iter = headers.begin(); iter != headers.end(); iter++) + { + if((*iter).first == name) + { + return (*iter).first + ":" + (*iter).second; + } + } + return "There is no header name " + name; +} + +int HTTPRequest::setHTTPHeaderVector(vector>* header_vector) +{ + vector>::iterator iter; + for(iter = header_vector->begin(); iter != header_vector->end(); iter++) + { + setHTTPHeader((*iter).first, (*iter).second); + } + return 0; +} + +vector>* HTTPRequest::getHTTPHeaderVector() +{ + return &headers; +} + +int HTTPRequest::setRequestBody(string& arg_body) +{ + body = arg_body; + return 0; +} + +string* HTTPRequest::getRequestBody() +{ + return &body; +} + +//set, get func end + +int HTTPRequest::parseRequestPacket() +{ + size_t cursor_begin = 0, cursor_end = 0; + size_t header_cursor_begin, header_cursor_end; + string http_method, http_protocol, header; + string name, content; + + //http method + http_method = updateCursor(cursor_begin, cursor_end, " ", request_packet, 1); + if(http_method == "GET") + { + method = GET; + } + else if(http_method == "PUT") + { + method = PUT; + } + else if(http_method == "POST") + { + method = POST; + } + else + { + method = NOT_IMPLEMENTED; + return 0; + } + + //url + url = updateCursor(cursor_begin, cursor_end, " ", request_packet, 1); + + //protocol + http_protocol = updateCursor(cursor_begin, cursor_end, CRLF, request_packet, 1); + if(http_protocol == "HTTP/1.0") + { + protocol = HTTP1_0; + } + else if(http_protocol == "HTTP/1.1") + { + protocol = HTTP1_1; + } + else + { + protocol = HTTP_UNSUPPORTED; + return 0; + } + + cursor_begin++; //CRLF + + //header parse start here + while(1) + { + header = updateCursor(cursor_begin, cursor_end, CRLF, request_packet, 1); + //separate header line by line + + header_cursor_begin = 0; + header_cursor_end = 0; + + //name: content + name = updateCursor(header_cursor_begin, header_cursor_end, ":", header, 2); + content = updateCursor(header_cursor_begin, header_cursor_end, CRLF, header, 0); + + setHTTPHeader(name, content); + cursor_begin++; //CRLF + if(request_packet.substr(cursor_begin, 2) == CRLF) //one more CRLF + { + break; + } + } + + cursor_begin+=2; + body = request_packet.substr(cursor_begin); + + return 0; +} + +int HTTPRequest::makeRequest() +{ + string http_method, http_protocol; + + switch(method){ + case GET: + http_method = "GET"; + break; + case PUT: + http_method = "PUT"; + break; + case POST: + http_method = "POST"; + break; + default: + return -1; + break; + } + + switch(protocol){ + case HTTP1_0: + http_protocol = "HTTP/1.0"; + break; + case HTTP1_1: + http_protocol = "HTTP/1.1"; + break; + default: + return -1; + break; + } + + request_packet += http_method + " " + url + " " + http_protocol + CRLF; + vector>::iterator iter; + for(iter = headers.begin(); iter != headers.end(); iter++){ + request_packet += (*iter).first + ": " + (*iter).second + CRLF; + } + request_packet += CRLF; + request_packet += body; + return 0; +} + +size_t HTTPRequest::getRequestSize() +{ + return request_packet.length(); +} + +string* HTTPRequest::getRequestData() +{ + return &request_packet; +} + +string HTTPRequest::updateCursor(size_t& cursor_begin, size_t& cursor_end, string target, string obj, size_t next) +{ + string result; + cursor_end = obj.find_first_of(target, cursor_begin); + result = obj.substr(cursor_begin, cursor_end - cursor_begin); + cursor_begin = cursor_end + next; + return result; +} \ No newline at end of file diff --git a/src/proxy/httprequest.h b/src/proxy/httprequest.h new file mode 100644 index 00000000..4193d138 --- /dev/null +++ b/src/proxy/httprequest.h @@ -0,0 +1,46 @@ +#pragma once + +#include "stdafx.h" +#include "http.h" + +class HTTPRequest +{ + Method method; + string url; + Protocol protocol; + string hostname; + string useragent; + + vector> headers; + string body; + string request_packet; + + public: + HTTPRequest(); + ~HTTPRequest(); + + void printRequest(); + void addRequestPacket(char* buf, int& len); + void addRequestBody(string& str); + + int setMethod(Method arg_method); + Method getMethod(); + int setURL(string arg_url); + string getURL(); + int setProtocol(Protocol arg_protocol); + Protocol getProtocol(); + int setUserAgent(string arg_useragent); + string getUserAgent(); + int setHTTPHeader(string name, string content); + string getHTTPHeader(string name); + int setHTTPHeaderVector(vector>* header_vector); + vector>* getHTTPHeaderVector(); + int setRequestBody(string& arg_body); + string* getRequestBody(); + + int parseRequestPacket(); + int makeRequest(); + size_t getRequestSize(); + string* getRequestData(); + string updateCursor(size_t& cursor_begin, size_t& cursor_end, string target, string obj, size_t next); +}; \ No newline at end of file diff --git a/src/proxy/httpresponse.cpp b/src/proxy/httpresponse.cpp new file mode 100644 index 00000000..392a194e --- /dev/null +++ b/src/proxy/httpresponse.cpp @@ -0,0 +1,244 @@ +#include "httpresponse.h" + +HTTPResponse::HTTPResponse() +{ + body = ""; + response_packet = ""; +} + +HTTPResponse::~HTTPResponse() +{ +} + +void HTTPResponse::printResponse() +{ + cout << " ===Request Begin===" << endl; + cout << response_packet << endl; + cout << " ====Request End====" << endl; +} + +void HTTPResponse::addResponsePacket(char *buf, int& len) +{ + response_packet.append(buf, len); +} + +int HTTPResponse::setProtocol(Protocol arg_protocol) +{ + protocol = arg_protocol; + return 0; +} + +Protocol HTTPResponse::getProtocol() +{ + return protocol; +} + +int HTTPResponse::setStatusCode(size_t arg_status_code) +{ + status_code = arg_status_code; + return 0; +} + +size_t HTTPResponse::getStatusCode() +{ + return status_code; +} + +int HTTPResponse::setReasonPhrase() +{ + switch(status_code) + { + case 200: + reason_phrase = "OK"; + break; + case 201: + reason_phrase = "Created"; + break; + case 400: + reason_phrase = "Bad Request"; + break; + case 403: + reason_phrase = "Forbidden"; + break; + case 404: + reason_phrase = "Not Found"; + break; + case 411: + reason_phrase = "Length Required"; + break; + case 500: + reason_phrase = "Internal Server Error"; + break; + case 501: + reason_phrase = "Not Implemented"; + break; + case 502: + reason_phrase = "Bad Gateway"; + break; + case 505: + reason_phrase = "HTTP Version Not Supported"; + break; + default: + return -1; + break; + } + + return 0; +} + +string HTTPResponse::getReasonPhrase() +{ + return reason_phrase; +} + +int HTTPResponse::setHTTPHeader(string name, string content) +{ + headers.push_back(make_pair(name, content)); + return 0; +} + +string HTTPResponse::getHTTPHeader(string name) +{ + vector>::iterator iter; + for(iter = headers.begin(); iter != headers.end(); iter++) + { + if((*iter).first == name) + { + return (*iter).second; + } + } + return "There is no header name " + name; +} + +int HTTPResponse::setHTTPHeaderVector(vector>* header_vector) +{ + vector>::iterator iter; + for(iter = header_vector->begin(); iter!=header_vector->end(); iter++) + { + setHTTPHeader((*iter).first, (*iter).second); + } + return 0; +} + +vector>* HTTPResponse::getHTTPHeaderVector() +{ + return &headers; +} + +int HTTPResponse::setResponseBody(string& arg_body) +{ + body = arg_body; + return 0; +} + +string* HTTPResponse::getResponseBody() +{ + return &body; +} + +int HTTPResponse::makeResponse() +{ + string http_protocol; + string tmp_packet; + + switch(protocol){ + case HTTP1_0: + http_protocol = "HTTP/1.0"; + break; + case HTTP1_1: + http_protocol = "HTTP/1.1"; + break; + default: + return -1; + break; + } + + tmp_packet += http_protocol + " " + to_string(status_code) + " " + reason_phrase + CRLF; + + vector>::iterator iter; + for(iter = headers.begin(); iter != headers.end(); iter++) + { + tmp_packet += (*iter).first + ": " + (*iter).second + CRLF; + } + tmp_packet += CRLF + body; + response_packet = tmp_packet; + return 0; +} + +int HTTPResponse::parseResponsePacket() +{ + size_t cursor_begin = 0, cursor_end = 0; + size_t header_cursor_begin, header_cursor_end; + string http_protocol, http_status_code, header; + string name, content; + + //protocol + http_protocol = updateCursor(cursor_begin, cursor_end, " ", response_packet, 1); + if(http_protocol == "HTTP/1.0") + { + protocol = HTTP1_0; + } + else if(http_protocol == "HTTP/1.1") + { + protocol = HTTP1_1; + } + else + { + protocol = HTTP_UNSUPPORTED; + return 0; + } + + //status code + http_status_code = updateCursor(cursor_begin, cursor_end, " ", response_packet, 1); + status_code = atoi(http_status_code.c_str()); + + //reason phrase + reason_phrase = updateCursor(cursor_begin, cursor_end, CRLF, response_packet, 1); + + cursor_begin++; //CRLF + + //header parse start here + while(1) + { + header = updateCursor(cursor_begin, cursor_end, CRLF, response_packet, 1); + //separate header line by line + + header_cursor_begin = 0; + header_cursor_end = 0; + + //name: content + name = updateCursor(header_cursor_begin, header_cursor_end, ":", header, 2); + content = updateCursor(header_cursor_begin, header_cursor_end, CRLF, header, 0); + + setHTTPHeader(name, content); + cursor_begin++; //CRLF + if(response_packet.substr(cursor_begin, 2) == CRLF) //one more CRLF + { + break; + } + } + + cursor_begin+=2; + body = response_packet.substr(cursor_begin); + + return 0; +} + +size_t HTTPResponse::getResponseSize(void ) +{ + return response_packet.length(); +} + +string* HTTPResponse::getResponseData() +{ + return &response_packet; +} + +string HTTPResponse::updateCursor(size_t& cursor_begin, size_t& cursor_end, string target, string obj, size_t next) +{ + string result; + cursor_end = obj.find_first_of(target, cursor_begin); + result = obj.substr(cursor_begin, cursor_end - cursor_begin); + cursor_begin = cursor_end + next; + return result; +} \ No newline at end of file diff --git a/src/proxy/httpresponse.h b/src/proxy/httpresponse.h new file mode 100644 index 00000000..9c02bcb2 --- /dev/null +++ b/src/proxy/httpresponse.h @@ -0,0 +1,40 @@ +#pragma once + +#include "stdafx.h" +#include "http.h" + +class HTTPResponse +{ + Protocol protocol; + size_t status_code; + string reason_phrase; + vector> headers; + string body; + string response_packet; + + public: + HTTPResponse(); + ~HTTPResponse(); + + void printResponse(); + void addResponsePacket(char* buf, int& len); + + int setProtocol(Protocol arg_protocol); + Protocol getProtocol(); + int setStatusCode(size_t arg_status_code); + size_t getStatusCode(); + int setReasonPhrase(); + string getReasonPhrase(); + int setHTTPHeader(string name, string content); + string getHTTPHeader(string name); + int setHTTPHeaderVector(vector>* header_vector); + vector>* getHTTPHeaderVector(); + int setResponseBody(string& arg_body); + string* getResponseBody(); + + int makeResponse(); + int parseResponsePacket(); + size_t getResponseSize(); + string* getResponseData(); + string updateCursor(size_t& cursor_begin, size_t& cursor_end, string target, string obj, size_t next); +}; \ No newline at end of file