spectrum2/3rdparty/cpprestsdk/tests/functional/http/utilities/http_asserts.cpp
2015-11-19 15:19:14 +01:00

336 lines
11 KiB
C++

/***
* ==++==
*
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* ==--==
* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
*
* http_asserts.cpp - Utility class to help verify assertions about http requests and responses.
*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
****/
#include "stdafx.h"
#include "cpprest/details/http_helpers.h"
using namespace web; using namespace utility;
using namespace utility::conversions;
namespace tests { namespace functional { namespace http { namespace utilities {
utility::string_t percent_encode_pound(utility::string_t str)
{
size_t index;
while((index = str.find_first_of(U("#"))) != str.npos)
{
str.insert(index, U("%23"));
str.erase(index + 3, 1);
}
return str;
}
// Helper function to verify all given headers are present.
template <typename T1, typename T2>
static void verify_headers(const T1 &expected, const T2 &actual)
{
for(auto iter = expected.begin(); iter != expected.end(); ++iter)
{
VERIFY_ARE_EQUAL(iter->second, actual.find(iter->first)->second);
}
}
void http_asserts::assert_request_equals(
::http::http_request request,
const ::http::method &mtd,
const utility::string_t & relative_path)
{
VERIFY_ARE_EQUAL(mtd, request.method());
if(relative_path == U(""))
{
VERIFY_ARE_EQUAL(U("/"), request.relative_uri().to_string());
}
else
{
VERIFY_ARE_EQUAL(relative_path, request.relative_uri().to_string());
}
}
void http_asserts::assert_request_equals(
::http::http_request request,
const ::http::method &mtd,
const utility::string_t & relative_uri,
const std::map<utility::string_t, utility::string_t> &headers)
{
assert_request_equals(request, mtd, relative_uri);
verify_headers(headers, request.headers());
}
void http_asserts::assert_request_equals(
::http::http_request request,
const ::http::method &mtd,
const utility::string_t & relative_path,
const utility::string_t & body)
{
assert_request_equals(request, mtd, relative_path);
auto request_data = request.extract_string().get();
VERIFY_ARE_EQUAL(body, request_data);
}
void http_asserts::assert_response_equals(
::http::http_response response,
const ::http::status_code &code)
{
VERIFY_ARE_EQUAL(response.status_code(), code);
}
void http_asserts::assert_response_equals(
::http::http_response response,
const ::http::status_code &code,
const utility::string_t &reason)
{
VERIFY_ARE_EQUAL(code, response.status_code());
VERIFY_ARE_EQUAL(reason, response.reason_phrase());
}
void http_asserts::assert_response_equals(
::http::http_response response,
const ::http::status_code &code,
const std::map<utility::string_t, utility::string_t> &headers)
{
VERIFY_ARE_EQUAL(code, response.status_code());
verify_headers(headers, response.headers());
}
void http_asserts::assert_http_headers_equals(
const ::http::http_headers &actual,
const ::http::http_headers &expected)
{
verify_headers(actual, expected);
}
void http_asserts::assert_test_request_equals(
const test_request *const p_request,
const ::http::method &mtd,
const utility::string_t &path)
{
VERIFY_ARE_EQUAL(mtd, p_request->m_method);
VERIFY_ARE_EQUAL(path, p_request->m_path);
}
void http_asserts::assert_test_request_equals(
const test_request *const p_request,
const ::http::method &mtd,
const utility::string_t &path,
const utility::string_t &content_type)
{
VERIFY_ARE_EQUAL(mtd, p_request->m_method);
VERIFY_ARE_EQUAL(path, p_request->m_path);
// verify that content-type key exists in the header and the value matches the one provided
auto iter = p_request->m_headers.find(U("Content-Type"));
if(content_type.empty())
{
VERIFY_ARE_EQUAL(iter, p_request->m_headers.end());
}
else
{
VERIFY_IS_TRUE(iter != p_request->m_headers.end());
VERIFY_ARE_EQUAL(iter->second.find(content_type), 0);
}
}
void http_asserts::assert_test_request_contains_headers(
const test_request *const p_request,
const ::http::http_headers &headers)
{
verify_headers(headers, p_request->m_headers);
}
void http_asserts::assert_test_request_contains_headers(
const test_request *const p_request,
const std::map<utility::string_t, utility::string_t> &headers)
{
verify_headers(headers, p_request->m_headers);
}
// Helper function to parse HTTP headers from a stringstream.
static std::map<utility::string_t, utility::string_t> parse_headers(utility::istringstream_t &ss)
{
// Keep parsing until CRLF is encountered.
std::map<utility::string_t, utility::string_t> headers;
utility::string_t header_line;
while(getline(ss, header_line).good())
{
const size_t colon_index = header_line.find(U(":"));
const utility::string_t header_name = header_line.substr(0, colon_index);
utility::string_t header_value = header_line.substr(colon_index + 1);
web::http::details::trim_whitespace(header_value);
headers[header_name] = header_value;
char c1 = (char)ss.get(), c2 = (char)ss.get();
if(c1 == '\r' && c2 == '\n')
{
break;
}
ss.unget();
ss.unget();
}
return headers;
}
void http_asserts::assert_request_string_equals(
const utility::string_t &request,
const ::http::method &mtd,
const utility::string_t &path,
const utility::string_t &version,
const std::map<utility::string_t, utility::string_t> &headers,
const utility::string_t &body)
{
utility::istringstream_t ss(request);
// Parse request line.
utility::string_t actual_method, actual_path, actual_version;
ss >> actual_method >> actual_path >> actual_version;
// Parse headers.
utility::string_t temp;
getline(ss, temp);
std::map<utility::string_t, utility::string_t> actual_headers = parse_headers(ss);
// Parse in any message body
utility::string_t actual_body = ss.str().substr((size_t)ss.tellg());
VERIFY_ARE_EQUAL(mtd, actual_method);
VERIFY_ARE_EQUAL(path, actual_path);
VERIFY_ARE_EQUAL(version, actual_version);
verify_headers(headers, actual_headers);
VERIFY_ARE_EQUAL(body, actual_body);
}
void http_asserts::assert_response_string_equals(
const utility::string_t &response,
const utility::string_t &version,
const ::http::status_code &code,
const utility::string_t &phrase,
const std::map<utility::string_t, utility::string_t> &headers,
const utility::string_t &body)
{
utility::istringstream_t ss(response);
// Parse response line.
utility::string_t actual_version, actual_phrase;
::http::status_code actual_code;
ss >> actual_version >> actual_code >> actual_phrase;
// Parse headers.
utility::string_t temp;
getline(ss, temp);
std::map<utility::string_t, utility::string_t> actual_headers = parse_headers(ss);
// Prase in any message body.
utility::string_t actual_body = ss.str().substr((size_t)ss.tellg());
VERIFY_ARE_EQUAL(version, actual_version);
VERIFY_ARE_EQUAL(code, actual_code);
VERIFY_ARE_EQUAL(phrase, actual_phrase);
verify_headers(headers, actual_headers);
VERIFY_ARE_EQUAL(body, actual_body);
}
void http_asserts::assert_test_request_equals(
const test_request *const p_request,
const ::http::method &mtd,
const utility::string_t &path,
const utility::string_t &content_type,
const utility::string_t &body)
{
assert_test_request_equals(p_request, mtd, path, content_type);
// Textual response is always sent as UTF-8, hence the converison to string_t
std::string s((char*)&p_request->m_body[0], p_request->m_body.size());
utility::string_t extracted_body = to_string_t(s);
VERIFY_ARE_EQUAL(body, extracted_body);
}
void http_asserts::assert_test_response_equals(
const test_response * const p_response,
const ::http::status_code &code)
{
VERIFY_ARE_EQUAL(code, p_response->m_status_code);
}
void http_asserts::assert_test_response_equals(
const test_response * const p_response,
const ::http::status_code &code,
const std::map<utility::string_t, utility::string_t> &headers)
{
VERIFY_ARE_EQUAL(code, p_response->m_status_code);
verify_headers(headers, p_response->m_headers);
}
void http_asserts::assert_test_response_equals(
const test_response * const p_response,
const ::http::status_code &code,
const ::http::http_headers &headers)
{
VERIFY_ARE_EQUAL(code, p_response->m_status_code);
verify_headers(headers, p_response->m_headers);
}
void http_asserts::assert_test_response_equals(
test_response * p_response,
const ::http::status_code &code,
const utility::string_t &content_type)
{
VERIFY_ARE_EQUAL(code, p_response->m_status_code);
utility::string_t found_content;
p_response->match_header(U("Content-Type"), found_content);
VERIFY_ARE_EQUAL(content_type, found_content);
}
void http_asserts::assert_test_response_equals(
test_response * p_response,
const ::http::status_code &code,
const utility::string_t &content_type,
const utility::string_t data)
{
VERIFY_ARE_EQUAL(code, p_response->m_status_code);
utility::string_t found_content;
p_response->match_header(U("Content-Type"), found_content);
VERIFY_ARE_EQUAL(found_content.find(content_type), 0);
// Beware: what kind of string this is? <-- stringhack until we tighten up wide/narrow string business
utility::string_t extracted_body;
if(p_response->m_data.size() == 0)
{
extracted_body = U("");
}
else
{
auto actualRawData = (char*)&p_response->m_data[0];
if(p_response->m_data.size() > 1 && *(actualRawData+1) == '\0' )
{
// We have more than one byte of data, but it's null-terminated at byte 1.
// Therefore, this is a wide string
extracted_body.assign((utility::char_t*)actualRawData, p_response->m_data.size()/sizeof(utility::char_t));
}
else{
std::string s(actualRawData, p_response->m_data.size());
extracted_body = to_string_t(s);
}
}
VERIFY_ARE_EQUAL(data, extracted_body);
}
}}}}