Coverage Report

Created: 2025-08-28 06:51

/src/crow/include/crow/http_request.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#ifdef CROW_USE_BOOST
4
#include <boost/asio.hpp>
5
#else
6
#ifndef ASIO_STANDALONE
7
#define ASIO_STANDALONE
8
#endif
9
#include <asio.hpp>
10
#endif
11
12
#include "crow/common.h"
13
#include "crow/ci_map.h"
14
#include "crow/query_string.h"
15
16
namespace crow // NOTE: Already documented in "crow/app.h"
17
{
18
#ifdef CROW_USE_BOOST
19
    namespace asio = boost::asio;
20
#endif
21
22
    /// Find and return the value associated with the key. (returns an empty string if nothing is found)
23
    template<typename T>
24
    inline const std::string& get_header_value(const T& headers, const std::string& key)
25
0
    {
26
0
        if (headers.count(key))
27
0
        {
28
0
            return headers.find(key)->second;
29
0
        }
30
0
        static std::string empty;
31
0
        return empty;
32
0
    }
33
34
    /// An HTTP request.
35
    struct request
36
    {
37
        HTTPMethod method;
38
        std::string raw_url;     ///< The full URL containing the `?` and URL parameters.
39
        std::string url;         ///< The endpoint without any parameters.
40
        query_string url_params; ///< The parameters associated with the request. (everything after the `?` in the URL)
41
        ci_map headers;
42
        std::string body;
43
        std::string remote_ip_address; ///< The IP address from which the request was sent.
44
        unsigned char http_ver_major, http_ver_minor;
45
        bool keep_alive,    ///< Whether or not the server should send a `connection: Keep-Alive` header to the client.
46
          close_connection, ///< Whether or not the server should shut down the TCP connection once a response is sent.
47
          upgrade;          ///< Whether or noth the server should change the HTTP connection to a different connection.
48
49
        void* middleware_context{};
50
        void* middleware_container{};
51
        asio::io_context* io_context{};
52
53
        /// Construct an empty request. (sets the method to `GET`)
54
        request():
55
          method(HTTPMethod::Get)
56
0
        {}
57
58
        /// Construct a request with all values assigned.
59
        request(HTTPMethod method_, std::string raw_url_, std::string url_, query_string url_params_, ci_map headers_, std::string body_, unsigned char http_major, unsigned char http_minor, bool has_keep_alive, bool has_close_connection, bool is_upgrade):
60
          method(method_), raw_url(std::move(raw_url_)), url(std::move(url_)), url_params(std::move(url_params_)), headers(std::move(headers_)), body(std::move(body_)), http_ver_major(http_major), http_ver_minor(http_minor), keep_alive(has_keep_alive), close_connection(has_close_connection), upgrade(is_upgrade)
61
0
        {}
62
63
        void add_header(std::string key, std::string value)
64
0
        {
65
0
            headers.emplace(std::move(key), std::move(value));
66
0
        }
67
68
        const std::string& get_header_value(const std::string& key) const
69
0
        {
70
0
            return crow::get_header_value(headers, key);
71
0
        }
72
73
        bool check_version(unsigned char major, unsigned char minor) const
74
0
        {
75
0
            return http_ver_major == major && http_ver_minor == minor;
76
0
        }
77
78
        /// Get the body as parameters in QS format.
79
80
        ///
81
        /// This is meant to be used with requests of type "application/x-www-form-urlencoded"
82
        const query_string get_body_params() const
83
0
        {
84
0
            return query_string(body, false);
85
0
        }
86
87
        /// Send data to whoever made this request with a completion handler and return immediately.
88
        template<typename CompletionHandler>
89
        void post(CompletionHandler handler)
90
        {
91
            asio::post(io_context, handler);
92
        }
93
94
        /// Send data to whoever made this request with a completion handler.
95
        template<typename CompletionHandler>
96
        void dispatch(CompletionHandler handler)
97
        {
98
            asio::dispatch(io_context, handler);
99
        }
100
    };
101
} // namespace crow