Skip to content

Commit d30ea67

Browse files
lihuibaColdwings
andauthored
reimplement HTTP status strings with static_strings (alibaba#847)
* reimplement HTTP status strings with ```static_strings``` * Use conststr --------- Co-authored-by: Coldwings <coldwings@me.com>
1 parent 0fcee0f commit d30ea67

3 files changed

Lines changed: 202 additions & 175 deletions

File tree

common/conststr.h

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ limitations under the License.
1616

1717
#pragma once
1818

19+
#include <photon/common/string_view.h>
20+
21+
#include <cstddef>
1922
#include <cstdint>
2023
#include <type_traits>
2124

22-
#include "string_view.h"
23-
2425
namespace ConstString {
2526

2627
template <typename T, T... xs>
@@ -151,6 +152,7 @@ struct Accumulate {
151152
using Prepend = Accumulate<T, 0, (xs + x)...>;
152153

153154
constexpr static T arr[sizeof...(xs)] = {xs...};
155+
constexpr static T size() { return sizeof...(xs); }
154156
};
155157

156158
template <typename T, T... xs>
@@ -214,7 +216,7 @@ constexpr std::string_view TStrArray<Tss...>::views[];
214216
template <typename... Tss>
215217
constexpr size_t TStrArray<Tss...>::size;
216218

217-
template<typename... Tss>
219+
template <typename... Tss>
218220
constexpr static decltype(auto) make_tstring_array(Tss...) {
219221
return TStrArray<Tss...>{};
220222
}
@@ -299,4 +301,32 @@ struct EnumStr : public Split {
299301
return ConstString::EnumStr<enum_name, sp>(); \
300302
}()
301303

304+
template <typename Accum, typename Whole>
305+
struct CompactStringArray {
306+
constexpr static decltype(auto) whole() { return Whole(); }
307+
308+
constexpr static std::string_view at(size_t i) {
309+
return {&Whole::chars[Accum::arr[i] + i],
310+
(size_t)Accum::arr[i + 1] - (size_t)Accum::arr[i]};
311+
}
312+
313+
template <typename TS>
314+
constexpr static decltype(auto) prepend(TS t) {
315+
return CompactStringArray<typename Accum::template Prepend<t.len>,
316+
decltype(t.template append<'\0'>().concat(
317+
Whole()))>();
318+
}
319+
};
320+
321+
template <typename SizeType>
322+
inline decltype(auto) make_compact_str_array() {
323+
return CompactStringArray<Accumulate<SizeType, 0>, TString<>>();
324+
}
325+
326+
template <typename SizeType, char... Chs, typename... Ts>
327+
inline decltype(auto) make_compact_str_array(TString<Chs...> first,
328+
Ts&&... tail) {
329+
return make_compact_str_array<SizeType>(tail...).prepend(first);
330+
}
331+
302332
} // namespace ConstString

net/http/status.cpp

Lines changed: 95 additions & 172 deletions
Original file line numberDiff line numberDiff line change
@@ -14,176 +14,99 @@ See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
1616

17-
#include "photon/common/string_view.h"
18-
#include "message.h"
19-
20-
struct SV : public std::string_view {
21-
template<size_t N>
22-
constexpr SV(const char(&s)[N]) : SV(s, N-1) { }
23-
constexpr SV(const char* s, size_t n) : std::string_view(s, n) { }
24-
};
25-
26-
constexpr static SV code_str[] = {
27-
/*100*/ "Continue",
28-
/*101*/ "Switching Protocols",
29-
/*102*/ "Processing",
30-
/*103*/ "Early Hints",
31-
32-
/*200*/ "OK",
33-
/*201*/ "Created",
34-
/*202*/ "Accepted",
35-
/*203*/ "Non-Authoritative Information",
36-
/*204*/ "No Content",
37-
/*205*/ "Reset Content",
38-
/*206*/ "Partial Content",
39-
/*207*/ "Multi-Status",
40-
/*208*/ "Already Reported",
41-
// /*226*/ "IM Used",
42-
43-
/*300*/ "Multiple Choices",
44-
/*301*/ "Moved Permanently",
45-
/*302*/ "Found",
46-
/*303*/ "See Other",
47-
/*304*/ "Not Modified",
48-
/*305*/ "Use Proxy",
49-
/*306*/ {0, 0},
50-
/*307*/ "Temporary Redirect",
51-
/*308*/ "Permanent Redirect",
52-
53-
/*400*/ "Bad Request",
54-
/*401*/ "Unauthorized",
55-
/*402*/ "Payment Required",
56-
/*403*/ "Forbidden",
57-
/*404*/ "Not Found",
58-
/*405*/ "Method Not Allowed",
59-
/*406*/ "Not Acceptable",
60-
/*407*/ "Proxy Authentication Required",
61-
/*408*/ "Request Timeout",
62-
/*409*/ "Conflict",
63-
/*410*/ "Gone",
64-
/*411*/ "Length Required",
65-
/*412*/ "Precondition Failed",
66-
/*413*/ "Content Too Large",
67-
/*414*/ "URI Too Long",
68-
/*415*/ "Unsupported Media Type",
69-
/*416*/ "Range Not Satisfiable",
70-
/*417*/ "Expectation Failed",
71-
/*418*/ "I'm a teapot",
72-
/*419*/ {0, 0},
73-
/*420*/ {0, 0},
74-
/*421*/ "Misdirected Request",
75-
/*422*/ "Unprocessable Content",
76-
/*423*/ "Locked",
77-
/*424*/ "Failed Dependency",
78-
/*425*/ "Too Early",
79-
/*426*/ "Upgrade Required",
80-
/*427*/ {0, 0},
81-
/*428*/ "Precondition Required",
82-
/*429*/ "Too Many Requests",
83-
/*430*/ {0, 0},
84-
/*431*/ "Request Header Fields Too Large",
85-
// /*451*/ "Unavailable For Legal Reasons",
86-
87-
/*500*/ "Internal Server Error",
88-
/*501*/ "Not Implemented",
89-
/*502*/ "Bad Gateway",
90-
/*503*/ "Service Unavailable",
91-
/*504*/ "Gateway Timeout",
92-
/*505*/ "HTTP Version Not Supported",
93-
/*506*/ "Variant Also Negotiates",
94-
/*507*/ "Insufficient Storage",
95-
/*508*/ "Loop Detected",
96-
/*509*/ {0, 0},
97-
/*510*/ "Not Extended",
98-
/*511*/ "Network Authentication Required",
99-
};
100-
101-
const static uint8_t LEN1xx = 4;
102-
const static uint8_t LEN2xx = 9 + LEN1xx;
103-
const static uint8_t LEN3xx = 9 + LEN2xx;
104-
const static uint8_t LEN4xx = 32 + LEN3xx;
105-
const static uint8_t LEN5xx = 12 + LEN4xx;
106-
uint8_t entries[] = {0, LEN1xx, LEN2xx, LEN3xx, LEN4xx, LEN5xx};
107-
108-
std::string_view photon::net::http::obsolete_reason(int code) {
109-
uint8_t major = code / 100 - 1;
110-
uint8_t minor = code % 100;
111-
if (unlikely(major > 4)) return {};
112-
uint8_t max = entries[major+1] - entries[major];
113-
if (unlikely(minor >= max)) return {};
114-
return code_str[entries[major] + minor];
115-
116-
/*
117-
switch (code){
118-
119-
case 100: return "Continue";
120-
case 101: return "Switching Protocols";
121-
case 102: return "Processing";
122-
case 103: return "Early Hints";
123-
124-
case 200: return "OK";
125-
case 201: return "Created";
126-
case 202: return "Accepted";
127-
case 203: return "Non-Authoritative Information";
128-
case 204: return "No Content";
129-
case 205: return "Reset Content";
130-
case 206: return "Partial Content";
131-
case 207: return "Multi-Status";
132-
case 208: return "Already Reported";
133-
case 226: return "IM Used";
134-
135-
case 300: return "Multiple Choices";
136-
case 301: return "Moved Permanently";
137-
case 302: return "Found";
138-
case 303: return "See Other";
139-
case 304: return "Not Modified";
140-
case 305: return "Use Proxy";
141-
case 307: return "Temporary Redirect";
142-
case 308: return "Permanent Redirect";
143-
144-
case 400: return "Bad Request";
145-
case 401: return "Unauthorized";
146-
case 402: return "Payment Required";
147-
case 403: return "Forbidden";
148-
case 404: return "Not Found";
149-
case 405: return "Method Not Allowed";
150-
case 406: return "Not Acceptable";
151-
case 407: return "Proxy Authentication Required";
152-
case 408: return "Request Timeout";
153-
case 409: return "Conflict";
154-
case 410: return "Gone";
155-
case 411: return "Length Required";
156-
case 412: return "Precondition Failed";
157-
case 413: return "Content Too Large";
158-
case 414: return "URI Too Long";
159-
case 415: return "Unsupported Media Type";
160-
case 416: return "Range Not Satisfiable";
161-
case 417: return "Expectation Failed";
162-
case 418: return "I'm a teapot";
163-
case 421: return "Misdirected Request";
164-
case 422: return "Unprocessable Content";
165-
case 423: return "Locked";
166-
case 424: return "Failed Dependency";
167-
case 425: return "Too Early";
168-
case 426: return "Upgrade Required";
169-
case 428: return "Precondition Required";
170-
case 429: return "Too Many Requests";
171-
case 431: return "Request Header Fields Too Large";
172-
case 451: return "Unavailable For Legal Reasons";
173-
174-
case 500: return "Internal Server Error";
175-
case 501: return "Not Implemented";
176-
case 502: return "Bad Gateway";
177-
case 503: return "Service Unavailable";
178-
case 504: return "Gateway Timeout";
179-
case 505: return "HTTP Version Not Supported";
180-
case 506: return "Variant Also Negotiates";
181-
case 507: return "Insufficient Storage";
182-
case 508: return "Loop Detected";
183-
case 510: return "Not Extended";
184-
case 511: return "Network Authentication Required";
185-
186-
default: return { };
187-
}
188-
*/
17+
#include <photon/common/conststr.h>
18+
#include <photon/common/string_view.h>
19+
#include <photon/common/utility.h>
20+
21+
namespace photon {
22+
namespace net {
23+
namespace http {
24+
25+
const static auto code_str = ConstString::make_compact_str_array<uint16_t>(
26+
/*100*/ TSTRING("Continue"),
27+
/*101*/ TSTRING("Switching Protocols"),
28+
/*102*/ TSTRING("Processing"),
29+
/*103*/ TSTRING("Early Hints"),
30+
31+
/*200*/ TSTRING("OK"),
32+
/*201*/ TSTRING("Created"),
33+
/*202*/ TSTRING("Accepted"),
34+
/*203*/ TSTRING("Non-Authoritative Information"),
35+
/*204*/ TSTRING("No Content"),
36+
/*205*/ TSTRING("Reset Content"),
37+
/*206*/ TSTRING("Partial Content"),
38+
/*207*/ TSTRING("Multi-Status"),
39+
/*208*/ TSTRING("Already Reported"),
40+
// /*226*/ TSTRING("IM Used"),
41+
42+
/*300*/ TSTRING("Multiple Choices"),
43+
/*301*/ TSTRING("Moved Permanently"),
44+
/*302*/ TSTRING("Found"),
45+
/*303*/ TSTRING("See Other"),
46+
/*304*/ TSTRING("Not Modified"),
47+
/*305*/ TSTRING("Use Proxy"),
48+
/*306*/ TSTRING(""),
49+
/*307*/ TSTRING("Temporary Redirect"),
50+
/*308*/ TSTRING("Permanent Redirect"),
51+
52+
/*400*/ TSTRING("Bad Request"),
53+
/*401*/ TSTRING("Unauthorized"),
54+
/*402*/ TSTRING("Payment Required"),
55+
/*403*/ TSTRING("Forbidden"),
56+
/*404*/ TSTRING("Not Found"),
57+
/*405*/ TSTRING("Method Not Allowed"),
58+
/*406*/ TSTRING("Not Acceptable"),
59+
/*407*/ TSTRING("Proxy Authentication Required"),
60+
/*408*/ TSTRING("Request Timeout"),
61+
/*409*/ TSTRING("Conflict"),
62+
/*410*/ TSTRING("Gone"),
63+
/*411*/ TSTRING("Length Required"),
64+
/*412*/ TSTRING("Precondition Failed"),
65+
/*413*/ TSTRING("Content Too Large"),
66+
/*414*/ TSTRING("URI Too Long"),
67+
/*415*/ TSTRING("Unsupported Media Type"),
68+
/*416*/ TSTRING("Range Not Satisfiable"),
69+
/*417*/ TSTRING("Expectation Failed"),
70+
/*418*/ TSTRING("I'm a teapot"),
71+
/*419*/ TSTRING(""),
72+
/*420*/ TSTRING(""),
73+
/*421*/ TSTRING("Misdirected Request"),
74+
/*422*/ TSTRING("Unprocessable Content"),
75+
/*423*/ TSTRING("Locked"),
76+
/*424*/ TSTRING("Failed Dependency"),
77+
/*425*/ TSTRING("Too Early"),
78+
/*426*/ TSTRING("Upgrade Required"),
79+
/*427*/ TSTRING(""),
80+
/*428*/ TSTRING("Precondition Required"),
81+
/*429*/ TSTRING("Too Many Requests"),
82+
/*430*/ TSTRING(""),
83+
/*431*/ TSTRING("Request Header Fields Too Large"),
84+
// /*451*/ TSTRING("Unavailable For Legal Reasons"),
85+
86+
/*500*/ TSTRING("Internal Server Error"),
87+
/*501*/ TSTRING("Not Implemented"),
88+
/*502*/ TSTRING("Bad Gateway"),
89+
/*503*/ TSTRING("Service Unavailable"),
90+
/*504*/ TSTRING("Gateway Timeout"),
91+
/*505*/ TSTRING("HTTP Version Not Supported"),
92+
/*506*/ TSTRING("Variant Also Negotiates"),
93+
/*507*/ TSTRING("Insufficient Storage"),
94+
/*508*/ TSTRING("Loop Detected"),
95+
/*509*/ TSTRING(""),
96+
/*510*/ TSTRING("Not Extended"),
97+
/*511*/ TSTRING("Network Authentication Required"));
98+
99+
std::string_view obsolete_reason(int code) {
100+
uint8_t major = code / 100 - 1;
101+
uint8_t minor = code % 100;
102+
constexpr static auto entries = ConstString::accumulate_helper(
103+
ConstString::TList<uint8_t, 4, 9, 9, 32, 12>());
104+
if (unlikely(major >= entries.size())) return {};
105+
auto i = entries.arr[major] + minor;
106+
if (unlikely(i >= entries.arr[major + 1])) return {};
107+
return code_str.at(i);
189108
}
109+
110+
} // namespace http
111+
} // namespace net
112+
} // namespace photon

0 commit comments

Comments
 (0)