HttpRequest

博客详细介绍了HTTP响应包的组成,主要由状态码(status),头部(headers)和主体(body)三部分构成,深入探讨了每个部分的作用和重要性。
摘要由CSDN通过智能技术生成
响应包分成三个部分(status+headers+nody)
//
//  HTTPRequest
//

#ifndef HTTPREQUEST_HPP
#define HTTPREQUEST_HPP

#include <algorithm>
#include <functional>
#include <stdexcept>
#include <system_error>
#include <map>
#include <string>
#include<memory>
#include <vector>
#include <cctype>
#include <cstddef>
#include <cstdint>


using namespace std;
#ifdef _WIN32
#  pragma push_macro("WIN32_LEAN_AND_MEAN")
#  pragma push_macro("NOMINMAX")
#  ifndef WIN32_LEAN_AND_MEAN
#    define WIN32_LEAN_AND_MEAN
#  endif
#  ifndef NOMINMAX
#    define NOMINMAX
#  endif
#  include <winsock2.h>
#  include <ws2tcpip.h>
#  pragma pop_macro("WIN32_LEAN_AND_MEAN")
#  pragma pop_macro("NOMINMAX")
# pragma comment(lib, "Ws2_32.lib")
#else
#  include <sys/socket.h>
#  include <netinet/in.h>
#  include <netdb.h>
#  include <unistd.h>
#  include <errno.h>
#endif

namespace http
{
   
#ifdef _WIN32
    class WinSock final
    {
   
    public:
        WinSock(){
   
            WSADATA wsaData;
            int error = WSAStartup(MAKEWORD(2, 2), &wsaData);
            if (error != 0)throw std::system_error(error, std::system_category(), "WSAStartup failed");
            started = true;
            if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) throw std::runtime_error("Invalid WinSock version");
        }

        ~WinSock()  {
   
            if (started) WSACleanup();
        }

        WinSock(const WinSock&) = delete;
        WinSock& operator=(const WinSock&) = delete;

        WinSock(WinSock&& other) noexcept:started(other.started){
   
            other.started = false;
        }

        WinSock& operator=(WinSock&& other) noexcept{
   
            if (&other == this) return *this;
            if (started) WSACleanup();
            started = other.started;
            other.started = false;
            return *this;
        }

    private:
        bool started = false;
    };
#endif

    inline int getLastError() noexcept
    {
   
#ifdef _WIN32
        return WSAGetLastError();
#else
        return errno;
#endif
    }

    enum class InternetProtocol: uint8_t
    {
   
        V4,
        V6
    };

    constexpr int getAddressFamily(InternetProtocol internetProtocol){
   
        return (internetProtocol == InternetProtocol::V4) ? AF_INET :
            (internetProtocol == InternetProtocol::V6) ? AF_INET6 :
            throw std::runtime_error("Unsupported protocol");
    }

    class Socket final
    {
   
    public:
#ifdef _WIN32
        using Type = SOCKET;
        static constexpr Type Invalid = INVALID_SOCKET;
#else
        using Type = int;
        static constexpr Type Invalid = -1;
#endif

        explicit Socket(InternetProtocol internetProtocol):endpoint(socket(getAddressFamily(internetProtocol), SOCK_STREAM, IPPROTO_TCP))
        {
   
            if (endpoint == Invalid)
                throw std::system_error(getLastError(), std::system_category(), "Failed to create socket");
        }

        explicit Socket(Type s) noexcept:
            endpoint(s)
        {
   
        }

        ~Socket()
        {
   
            if (endpoint != Invalid) close();
        }

        Socket(const Socket&) = delete;
        Socket& operator=(const Socket&) = delete;

        Socket(Socket&& other) noexcept:
            endpoint(other.endpoint)
        {
   
            other.endpoint = Invalid;
        }

        Socket& operator=(Socket&& other) noexcept
        {
   
            if (&other == this) return *this;
            if (endpoint != Invalid) close();
            endpoint = other.endpoint;
            other.endpoint = Invalid;
            return *this;
        }

        inline operator Type() const noexcept {
    return endpoint; }

    private:
        inline void close() noexcept
        {
   
#ifdef _WIN32
            closesocket(endpoint);
#else
            ::close(endpoint);
#endif
        }

        Type endpoint = Invalid;
    };

    inline std::string urlEncode(const std::string& str)
    {
   
        constexpr char hexChars[16] = {
   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};

        std::string result;

        for (auto i = str.begin(
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值