2017-04-06 22:35:06 +00:00
|
|
|
/* Copyright 2017, Michele Santullo
|
|
|
|
* This file is part of "tawashi".
|
|
|
|
*
|
|
|
|
* "tawashi" is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* "tawashi" is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with "tawashi". If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2017-04-06 19:12:44 +00:00
|
|
|
#include "cgi_post.hpp"
|
|
|
|
#include "cgi_env.hpp"
|
|
|
|
#include "split_get_vars.hpp"
|
2017-04-25 21:07:02 +00:00
|
|
|
#include "escapist.hpp"
|
2017-04-26 19:11:18 +00:00
|
|
|
#include "sanitized_utf8.hpp"
|
2017-04-06 19:12:44 +00:00
|
|
|
#include <iostream>
|
|
|
|
#include <iterator>
|
|
|
|
#include <algorithm>
|
|
|
|
#include <string>
|
|
|
|
#include <cassert>
|
|
|
|
#include <ciso646>
|
|
|
|
|
|
|
|
namespace tawashi {
|
2017-06-02 08:23:35 +00:00
|
|
|
UnsupportedContentTypeException::UnsupportedContentTypeException (const boost::string_ref& parMessage) :
|
|
|
|
TawashiException(ErrorReasons::UnsupportedContentType, parMessage)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-04-06 19:12:44 +00:00
|
|
|
namespace cgi {
|
|
|
|
namespace {
|
2017-06-02 08:23:35 +00:00
|
|
|
bool valid_content_type (const Env& parEnv) {
|
|
|
|
if (parEnv.content_type_split().type != "application" or
|
|
|
|
parEnv.content_type_split().subtype !=
|
|
|
|
"x-www-form-urlencoded") {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string read_n (std::istream& parSrc, std::size_t parSize) {
|
|
|
|
if (0 == parSize)
|
|
|
|
return std::string();
|
|
|
|
|
|
|
|
std::string original_data;
|
|
|
|
original_data.reserve(parSize);
|
|
|
|
std::copy_n(
|
|
|
|
std::istream_iterator<char>(parSrc),
|
|
|
|
parSize,
|
|
|
|
std::back_inserter(original_data)
|
|
|
|
);
|
|
|
|
return sanitized_utf8(original_data);
|
|
|
|
}
|
2017-04-06 19:12:44 +00:00
|
|
|
} //unnamed namespace
|
|
|
|
|
2017-05-10 19:42:42 +00:00
|
|
|
const PostMapType& read_post (std::istream& parSrc, const Env& parEnv) {
|
2017-06-02 08:23:35 +00:00
|
|
|
return read_post(parSrc, parEnv, parEnv.content_length());
|
|
|
|
}
|
|
|
|
|
|
|
|
const PostMapType& read_post (std::istream& parSrc, const Env& parEnv, std::size_t parMaxLen) {
|
2017-04-06 19:12:44 +00:00
|
|
|
static bool already_read = false;
|
|
|
|
static PostMapType map;
|
|
|
|
static std::string original_data;
|
|
|
|
|
|
|
|
if (not already_read) {
|
|
|
|
assert(original_data.empty());
|
|
|
|
assert(map.empty());
|
|
|
|
|
2017-06-02 08:23:35 +00:00
|
|
|
if (not valid_content_type(parEnv)) {
|
|
|
|
throw UnsupportedContentTypeException(parEnv.content_type());
|
|
|
|
}
|
2017-04-06 19:12:44 +00:00
|
|
|
|
2017-06-02 08:23:35 +00:00
|
|
|
const auto input_len = std::min(parMaxLen, parEnv.content_length());
|
|
|
|
original_data = read_n(parSrc, input_len);
|
|
|
|
Escapist houdini;
|
|
|
|
for (auto& itm : split_env_vars(original_data)) {
|
|
|
|
std::string key(houdini.unescape_url(itm.first));
|
|
|
|
std::string val(houdini.unescape_url(itm.second));
|
|
|
|
map[std::move(key)] = std::move(val);
|
2017-04-06 19:12:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
already_read = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return map;
|
|
|
|
}
|
|
|
|
} //namespace cgi
|
|
|
|
} //namespace tawashi
|