Added new public API function MHD_get_reason_phrase_len_for()

This commit is contained in:
Evgeny Grin (Karlson2k)
2021-07-28 11:28:44 +03:00
parent bbf0a2969c
commit 140f4844bb
5 changed files with 180 additions and 128 deletions
+6 -5
View File
@@ -70,10 +70,10 @@ FNR > 1 {
desc = $3
if (num % 100 == 0) {
if (num != 100) {
printf (" /* %s */ %-24s /* %s */\n};\n\n", prev_num, "\""prev_reason"\"", prev_desc)
printf (" /* %s */ %-36s /* %s */\n};\n\n", prev_num, "_MHD_S_STR_W_LEN (\""prev_reason"\")", prev_desc)
}
prev_num = num;
print "static const char *const " hundreds[$1/100] "_hundred[] = {"
print "static const struct _MHD_str_w_len " hundreds[$1/100] "_hundred[] = {"
}
if (num == 306) {
reason = "Switch Proxy"
@@ -81,20 +81,21 @@ FNR > 1 {
}
if (reason == "Unassigned") next
if (prev_num != num)
printf (" /* %s */ %-24s /* %s */\n", prev_num, "\""prev_reason"\",", prev_desc)
printf (" /* %s */ %-36s /* %s */\n", prev_num, "_MHD_S_STR_W_LEN (\""prev_reason"\"),", prev_desc)
while(++prev_num < num) {
if (prev_num == 449) {prev_reason="Reply With"; prev_desc="MS IIS extension";}
else if (prev_num == 450) {prev_reason="Blocked by Windows Parental Controls"; prev_desc="MS extension";}
else if (prev_num == 509) {prev_reason="Bandwidth Limit Exceeded"; prev_desc="Apache extension";}
else {prev_reason="Unknown"; prev_desc="Not used";}
printf (" /* %s */ %-24s /* %s */\n", prev_num, "\""prev_reason"\",", prev_desc)
if (prev_reason=="Unknown") printf (" /* %s */ %-36s /* %s */\n", prev_num, "{\""prev_reason"\", 0},", prev_desc)
else printf (" /* %s */ %-36s /* %s */\n", prev_num, "_MHD_S_STR_W_LEN (\""prev_reason"\"),", prev_desc)
}
prev_num = num
prev_reason = reason
prev_desc = desc
}
END {
printf (" /* %s */ %-24s /* %s */\n};\n", prev_num, "\""prev_reason"\"", prev_desc)
printf (" /* %s */ %-36s /* %s */\n};\n", prev_num, "_MHD_S_STR_W_LEN (\""prev_reason"\")", prev_desc)
}' http-status-codes-1.csv > code_insert_statuses.c && \
echo OK && \
rm http-status-codes-1.csv || exit
+10 -1
View File
@@ -343,7 +343,7 @@ _MHD_DEPR_MACRO (
* @defgroup httpcode HTTP response codes.
* These are the status codes defined for HTTP responses.
* See: https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
* Registry export date: 2019-06-09
* Registry export date: 2021-06-08
* @{
*/
@@ -544,6 +544,15 @@ _MHD_EXTERN const char *
MHD_get_reason_phrase_for (unsigned int code);
/**
* Returns the length of the string reason phrase for a response code.
*
* If message string is not available for a status code,
* 0 is returned.
*/
_MHD_EXTERN size_t
MHD_get_reason_phrase_len_for (unsigned int code);
/**
* Flag to be or-ed with MHD_HTTP status code for
* SHOUTcast. This will cause the response to begin
+12
View File
@@ -50,6 +50,18 @@ typedef intptr_t ssize_t;
#define MHD_STATICSTR_LEN_(macro) (sizeof(macro) / sizeof(char) - 1)
#endif /* ! MHD_STATICSTR_LEN_ */
struct _MHD_str_w_len
{
const char *str;
const size_t len;
};
/**
* Static string initialiser for struct _MHD_str_w_len
*/
#define _MHD_S_STR_W_LEN(str) { str, MHD_STATICSTR_LEN_(str) }
/*
* Block of functions/macros that use US-ASCII charset as required by HTTP
* standards. Not affected by current locale settings.
+126 -114
View File
@@ -26,142 +26,143 @@
*/
#include "platform.h"
#include "microhttpd.h"
#include "mhd_str.h"
#ifndef NULL
#define NULL ((void*) 0)
#endif
static const char *const invalid_hundred[] = {
NULL
static const struct _MHD_str_w_len invalid_hundred[] = {
{ NULL, 0 }
};
static const char *const one_hundred[] = {
/* 100 */ "Continue", /* RFC7231, Section 6.2.1 */
/* 101 */ "Switching Protocols", /* RFC7231, Section 6.2.2 */
/* 102 */ "Processing", /* RFC2518 */
/* 103 */ "Early Hints" /* RFC8297 */
static const struct _MHD_str_w_len one_hundred[] = {
/* 100 */ _MHD_S_STR_W_LEN ("Continue"), /* RFC7231, Section 6.2.1 */
/* 101 */ _MHD_S_STR_W_LEN ("Switching Protocols"), /* RFC7231, Section 6.2.2 */
/* 102 */ _MHD_S_STR_W_LEN ("Processing"), /* RFC2518 */
/* 103 */ _MHD_S_STR_W_LEN ("Early Hints") /* RFC8297 */
};
static const char *const two_hundred[] = {
/* 200 */ "OK", /* RFC7231, Section 6.3.1 */
/* 201 */ "Created", /* RFC7231, Section 6.3.2 */
/* 202 */ "Accepted", /* RFC7231, Section 6.3.3 */
/* 203 */ "Non-Authoritative Information", /* RFC7231, Section 6.3.4 */
/* 204 */ "No Content", /* RFC7231, Section 6.3.5 */
/* 205 */ "Reset Content", /* RFC7231, Section 6.3.6 */
/* 206 */ "Partial Content", /* RFC7233, Section 4.1 */
/* 207 */ "Multi-Status", /* RFC4918 */
/* 208 */ "Already Reported", /* RFC5842 */
/* 209 */ "Unknown", /* Not used */
/* 210 */ "Unknown", /* Not used */
/* 211 */ "Unknown", /* Not used */
/* 212 */ "Unknown", /* Not used */
/* 213 */ "Unknown", /* Not used */
/* 214 */ "Unknown", /* Not used */
/* 215 */ "Unknown", /* Not used */
/* 216 */ "Unknown", /* Not used */
/* 217 */ "Unknown", /* Not used */
/* 218 */ "Unknown", /* Not used */
/* 219 */ "Unknown", /* Not used */
/* 220 */ "Unknown", /* Not used */
/* 221 */ "Unknown", /* Not used */
/* 222 */ "Unknown", /* Not used */
/* 223 */ "Unknown", /* Not used */
/* 224 */ "Unknown", /* Not used */
/* 225 */ "Unknown", /* Not used */
/* 226 */ "IM Used" /* RFC3229 */
static const struct _MHD_str_w_len two_hundred[] = {
/* 200 */ _MHD_S_STR_W_LEN ("OK"), /* RFC7231, Section 6.3.1 */
/* 201 */ _MHD_S_STR_W_LEN ("Created"), /* RFC7231, Section 6.3.2 */
/* 202 */ _MHD_S_STR_W_LEN ("Accepted"), /* RFC7231, Section 6.3.3 */
/* 203 */ _MHD_S_STR_W_LEN ("Non-Authoritative Information"), /* RFC7231, Section 6.3.4 */
/* 204 */ _MHD_S_STR_W_LEN ("No Content"), /* RFC7231, Section 6.3.5 */
/* 205 */ _MHD_S_STR_W_LEN ("Reset Content"), /* RFC7231, Section 6.3.6 */
/* 206 */ _MHD_S_STR_W_LEN ("Partial Content"), /* RFC7233, Section 4.1 */
/* 207 */ _MHD_S_STR_W_LEN ("Multi-Status"), /* RFC4918 */
/* 208 */ _MHD_S_STR_W_LEN ("Already Reported"), /* RFC5842 */
/* 209 */ {"Unknown", 0}, /* Not used */
/* 210 */ {"Unknown", 0}, /* Not used */
/* 211 */ {"Unknown", 0}, /* Not used */
/* 212 */ {"Unknown", 0}, /* Not used */
/* 213 */ {"Unknown", 0}, /* Not used */
/* 214 */ {"Unknown", 0}, /* Not used */
/* 215 */ {"Unknown", 0}, /* Not used */
/* 216 */ {"Unknown", 0}, /* Not used */
/* 217 */ {"Unknown", 0}, /* Not used */
/* 218 */ {"Unknown", 0}, /* Not used */
/* 219 */ {"Unknown", 0}, /* Not used */
/* 220 */ {"Unknown", 0}, /* Not used */
/* 221 */ {"Unknown", 0}, /* Not used */
/* 222 */ {"Unknown", 0}, /* Not used */
/* 223 */ {"Unknown", 0}, /* Not used */
/* 224 */ {"Unknown", 0}, /* Not used */
/* 225 */ {"Unknown", 0}, /* Not used */
/* 226 */ _MHD_S_STR_W_LEN ("IM Used") /* RFC3229 */
};
static const char *const three_hundred[] = {
/* 300 */ "Multiple Choices", /* RFC7231, Section 6.4.1 */
/* 301 */ "Moved Permanently", /* RFC7231, Section 6.4.2 */
/* 302 */ "Found", /* RFC7231, Section 6.4.3 */
/* 303 */ "See Other", /* RFC7231, Section 6.4.4 */
/* 304 */ "Not Modified", /* RFC7232, Section 4.1 */
/* 305 */ "Use Proxy", /* RFC7231, Section 6.4.5 */
/* 306 */ "Switch Proxy", /* Not used! RFC7231, Section 6.4.6 */
/* 307 */ "Temporary Redirect", /* RFC7231, Section 6.4.7 */
/* 308 */ "Permanent Redirect" /* RFC7538 */
static const struct _MHD_str_w_len three_hundred[] = {
/* 300 */ _MHD_S_STR_W_LEN ("Multiple Choices"), /* RFC7231, Section 6.4.1 */
/* 301 */ _MHD_S_STR_W_LEN ("Moved Permanently"), /* RFC7231, Section 6.4.2 */
/* 302 */ _MHD_S_STR_W_LEN ("Found"), /* RFC7231, Section 6.4.3 */
/* 303 */ _MHD_S_STR_W_LEN ("See Other"), /* RFC7231, Section 6.4.4 */
/* 304 */ _MHD_S_STR_W_LEN ("Not Modified"), /* RFC7232, Section 4.1 */
/* 305 */ _MHD_S_STR_W_LEN ("Use Proxy"), /* RFC7231, Section 6.4.5 */
/* 306 */ _MHD_S_STR_W_LEN ("Switch Proxy"), /* Not used! RFC7231, Section 6.4.6 */
/* 307 */ _MHD_S_STR_W_LEN ("Temporary Redirect"), /* RFC7231, Section 6.4.7 */
/* 308 */ _MHD_S_STR_W_LEN ("Permanent Redirect") /* RFC7538 */
};
static const char *const four_hundred[] = {
/* 400 */ "Bad Request", /* RFC7231, Section 6.5.1 */
/* 401 */ "Unauthorized", /* RFC7235, Section 3.1 */
/* 402 */ "Payment Required", /* RFC7231, Section 6.5.2 */
/* 403 */ "Forbidden", /* RFC7231, Section 6.5.3 */
/* 404 */ "Not Found", /* RFC7231, Section 6.5.4 */
/* 405 */ "Method Not Allowed", /* RFC7231, Section 6.5.5 */
/* 406 */ "Not Acceptable", /* RFC7231, Section 6.5.6 */
/* 407 */ "Proxy Authentication Required", /* RFC7235, Section 3.2 */
/* 408 */ "Request Timeout", /* RFC7231, Section 6.5.7 */
/* 409 */ "Conflict", /* RFC7231, Section 6.5.8 */
/* 410 */ "Gone", /* RFC7231, Section 6.5.9 */
/* 411 */ "Length Required", /* RFC7231, Section 6.5.10 */
/* 412 */ "Precondition Failed", /* RFC7232, Section 4.2; RFC8144, Section 3.2 */
/* 413 */ "Payload Too Large", /* RFC7231, Section 6.5.11 */
/* 414 */ "URI Too Long", /* RFC7231, Section 6.5.12 */
/* 415 */ "Unsupported Media Type", /* RFC7231, Section 6.5.13; RFC7694, Section 3 */
/* 416 */ "Range Not Satisfiable", /* RFC7233, Section 4.4 */
/* 417 */ "Expectation Failed", /* RFC7231, Section 6.5.14 */
/* 418 */ "Unknown", /* Not used */
/* 419 */ "Unknown", /* Not used */
/* 420 */ "Unknown", /* Not used */
/* 421 */ "Misdirected Request", /* RFC7540, Section 9.1.2 */
/* 422 */ "Unprocessable Entity", /* RFC4918 */
/* 423 */ "Locked", /* RFC4918 */
/* 424 */ "Failed Dependency", /* RFC4918 */
/* 425 */ "Too Early", /* RFC8470 */
/* 426 */ "Upgrade Required", /* RFC7231, Section 6.5.15 */
/* 427 */ "Unknown", /* Not used */
/* 428 */ "Precondition Required", /* RFC6585 */
/* 429 */ "Too Many Requests", /* RFC6585 */
/* 430 */ "Unknown", /* Not used */
/* 431 */ "Request Header Fields Too Large", /* RFC6585 */
/* 432 */ "Unknown", /* Not used */
/* 433 */ "Unknown", /* Not used */
/* 434 */ "Unknown", /* Not used */
/* 435 */ "Unknown", /* Not used */
/* 436 */ "Unknown", /* Not used */
/* 437 */ "Unknown", /* Not used */
/* 438 */ "Unknown", /* Not used */
/* 439 */ "Unknown", /* Not used */
/* 440 */ "Unknown", /* Not used */
/* 441 */ "Unknown", /* Not used */
/* 442 */ "Unknown", /* Not used */
/* 443 */ "Unknown", /* Not used */
/* 444 */ "Unknown", /* Not used */
/* 445 */ "Unknown", /* Not used */
/* 446 */ "Unknown", /* Not used */
/* 447 */ "Unknown", /* Not used */
/* 448 */ "Unknown", /* Not used */
/* 449 */ "Reply With", /* MS IIS extension */
/* 450 */ "Blocked by Windows Parental Controls", /* MS extension */
/* 451 */ "Unavailable For Legal Reasons" /* RFC7725 */
static const struct _MHD_str_w_len four_hundred[] = {
/* 400 */ _MHD_S_STR_W_LEN ("Bad Request"), /* RFC7231, Section 6.5.1 */
/* 401 */ _MHD_S_STR_W_LEN ("Unauthorized"), /* RFC7235, Section 3.1 */
/* 402 */ _MHD_S_STR_W_LEN ("Payment Required"), /* RFC7231, Section 6.5.2 */
/* 403 */ _MHD_S_STR_W_LEN ("Forbidden"), /* RFC7231, Section 6.5.3 */
/* 404 */ _MHD_S_STR_W_LEN ("Not Found"), /* RFC7231, Section 6.5.4 */
/* 405 */ _MHD_S_STR_W_LEN ("Method Not Allowed"), /* RFC7231, Section 6.5.5 */
/* 406 */ _MHD_S_STR_W_LEN ("Not Acceptable"), /* RFC7231, Section 6.5.6 */
/* 407 */ _MHD_S_STR_W_LEN ("Proxy Authentication Required"), /* RFC7235, Section 3.2 */
/* 408 */ _MHD_S_STR_W_LEN ("Request Timeout"), /* RFC7231, Section 6.5.7 */
/* 409 */ _MHD_S_STR_W_LEN ("Conflict"), /* RFC7231, Section 6.5.8 */
/* 410 */ _MHD_S_STR_W_LEN ("Gone"), /* RFC7231, Section 6.5.9 */
/* 411 */ _MHD_S_STR_W_LEN ("Length Required"), /* RFC7231, Section 6.5.10 */
/* 412 */ _MHD_S_STR_W_LEN ("Precondition Failed"), /* RFC7232, Section 4.2; RFC8144, Section 3.2 */
/* 413 */ _MHD_S_STR_W_LEN ("Payload Too Large"), /* RFC7231, Section 6.5.11 */
/* 414 */ _MHD_S_STR_W_LEN ("URI Too Long"), /* RFC7231, Section 6.5.12 */
/* 415 */ _MHD_S_STR_W_LEN ("Unsupported Media Type"), /* RFC7231, Section 6.5.13; RFC7694, Section 3 */
/* 416 */ _MHD_S_STR_W_LEN ("Range Not Satisfiable"), /* RFC7233, Section 4.4 */
/* 417 */ _MHD_S_STR_W_LEN ("Expectation Failed"), /* RFC7231, Section 6.5.14 */
/* 418 */ {"Unknown", 0}, /* Not used */
/* 419 */ {"Unknown", 0}, /* Not used */
/* 420 */ {"Unknown", 0}, /* Not used */
/* 421 */ _MHD_S_STR_W_LEN ("Misdirected Request"), /* RFC7540, Section 9.1.2 */
/* 422 */ _MHD_S_STR_W_LEN ("Unprocessable Entity"), /* RFC4918 */
/* 423 */ _MHD_S_STR_W_LEN ("Locked"), /* RFC4918 */
/* 424 */ _MHD_S_STR_W_LEN ("Failed Dependency"), /* RFC4918 */
/* 425 */ _MHD_S_STR_W_LEN ("Too Early"), /* RFC8470 */
/* 426 */ _MHD_S_STR_W_LEN ("Upgrade Required"), /* RFC7231, Section 6.5.15 */
/* 427 */ {"Unknown", 0}, /* Not used */
/* 428 */ _MHD_S_STR_W_LEN ("Precondition Required"), /* RFC6585 */
/* 429 */ _MHD_S_STR_W_LEN ("Too Many Requests"), /* RFC6585 */
/* 430 */ {"Unknown", 0}, /* Not used */
/* 431 */ _MHD_S_STR_W_LEN ("Request Header Fields Too Large"), /* RFC6585 */
/* 432 */ {"Unknown", 0}, /* Not used */
/* 433 */ {"Unknown", 0}, /* Not used */
/* 434 */ {"Unknown", 0}, /* Not used */
/* 435 */ {"Unknown", 0}, /* Not used */
/* 436 */ {"Unknown", 0}, /* Not used */
/* 437 */ {"Unknown", 0}, /* Not used */
/* 438 */ {"Unknown", 0}, /* Not used */
/* 439 */ {"Unknown", 0}, /* Not used */
/* 440 */ {"Unknown", 0}, /* Not used */
/* 441 */ {"Unknown", 0}, /* Not used */
/* 442 */ {"Unknown", 0}, /* Not used */
/* 443 */ {"Unknown", 0}, /* Not used */
/* 444 */ {"Unknown", 0}, /* Not used */
/* 445 */ {"Unknown", 0}, /* Not used */
/* 446 */ {"Unknown", 0}, /* Not used */
/* 447 */ {"Unknown", 0}, /* Not used */
/* 448 */ {"Unknown", 0}, /* Not used */
/* 449 */ _MHD_S_STR_W_LEN ("Reply With"), /* MS IIS extension */
/* 450 */ _MHD_S_STR_W_LEN ("Blocked by Windows Parental Controls"), /* MS extension */
/* 451 */ _MHD_S_STR_W_LEN ("Unavailable For Legal Reasons") /* RFC7725 */
};
static const char *const five_hundred[] = {
/* 500 */ "Internal Server Error", /* RFC7231, Section 6.6.1 */
/* 501 */ "Not Implemented", /* RFC7231, Section 6.6.2 */
/* 502 */ "Bad Gateway", /* RFC7231, Section 6.6.3 */
/* 503 */ "Service Unavailable", /* RFC7231, Section 6.6.4 */
/* 504 */ "Gateway Timeout", /* RFC7231, Section 6.6.5 */
/* 505 */ "HTTP Version Not Supported", /* RFC7231, Section 6.6.6 */
/* 506 */ "Variant Also Negotiates", /* RFC2295 */
/* 507 */ "Insufficient Storage", /* RFC4918 */
/* 508 */ "Loop Detected", /* RFC5842 */
/* 509 */ "Bandwidth Limit Exceeded", /* Apache extension */
/* 510 */ "Not Extended", /* RFC2774 */
/* 511 */ "Network Authentication Required" /* RFC6585 */
static const struct _MHD_str_w_len five_hundred[] = {
/* 500 */ _MHD_S_STR_W_LEN ("Internal Server Error"), /* RFC7231, Section 6.6.1 */
/* 501 */ _MHD_S_STR_W_LEN ("Not Implemented"), /* RFC7231, Section 6.6.2 */
/* 502 */ _MHD_S_STR_W_LEN ("Bad Gateway"), /* RFC7231, Section 6.6.3 */
/* 503 */ _MHD_S_STR_W_LEN ("Service Unavailable"), /* RFC7231, Section 6.6.4 */
/* 504 */ _MHD_S_STR_W_LEN ("Gateway Timeout"), /* RFC7231, Section 6.6.5 */
/* 505 */ _MHD_S_STR_W_LEN ("HTTP Version Not Supported"), /* RFC7231, Section 6.6.6 */
/* 506 */ _MHD_S_STR_W_LEN ("Variant Also Negotiates"), /* RFC2295 */
/* 507 */ _MHD_S_STR_W_LEN ("Insufficient Storage"), /* RFC4918 */
/* 508 */ _MHD_S_STR_W_LEN ("Loop Detected"), /* RFC5842 */
/* 509 */ _MHD_S_STR_W_LEN ("Bandwidth Limit Exceeded"), /* Apache extension */
/* 510 */ _MHD_S_STR_W_LEN ("Not Extended"), /* RFC2774 */
/* 511 */ _MHD_S_STR_W_LEN ("Network Authentication Required") /* RFC6585 */
};
struct MHD_Reason_Block
{
size_t max;
const char *const*data;
const struct _MHD_str_w_len *const data;
};
#define BLOCK(m) { (sizeof(m) / sizeof(char*)), m }
#define BLOCK(m) { (sizeof(m) / sizeof(m[0])), m }
static const struct MHD_Reason_Block reasons[] = {
BLOCK (invalid_hundred),
@@ -179,6 +180,17 @@ MHD_get_reason_phrase_for (unsigned int code)
if ( (code >= 100) &&
(code < 600) &&
(reasons[code / 100].max > (code % 100)) )
return reasons[code / 100].data[code % 100];
return reasons[code / 100].data[code % 100].str;
return "Unknown";
}
size_t
MHD_get_reason_phrase_len_for (unsigned int code)
{
if ( (code >= 100) &&
(code < 600) &&
(reasons[code / 100].max > (code % 100)) )
return reasons[code / 100].data[code % 100].len;
return 0;
}
+26 -8
View File
@@ -1,6 +1,6 @@
/*
This file is part of libmicrohttpd
Copyright (C) 2017 Karlson2k (Evgeny Grin)
Copyright (C) 2017-2021 Karlson2k (Evgeny Grin)
This test tool is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -25,18 +25,36 @@
#include "mhd_options.h"
#include <stdio.h>
#include <string.h>
#include "microhttpd.h"
#include "mhd_str.h"
static const char *const r_unknown = "unknown";
static int
expect_result (int code, const char*expected)
expect_result (int code, const char *expected)
{
const char*const reason = MHD_get_reason_phrase_for (code);
if (MHD_str_equal_caseless_ (reason, expected))
const char *const reason = MHD_get_reason_phrase_for (code);
const size_t len = MHD_get_reason_phrase_len_for (code);
size_t exp_len;
if (! MHD_str_equal_caseless_ (reason, expected))
{
fprintf (stderr,
"Incorrect reason returned for code %d:\n Returned: \"%s\" \tExpected: \"%s\"\n",
code, reason, expected);
return 0;
fprintf (stderr,
"Incorrect reason returned for code %d:\n Returned: \"%s\" \tExpected: \"%s\"\n",
code, reason, expected);
}
if (r_unknown == expected)
exp_len = 0;
else
exp_len = strlen (expected);
if (exp_len != len)
{
fprintf (stderr,
"Incorrect reason length returned for code %d:\n Returned: \"%u\" \tExpected: \"%u\"\n",
code, (unsigned) len, (unsigned) exp_len);
return 0;
}
return 1;
}
@@ -44,7 +62,7 @@ expect_result (int code, const char*expected)
static int
expect_absent (int code)
{
return expect_result (code, "unknown");
return expect_result (code, r_unknown);
}