| 107 | } |
| 108 | |
| 109 | bool http_server_request::handle_buffer(std::string &buffer) |
| 110 | { |
| 111 | bool state_changed = false; |
| 112 | do { |
| 113 | state_changed = false; |
| 114 | switch (state) { |
| 115 | case HTTPS_HEADERS: |
| 116 | if (buffer.length() > get_max_header_size()) { |
| 117 | owner->log(ll_warning, "HTTTP request exceeds max header size, dropped"); |
| 118 | return false; |
| 119 | } else if (buffer.find("\r\n\r\n") != std::string::npos) { |
| 120 | |
| 121 | /* Add 10 seconds to retrieve body */ |
| 122 | timeout += 10; |
| 123 | |
| 124 | /* Got all headers, proceed to new state */ |
| 125 | |
| 126 | /* Get headers string */ |
| 127 | std::string headers = buffer.substr(0, buffer.find("\r\n\r\n")); |
| 128 | |
| 129 | /* Modify buffer, remove headers section */ |
| 130 | buffer.erase(0, buffer.find("\r\n\r\n") + 4); |
| 131 | |
| 132 | /* Process headers into map */ |
| 133 | std::vector<std::string> h = utility::tokenize(headers); |
| 134 | |
| 135 | if (h.empty()) { |
| 136 | generate_error(400, "Malformed request"); |
| 137 | return true; |
| 138 | } |
| 139 | |
| 140 | /* First line is special */ |
| 141 | std::vector<std::string> verb_path_protocol = utility::tokenize(h[0], " "); |
| 142 | if (verb_path_protocol.size() < 3) { |
| 143 | generate_error(400, "Malformed request"); |
| 144 | return true; |
| 145 | } |
| 146 | std::string req_verb = uppercase(verb_path_protocol[0]); |
| 147 | request_type = req_verb; |
| 148 | std::string req_path = verb_path_protocol[1]; |
| 149 | path = req_path; |
| 150 | std::string protocol = uppercase(verb_path_protocol[2]); |
| 151 | |
| 152 | h.erase(h.begin()); |
| 153 | |
| 154 | if (protocol.substr(0, 5) != "HTTP/") { |
| 155 | generate_error(400, "Malformed request"); |
| 156 | return true; |
| 157 | } |
| 158 | |
| 159 | if (std::find(verb.begin(), verb.end(), req_verb) == verb.end()) { |
| 160 | generate_error(401, "Unsupported method"); |
| 161 | return true; |
| 162 | } |
| 163 | |
| 164 | for(auto &hd : h) { |
| 165 | std::string::size_type sep = hd.find(": "); |
| 166 | if (sep != std::string::npos) { |
nothing calls this directly
no test coverage detected