CPPMyth
Library to interoperate with MythTV server
Loading...
Searching...
No Matches
wsstatic.c
1/*
2 * Copyright (C) 2014-2025 Jean-Luc Barriere
3 *
4 * This library is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 3, or (at your option)
7 * any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; see the file COPYING. If not, write to
16 * the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 */
21
22#include "wsstatic.h"
23
24#include <stddef.h> // for NULL
25#include <string.h> // for memcmp
26
27typedef struct { unsigned sz; const char* txt; } WS_METHOD_TABLE;
28static const WS_METHOD_TABLE ws_method_table[] = {
29 { 4, "GET" },
30 { 5, "POST" },
31 { 5, "HEAD" },
32 { 8, "OPTIONS" },
33 { 10, "SUBSCRIBE" },
34 { 12, "UNSUBSCRIBE" },
35 { 7, "NOTIFY" },
36 { 4, "PUT" },
37 { 7, "DELETE" },
38 { 6, "PATCH" },
39 { 0, NULL }
40};
41
42WS_METHOD ws_method_from_str(const char* str)
43{
44 const WS_METHOD_TABLE* p = ws_method_table;
45 while (p->txt)
46 {
47 if (memcmp(p->txt, str, p->sz) == 0)
48 return (WS_METHOD)(p - ws_method_table);
49 ++p;
50 }
51 return WS_METHOD_UNKNOWN;
52}
53
54const char* ws_method_to_str(WS_METHOD m)
55{
56 return ws_method_table[(unsigned)m].txt;
57}
58
59typedef struct { unsigned sz; const char* txt; } WS_CTYPE_TABLE;
60static const WS_CTYPE_TABLE ws_ctype_table[] = {
61 { 1, "" },
62 { 34, "application/x-www-form-urlencoded" },
63 { 25, "application/octet-stream" },
64 { 4, "*/*" },
65 { 0, NULL }
66};
67
68WS_CTYPE ws_ctype_from_str(const char* str)
69{
70 const WS_CTYPE_TABLE* p = ws_ctype_table;
71 while (p->txt)
72 {
73 if (memcmp(p->txt, str, p->sz) == 0)
74 return (WS_CTYPE)(p - ws_ctype_table);
75 ++p;
76 }
77 return WS_CTYPE_UNKNOWN;
78}
79
80const char* ws_ctype_to_str(WS_CTYPE t)
81{
82 return ws_ctype_table[(unsigned)t].txt;
83}
84
85typedef struct { unsigned sz; const char* txt; } WS_CENCODING_TABLE;
86static const WS_CENCODING_TABLE ws_cencoding_table[] = {
87 { 1, "" },
88 { 8, "deflate" },
89 { 5, "gzip" },
90 { 0, NULL }
91};
92
93WS_CENCODING ws_cencoding_from_str(const char* str)
94{
95 const WS_CENCODING_TABLE* p = ws_cencoding_table;
96 while (p->txt)
97 {
98 if (memcmp(p->txt, str, p->sz) == 0)
99 return (WS_CENCODING)(p - ws_cencoding_table);
100 ++p;
101 }
102 return WS_CENCODING_UNKNOWN;
103}
104
105const char* ws_cencoding_to_str(WS_CENCODING e)
106{
107 return ws_cencoding_table[(unsigned)e].txt;
108}
109
110typedef struct { unsigned sz; const char* txt; const char* upper_txt; } WS_HEADER_TABLE;
111static const WS_HEADER_TABLE ws_header_table[] = {
112 { 7, "Accept", "ACCEPT" },
113 { 15, "Accept-Charset", "ACCEPT-CHARSET" },
114 { 16, "Accept-Encoding", "ACCEPT-ENCODING" },
115 { 16, "Accept-Language", "ACCEPT-LANGUAGE" },
116 { 14, "Accept-Ranges", "ACCEPT-RANGES" },
117 { 14, "Authorization", "AUTHORIZATION" },
118 { 14, "Cache-Control", "CACHE-CONTROL" },
119 { 11, "Connection", "CONNECTION" },
120 { 17, "Content-Encoding", "CONTENT-ENCODING" },
121 { 15, "Content-Length", "CONTENT-LENGTH" },
122 { 17, "Content-Location", "CONTENT-LOCATION" },
123 { 15, "Content-Range", "CONTENT-RANGE" },
124 { 13, "Content-Type", "CONTENT-TYPE" },
125 { 5, "ETag", "ETAG" },
126 { 8, "Expires", "EXPIRES" },
127 { 5, "Host", "HOST" },
128 { 9, "If-Match", "IF-MATCH" },
129 { 14, "If-None-Match", "IF-NONE-MATCH" },
130 { 11, "Keep-Alive", "KEEP-ALIVE" },
131 { 14, "Last-Modified", "LAST-MODIFIED" },
132 { 9, "Location", "LOCATION" },
133 { 6, "Range", "RANGE" },
134 { 7, "Server", "SERVER" },
135 { 18, "Transfer-Encoding", "TRANSFER-ENCODING" },
136 { 11, "User-Agent", "USER-AGENT" },
137 { 17, "WWW-Authenticate", "WWW-AUTHENTICATE" },
138 { 16, "X-Forwarded-For", "X-FORWARDED-FOR" },
139 { 17, "X-Forwarded-Host", "X-FORWARDED-HOST" },
140 { 18, "X-Forwarded-Proto", "X-FORWARDED-PROTO" },
141 { 10, "X-Real-IP", "X-REAL-IP" },
142 { 0, NULL, NULL }
143};
144
145WS_HEADER ws_header_from_upperstr(const char* upperstr)
146{
147 const WS_HEADER_TABLE* p = ws_header_table;
148 while (p->upper_txt)
149 {
150 if (memcmp(p->upper_txt, upperstr, p->sz) == 0)
151 return (WS_HEADER)(p - ws_header_table);
152 ++p;
153 }
154 return WS_HEADER_UNKNOWN;
155}
156
157const char* ws_header_to_str(WS_HEADER h)
158{
159 return ws_header_table[(unsigned)h].txt;
160}
161
162const char* ws_header_to_upperstr(WS_HEADER h)
163{
164 return ws_header_table[(unsigned)h].upper_txt;
165}
166
167typedef struct { int num; unsigned sz; const char* numstr; const char* msgstr; } WS_STATUS_TABLE;
168static const WS_STATUS_TABLE ws_status_table[] = {
169 /* 2xx */
170 { 200, 4, "200", "OK" },
171 { 201, 4, "201", "Created" },
172 { 202, 4, "202", "Accepted" },
173 { 203, 4, "203", "Non-Authoritative Information" },
174 { 204, 4, "204", "No content" },
175 { 205, 4, "205", "Reset Content" },
176 { 206, 4, "206", "Partial content" },
177 { 207, 4, "207", "Multi-Status" },
178 { 208, 4, "208", "Already Reported" },
179
180 /* 3xx */
181 { 301, 4, "301", "Moved permanently" },
182 { 302, 4, "302", "Moved temporarily" },
183 { 303, 4, "303", "See Other" },
184 { 304, 4, "304", "Not modified" },
185 { 305, 4, "305", "Use Proxy" },
186 { 306, 4, "306", "RESERVED" },
187 { 307, 4, "307", "Temporary Redirect" },
188 { 308, 4, "308", "Permanent Redirect" },
189
190 /* 4xx */
191 { 400, 4, "400", "Bad request" },
192 { 401, 4, "401", "Unauthorized" },
193 { 402, 4, "402", "Payment Required" },
194 { 403, 4, "403", "Forbidden" },
195 { 404, 4, "404", "Not found" },
196 { 405, 4, "405", "Method Not Allowed" },
197 { 406, 4, "406", "Not Acceptable" },
198 { 407, 4, "407", "Proxy Authentication Required" },
199 { 408, 4, "408", "Request Timeout" },
200 { 409, 4, "409", "Conflict" },
201 { 410, 4, "410", "Gone" },
202 { 411, 4, "411", "Length Required" },
203 { 412, 4, "412", "Precondition Failed" },
204 { 413, 4, "413", "Content Too Large" },
205 { 414, 4, "414", "URI Too Long" },
206 { 415, 4, "415", "Unsupported Media Type" },
207 { 416, 4, "416", "Range Not Satisfiable" },
208 { 417, 4, "417", "Expectation Failed" },
209 { 418, 4, "418", "I'm a teapot" },
210
211 { 421, 4, "421", "Misdirected Request" },
212 { 422, 4, "422", "Unprocessable Content" },
213 { 423, 4, "423", "Locked" },
214 { 424, 4, "424", "Failed Dependency" },
215 { 425, 4, "425", "Too Early" },
216 { 426, 4, "426", "Upgrade Required" },
217
218 { 428, 4, "428", "Precondition Required" },
219 { 429, 4, "429", "Too Many Requests" },
220
221 { 431, 4, "431", "Request Header Fields Too Large" },
222
223 { 451, 4, "451", "Unavailable For Legal Reasons" },
224
225 /* 5xx */
226 { 500, 4, "500", "Internal server error" },
227 { 501, 4, "501", "Not implemented" },
228 { 502, 4, "502", "Bad gateway" },
229 { 503, 4, "503", "Service unavailable" },
230 { 504, 4, "504", "Gateway Timeout" },
231 { 505, 4, "505", "HTTP Version Not Supported" },
232 { 506, 4, "506", "Variant Also Negotiates" },
233 { 507, 4, "507", "Insufficient Storage" },
234 { 508, 4, "508", "Loop Detected" },
235
236 { 510, 4, "510", "Not Extended" },
237 { 511, 4, "511", "Network Authentication Required" },
238
239 /* 1xx */
240 { 100, 4, "100", "Continue" },
241 { 101, 4, "101", "Switching Protocols" },
242 { 102, 4, "102", "Processing" },
243 { 103, 4, "103", "Early Hints" },
244
245 { 0, 0, NULL , NULL }
246};
247
248
249WS_STATUS ws_status_from_num(int num)
250{
251 const WS_STATUS_TABLE* p = ws_status_table;
252 while (p->numstr)
253 {
254 if (p->num == num)
255 return (WS_STATUS)(p - ws_status_table);
256 ++p;
257 }
258 return WS_STATUS_UNKNOWN;
259}
260
261WS_STATUS ws_status_from_numstr(const char* numstr)
262{
263 const WS_STATUS_TABLE* p = ws_status_table;
264 while (p->numstr)
265 {
266 if (memcmp(p->numstr, numstr, p->sz) == 0)
267 return (WS_STATUS)(p - ws_status_table);
268 ++p;
269 }
270 return WS_STATUS_UNKNOWN;
271}
272
273int ws_status_to_num(WS_STATUS s)
274{
275 return ws_status_table[(unsigned) s].num;
276}
277
278const char* ws_status_to_numstr(WS_STATUS s)
279{
280 return ws_status_table[(unsigned) s].numstr;
281}
282
283const char* ws_status_to_msgstr(WS_STATUS s)
284{
285 return ws_status_table[(unsigned) s].msgstr;
286}