#include "Client.hpp" const std::vector &Client::get_rq_multi_bodys() const { return _request.multi_bodys; } const std::string Client::get_rq_multi_bodys_headers(const std::string & key, std::vector::const_iterator body_it) const { std::map::const_iterator it; it = body_it->headers.find(::str_tolower(key)); if (it == body_it->headers.end()) return ""; // IF return reference compiler "warning: returning reference to local temporary" return it->second; } void Client::_parse_multipart_body(size_t pos) { /* ** Parsing roughly like described in : ** https://www.rfc-editor.org/rfc/rfc2046#section-5.1.1 */ MultipartBody new_body; std::string boundary; size_t start_pos; size_t end_pos; std::string tmp; size_t tmp_pos; size_t ret; // Get boundary boundary = get_rq_headers("Content-Type"); start_pos = boundary.find("boundary="); if (start_pos == NPOS) { status = 400; std::cerr << "_parse_multipart_body() error 1\n"; return; } start_pos += sizeof("boundary=")-1; boundary = boundary.substr(start_pos); std::cerr << "boundary =|" << boundary << "|\n"; // Search boundary start_pos = raw_request.find("--" + boundary, pos); if (start_pos == NPOS || start_pos + sizeof("--")-1 + boundary.size() > raw_request.size()) { status = 400; std::cerr << "_parse_multipart_body() error 2\n"; return; } start_pos += sizeof("--")-1 + boundary.size() + CRLF_SIZE; while (1) // TODO : test loop for multi body { end_pos = raw_request.find("--" + boundary, start_pos); if (end_pos == NPOS) { status = 400; std::cerr << "_parse_multipart_body() error 3\n"; return; } /* // Maye useful for multi body (remove "start_pos - CRLF_SIZE" if used) end_pos = raw_request.rfind(CRLF, end_pos); if (end_pos == NPOS) {status = 400; return; } */ new_body.body = raw_request.substr(start_pos, end_pos - start_pos - CRLF_SIZE); // Split headers from body tmp_pos = new_body.body.find(CRLF CRLF); if (tmp_pos != NPOS) { ret = ::parse_http_headers(new_body.body.substr(0, tmp_pos), new_body.headers); ::str_map_key_tolower(new_body.headers); if (ret) { status = 400; std::cerr << "_parse_multipart_body() error 4\n"; return; } tmp_pos += CRLF_SIZE*2; new_body.body.erase(0, tmp_pos); // ::print_map(new_body.headers); } else { // No headers case tmp_pos = new_body.body.find(CRLF); if (tmp_pos != 0) { status = 400; std::cerr << "_parse_multipart_body() error 5\n"; return; } } _request.multi_bodys.push_back(new_body); // Move start for next loop start_pos = end_pos + sizeof("--")-1 + boundary.size(); if ( start_pos + 2 + CRLF_SIZE == raw_request.size() && raw_request[start_pos] == '-' && raw_request[start_pos+1] == '-') break; /* ::print_special(raw_request); std::cerr << "start_pos = " << start_pos << "\n"; std::cerr << "raw_request.size() = " << raw_request.size() << "\n"; std::cerr << raw_request.substr(start_pos); */ } }