[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/MatthieuTexier/libhttpserver/master/src/http_utils.cpp [Back]  [Original]

/*
     This file is part of libhttpserver
     Copyright (C) 2011-2019 Sebastiano Merlino

     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public
     License as published by the Free Software Foundation; either
     version 2.1 of the License, or (at your option) any later version.

     This library 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
     Lesser General Public License for more details.

     You should have received a copy of the GNU Lesser General Public
     License along with this library; if not, write to the Free Software
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
     USA
*/

#include "httpserver/http_utils.hpp"

#if defined(_WIN32) && ! defined(__CYGWIN__)
#include 
#include 
#else // WIN32 check
#if defined(__FreeBSD__)
#include 
#endif // FreeBSD
#include 
#include 
#include 
#include 
#include 
#endif // WIN32 check

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "httpserver/string_utilities.hpp"

#pragma GCC diagnostic ignored "-Warray-bounds"
#define CHECK_BIT(var,pos) ((var) & (1sin_addr), to_ret, INET_ADDRSTRLEN);
        return to_ret;
    }
    else
    {
        throw std::invalid_argument("IP family must be either AF_INET or AF_INET6");
    }
}

unsigned short get_port(const struct sockaddr* sa)
{
    if (!sa) throw std::invalid_argument("socket pointer is null");

    if (sa->sa_family == AF_INET)
    {
        return ((struct sockaddr_in*) sa)->sin_port;
    }
    else if (sa->sa_family == AF_INET6)
    {
        return ((struct sockaddr_in6*) sa)->sin6_port;
    }
    else
    {
        throw std::invalid_argument("IP family must be either AF_INET or AF_INET6");
    }
}

size_t http_unescape(std::string& val)
{
    if (val.empty()) return 0;

    int rpos = 0;
    int wpos = 0;

    unsigned int num;

    while ('\0' != val[rpos])
    {
        switch (val[rpos])
        {
            case '+':
                val[wpos] = ' ';
                wpos++;
                rpos++;
                break;
            case '%':
                if ( (1 == sscanf (val.substr(rpos + 1).c_str(), "%2x", &num)) ||
                    (1 == sscanf (val.substr(rpos + 1).c_str(), "%2X", &num))
                )
                {
                    val[wpos] = (unsigned char) num;
                    wpos++;
                    rpos += 3;
                    break;
                }
            /* intentional fall through! */
            default:
                val[wpos] = val[rpos];
                wpos++;
                rpos++;
        }
    }
    val[wpos] = '\0'; /* add 0-terminator */
    val.resize(wpos);
    return wpos; /* = strlen(val) */
}

ip_representation::ip_representation(const struct sockaddr* ip)
{
    std::fill(pieces, pieces + 16, 0);
    if(ip->sa_family == AF_INET)
    {
        ip_version = http_utils::IPV4;
        for(int i=0;isin_addr))[i];
        }
    }
    else
    {
        ip_version = http_utils::IPV6;
        for (int i = 0; i < 16; i++)
        {
            pieces[i] = ((u_char*)&(((struct sockaddr_in6 *)ip)->sin6_addr))[i];
        }
    }
    mask = DEFAULT_MASK_VALUE;
}

ip_representation::ip_representation(const std::string& ip)
{
    std::vector parts;
    mask = DEFAULT_MASK_VALUE;
    std::fill(pieces, pieces + 16, 0);
    if(ip.find(':') != std::string::npos) //IPV6
    {
        ip_version = http_utils::IPV6;
        parts = string_utilities::string_split(ip, ':', false);
        if (parts.size() > 8)
        {
            throw std::invalid_argument("IP is badly formatted. Max 8 parts in IPV6.");
        }

        unsigned int omitted = 8 - (parts.size() - 1);
        if (omitted != 0)
        {
            int empty_count = 0;
            for (unsigned int i = 0; i < parts.size(); i++)
            {
                if (parts[i].size() == 0) empty_count++;
            }

            if (empty_count > 1)
            {
                if (parts[parts.size() - 1].find(".") != std::string::npos) omitted -= 1;

                if (empty_count == 2 && parts[0] == "" && parts[1] == "")
                {
                    omitted += 1;
                    parts = std::vector(parts.begin() + 1, parts.end());
                }
                else
                {
                    throw std::invalid_argument("IP is badly formatted. Cannot have more than one omitted segment in IPV6.");
                }
            }
        }

        int y = 0;
        for (unsigned int i = 0; i < parts.size(); i++)
        {
            if (parts[i] != "*")
            {
                if (parts[i].size() == 0)
                {
                    for (unsigned int omitted_idx = 0; omitted_idx < omitted; omitted_idx++)
                    {
                        pieces[y] = 0;
                        pieces[y+1] = 0;
                        y += 2;
                    }

                    continue;
                }

                if (parts[i].size() < 4)
                {
                    stringstream ss;
                    ss 

Web Proxy Viewer  |  New URL  |  Original Page