bool is_matching_content_type(const utility::string_t& actual, const utility::string_t& expected)
 {
     // Check if the response's actual content type matches the expected content type.
     // It is OK if the actual content type has additional parameters (e.g. application/json;odata=minimalmetadata;streaming=true;charset=utf-8).
     return (actual.size() == expected.size() || (actual.size() > expected.size() && actual.at(expected.size()) == U(';'))) &&
         std::equal(expected.cbegin(), expected.cend(), actual.cbegin());
 }
Пример #2
0
void split_string(::utility::string_t& source, const ::utility::string_t& delim, std::list<::utility::string_t>& ret)
{
	ret.clear();

	if (delim.empty() || source.empty())
	{
		ret.push_back(source);
		return ;
	}

	size_t last = 0;
	size_t index = source.find(delim, last);

    while (index!=std::string::npos)
    {
		ret.push_back(source.substr(last, index - last));
		last = index + delim.size();
		index = source.find(delim, last);
	}

    if(index - last > 0)
	{
		ret.push_back(source.substr(last, index - last));
	}
}
Пример #3
0
utility::string_t get_object_name(const utility::string_t& object_type_name)
{
    utility::string_t object_name;
    object_name.reserve(37U + object_type_name.size());
    object_name.append(object_name_prefix);
    object_name.append(object_type_name);
    object_name.append(get_random_string());
    return object_name;
}
Пример #4
0
void extract_fractional_second(const utility::string_t& dateString, utility::string_t& resultString, uint64_t& ufrac_second)
{
    resultString = dateString;
    // First, the string must be strictly longer than 2 characters, and the trailing character must be 'Z'
    if (resultString.size() > 2 && resultString[resultString.size() - 1] == U('Z'))
    {
        // Second, find the last non-digit by scanning the string backwards
        auto last_non_digit = std::find_if_not(resultString.rbegin() + 1, resultString.rend(), is_digit);
        if (last_non_digit < resultString.rend() - 1)
        {
            // Finally, make sure the last non-digit is a dot:
            auto last_dot = last_non_digit.base() - 1;
            if (*last_dot == U('.'))
            {
                // Got it! Now extract the fractional second
                auto last_before_Z = std::end(resultString) - 1;
                ufrac_second = timeticks_from_second(last_dot, last_before_Z);
                // And erase it from the string
                resultString.erase(last_dot, last_before_Z);
            }
        }
    }
}
Пример #5
0
/// <summary>
/// Parses the given Content-Type header value to get out actual content type and charset.
/// If the charset isn't specified the default charset for the content type will be set.
/// </summary>
static void parse_content_type_and_charset(const utility::string_t& content_type,
                                           utility::string_t& content,
                                           utility::string_t& charset)
{
    const size_t semi_colon_index = content_type.find_first_of(_XPLATSTR(";"));

    // No charset specified.
    if (semi_colon_index == utility::string_t::npos)
    {
        content = content_type;
        trim_whitespace(content);
        charset = get_default_charset(content);
        return;
    }

    // Split into content type and second part which could be charset.
    content = content_type.substr(0, semi_colon_index);
    trim_whitespace(content);
    utility::string_t possible_charset = content_type.substr(semi_colon_index + 1);
    trim_whitespace(possible_charset);
    const size_t equals_index = possible_charset.find_first_of(_XPLATSTR("="));

    // No charset specified.
    if (equals_index == utility::string_t::npos)
    {
        charset = get_default_charset(content);
        return;
    }

    // Split and make sure 'charset'
    utility::string_t charset_key = possible_charset.substr(0, equals_index);
    trim_whitespace(charset_key);
    if (!utility::details::str_iequal(charset_key, _XPLATSTR("charset")))
    {
        charset = get_default_charset(content);
        return;
    }
    charset = possible_charset.substr(equals_index + 1);
    // Remove the redundant ';' at the end of charset.
    while (charset.back() == ';')
    {
        charset.pop_back();
    }
    trim_whitespace(charset);
    if (charset.front() == _XPLATSTR('"') && charset.back() == _XPLATSTR('"'))
    {
        charset = charset.substr(1, charset.size() - 2);
        trim_whitespace(charset);
    }
}
Пример #6
0
/// <summary>
/// Determines whether or not the given content type is 'textual' according the feature specifications.
/// </summary>
static bool is_content_type_textual(const utility::string_t& content_type)
{
#if !defined(_WIN32) || _MSC_VER >= 1900
    static const utility::string_t textual_types[] = {mime_types::message_http,
                                                      mime_types::application_json,
                                                      mime_types::application_xml,
                                                      mime_types::application_atom_xml,
                                                      mime_types::application_http,
                                                      mime_types::application_x_www_form_urlencoded};
#endif

    if (content_type.size() >= 4 && utility::details::str_iequal(content_type.substr(0, 4), _XPLATSTR("text")))
    {
        return true;
    }
    return (is_content_type_one_of(std::begin(textual_types), std::end(textual_types), content_type));
}
Пример #7
0
::utility::string_t strip_string(const ::utility::string_t& escaped)
{
    ::utility::string_t::size_type first = 0;
    ::utility::string_t::size_type size = escaped.size();

	if (escaped.empty())
	{
		return escaped;
	}

    if (escaped[0] == U('"'))
	{
        first += 1;
	}

    if (escaped[size - 1] == U('"'))
	{
        size -= 1;
	}

    return escaped.substr(first, size - first);
}
Пример #8
0
std::map<utility::string_t, utility::string_t> uri::split_query(const utility::string_t &query)
{
    std::map<utility::string_t, utility::string_t> results;

    // Split into key value pairs separated by '&'.
    size_t prev_amp_index = 0;
    while(prev_amp_index != utility::string_t::npos)
    {
        size_t amp_index = query.find_first_of(_XPLATSTR('&'), prev_amp_index);
        if (amp_index == utility::string_t::npos)
            amp_index = query.find_first_of(_XPLATSTR(';'), prev_amp_index);

        utility::string_t key_value_pair = query.substr(
            prev_amp_index,
            amp_index == utility::string_t::npos ? query.size() - prev_amp_index : amp_index - prev_amp_index);
        prev_amp_index = amp_index == utility::string_t::npos ? utility::string_t::npos : amp_index + 1;

        size_t equals_index = key_value_pair.find_first_of(_XPLATSTR('='));
        if(equals_index == utility::string_t::npos)
        {
            continue;
        }
        else if (equals_index == 0)
        {
            utility::string_t value(key_value_pair.begin() + equals_index + 1, key_value_pair.end());
            results[_XPLATSTR("")] = value;
        }
        else
        {
            utility::string_t key(key_value_pair.begin(), key_value_pair.begin() + equals_index);
            utility::string_t value(key_value_pair.begin() + equals_index + 1, key_value_pair.end());
        results[key] = value;
    }
    }

    return results;
}
Пример #9
0
std::vector<unsigned char> _from_base64(const utility::string_t& input)
{
    std::vector<unsigned char> result;

    if ( input.empty() ) 
        return result;

    size_t padding = 0;

    // Validation
    {
        auto size = input.size();

        if ( (size % 4) != 0 )
        {
            throw std::runtime_error("length of base64 string is not an even multiple of 4");
        }

        for (auto iter = input.begin(); iter != input.end(); ++iter,--size)
        {
            auto ch = *iter;
            if ( ch < 0 || _base64_dectbl[ch] == 255 )
            {
                throw std::runtime_error("invalid character found in base64 string");
            }
            if ( _base64_dectbl[ch] == 254 )
            {
                padding++;
                // padding only at the end
                if ( size > 2 || (size == 2 && _base64_dectbl[*(iter+1)] != 254) )
                {
                    throw std::runtime_error("invalid padding character found in base64 string");
                }
            }
        }
    }


    auto size = input.size();
    const char_t* ptr = &input[0];

    auto outsz = (size / 4)*3;
    outsz -= padding;

    result.resize(outsz);

    size_t idx = 0;
    for (; size > 4; ++idx )
    {
        unsigned char target[3];
        memset(target, 0, sizeof(target));
        _triple_byte* record = reinterpret_cast<_triple_byte*>(target);

        unsigned char val0 = _base64_dectbl[ptr[0]];
        unsigned char val1 = _base64_dectbl[ptr[1]];
        unsigned char val2 = _base64_dectbl[ptr[2]];
        unsigned char val3 = _base64_dectbl[ptr[3]];

        record->_0   = val0;
        record->_1_1 = val1 >> 4;
        result[idx] = target[0];

        record->_1_2 = val1 & 0xF;
        record->_2_1 = val2 >> 2;
        result[++idx] = target[1];

        record->_2_2 = val2 & 0x3;
        record->_3   = val3 & 0x3F;
        result[++idx] = target[2];

        ptr += 4;
        size -= 4;
    }

    // Handle the last four bytes separately, to avoid having the conditional statements
    // in all the iterations (a performance issue).

    { 
        unsigned char target[3];
        memset(target, 0, sizeof(target));
        _triple_byte* record = reinterpret_cast<_triple_byte*>(target);

        unsigned char val0 = _base64_dectbl[ptr[0]];
        unsigned char val1 = _base64_dectbl[ptr[1]];
        unsigned char val2 = _base64_dectbl[ptr[2]];
        unsigned char val3 = _base64_dectbl[ptr[3]];

        record->_0   = val0;
        record->_1_1 = val1 >> 4;
        result[idx] = target[0];

        record->_1_2 = val1 & 0xF;
        if ( val2 != 254 )
        {
            record->_2_1 = val2 >> 2;
            result[++idx] = target[1];
        }
        else
        {
            // There shouldn't be any information (ones) in the unused bits,
            if ( record->_1_2 != 0 )