summaryrefslogtreecommitdiffstats
path: root/src/seastar/include/seastar/http/request.hh
blob: e09a1c1b33e754658047d9d0c1381d2b8c9cb8e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  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.
 */
/*
 * Copyright 2015 Cloudius Systems
 */

//
// request.hpp
// ~~~~~~~~~~~
//
// Copyright (c) 2003-2013 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#pragma once

#include <seastar/core/sstring.hh>
#include <string>
#include <vector>
#include <strings.h>
#include <seastar/http/common.hh>

namespace seastar {

namespace httpd {
class connection;

/**
 * A request received from a client.
 */
struct request {
    enum class ctclass
        : char {
            other, multipart, app_x_www_urlencoded,
    };

    struct case_insensitive_cmp {
        bool operator()(const sstring& s1, const sstring& s2) const {
            return std::equal(s1.begin(), s1.end(), s2.begin(), s2.end(),
                    [](char a, char b) { return ::tolower(a) == ::tolower(b); });
        }
    };

    struct case_insensitive_hash {
        size_t operator()(sstring s) const {
            std::transform(s.begin(), s.end(), s.begin(), ::tolower);
            return std::hash<sstring>()(s);
        }
    };

    sstring _method;
    sstring _url;
    sstring _version;
    int http_version_major;
    int http_version_minor;
    ctclass content_type_class;
    size_t content_length = 0;
    std::unordered_map<sstring, sstring, case_insensitive_hash, case_insensitive_cmp> _headers;
    std::unordered_map<sstring, sstring> query_parameters;
    connection* connection_ptr;
    parameters param;
    sstring content;
    sstring protocol_name = "http";

    /**
     * Search for the first header of a given name
     * @param name the header name
     * @return a pointer to the header value, if it exists or empty string
     */
    sstring get_header(const sstring& name) const {
        auto res = _headers.find(name);
        if (res == _headers.end()) {
            return "";
        }
        return res->second;
    }

    /**
     * Search for the first header of a given name
     * @param name the header name
     * @return a pointer to the header value, if it exists or empty string
     */
    sstring get_query_param(const sstring& name) const {
        auto res = query_parameters.find(name);
        if (res == query_parameters.end()) {
            return "";
        }
        return res->second;
    }

    /**
     * Get the request protocol name. Can be either "http" or "https".
     */
    sstring get_protocol_name() const {
        return protocol_name;
    }

    /**
     * Get the request url.
     * @return the request url
     */
    sstring get_url() const {
        return get_protocol_name() + "://" + get_header("Host") + _url;
    }

    bool is_multi_part() const {
        return content_type_class == ctclass::multipart;
    }

    bool is_form_post() const {
        return content_type_class == ctclass::app_x_www_urlencoded;
    }

};

} // namespace httpd

}