#include "http.h" #include #include #include #include HTTPRequest::HTTPRequest(std::istream& is) { std::string firstline, query_str; std::getline(is, firstline); std::vector splitvec; boost::algorithm::split(splitvec, firstline, boost::algorithm::is_space()); type = splitvec[0]; path = splitvec[1]; httpver = splitvec[2]; if(path.find("?") != std::string::npos) { boost::algorithm::split(splitvec, path, boost::is_any_of("?")); path = splitvec[0]; query_str = splitvec[1]; boost::algorithm::split(splitvec, query_str, boost::is_any_of("&")); for(std::vector::iterator it = splitvec.begin(); it != splitvec.end(); it++) { std::vector sv; boost::algorithm::split(sv, *it, boost::is_any_of("=")); std::string key = sv[0]; std::string value = sv[1]; url_decode(key); url_decode(value); query[key] = value; std::cout << boost::format("%s: %s") % key % value << std::endl; } } url_decode(path); std::cout << boost::format("%s %s %s\n") % type % path % httpver; while(is.good()) { std::string line; std::getline(is, line); boost::trim(line); if(!line.size()) continue; std::vector v; boost::algorithm::split_regex(v, line, boost::regex(": ")); headers[v[0]] = v[1]; } } void HTTPRequest::url_decode(std::string& str) { std::string::const_iterator start, end, prev; start = str.begin(); end = str.end(); boost::match_results what; boost::match_flag_type flags = boost::match_default; boost::regex re("%([0-9a-fA-F]{2})"); prev = start; std::string out; while(boost::regex_search(start, end, what, re, flags)) { std::istringstream hs(what[1]); char c; int hi; hs >> std::hex >> hi; c = hi; out += std::string(prev, what[1].first - 1) + c; start = what[1].second; prev = start; } out += std::string(prev, end); str = out; } HTTPResponse::HTTPResponse(boost::asio::ip::tcp::socket& socket_) : socket(socket_){ httpver = "1.1"; headers_written = false; } void HTTPResponse::add_header(std::string key, std::string value) { headers[key] = value; } void HTTPResponse::write_headers() { write(boost::str(boost::format("HTTP/%s %d %s\r\n") % httpver % code % status)); for(HTTPHeaders::iterator it = headers.begin(); it != headers.end(); it++) { write(boost::str(boost::format("%s: %s\r\n") % it->first % it->second)); } write("\r\n"); } void HTTPResponse::write(char *data, unsigned int len) { write(std::string(data, len)); } void HTTPResponse::write(std::string str) { if(!headers_written) { // make sure to set headers_written before calling write_headers headers_written = true; write_headers(); } boost::asio::streambuf b; std::ostream os(&b); os << str; boost::asio::write(socket, b); }