libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 140f4844bb2b32af23a86fa804724512636b16e3
parent bbf0a2969c28a404439af922b7a01420ebc98300
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Tue,  8 Jun 2021 18:59:14 +0300

Added new public API function MHD_get_reason_phrase_len_for()

Diffstat:
Mcontrib/gen_http_statuses_inserts.sh | 11++++++-----
Msrc/include/microhttpd.h | 11++++++++++-
Msrc/microhttpd/mhd_str.h | 12++++++++++++
Msrc/microhttpd/reason_phrase.c | 240+++++++++++++++++++++++++++++++++++++++++--------------------------------------
Msrc/microhttpd/test_http_reasons.c | 34++++++++++++++++++++++++++--------
5 files changed, 180 insertions(+), 128 deletions(-)

diff --git a/contrib/gen_http_statuses_inserts.sh b/contrib/gen_http_statuses_inserts.sh @@ -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 diff --git a/src/include/microhttpd.h b/src/include/microhttpd.h @@ -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 * @{ */ @@ -545,6 +545,15 @@ 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 * with the SHOUTcast "ICY" line instead of "HTTP". diff --git a/src/microhttpd/mhd_str.h b/src/microhttpd/mhd_str.h @@ -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. diff --git a/src/microhttpd/reason_phrase.c b/src/microhttpd/reason_phrase.c @@ -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; +} diff --git a/src/microhttpd/test_http_reasons.c b/src/microhttpd/test_http_reasons.c @@ -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; + } + 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; - fprintf (stderr, - "Incorrect reason returned for code %d:\n Returned: \"%s\" \tExpected: \"%s\"\n", - code, reason, expected); + } 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); }