Skip to content

Commit e20cbdb

Browse files
Unify HTTP status code maps
1 parent dca2e96 commit e20cbdb

File tree

6 files changed

+99
-164
lines changed

6 files changed

+99
-164
lines changed

ext/standard/tests/general_functions/header_redirection_001.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ Location: headers change the status code
66
header('Location: http://example.com/');
77
?>
88
--EXPECTHEADERS--
9-
Status: 302 Moved Temporarily
9+
Status: 302 Found
1010
Location: http://example.com/
1111
--EXPECT--

ext/standard/tests/general_functions/header_redirection_002.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ header("HTTP/1.1 418 I'm a Teapot");
77
header('Location: http://example.com/');
88
?>
99
--EXPECTHEADERS--
10-
Status: 302 Moved Temporarily
10+
Status: 302 Found
1111
Location: http://example.com/
1212
--EXPECT--

main/http_status_codes.h

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
+----------------------------------------------------------------------+
3+
| PHP Version 7 |
4+
+----------------------------------------------------------------------+
5+
| Copyright (c) 1997-2014 The PHP Group |
6+
+----------------------------------------------------------------------+
7+
| This source file is subject to version 3.01 of the PHP license, |
8+
| that is bundled with this package in the file LICENSE, and is |
9+
| available through the world-wide-web at the following url: |
10+
| http://www.php.net/license/3_01.txt |
11+
| If you did not receive a copy of the PHP license and are unable to |
12+
| obtain it through the world-wide-web, please send a note to |
13+
| license@php.net so we can mail you a copy immediately. |
14+
+----------------------------------------------------------------------+
15+
| Author: Andrea Faulds <ajf@ajf.me> |
16+
+----------------------------------------------------------------------+
17+
*/
18+
19+
/* $Id: $ */
20+
21+
#ifndef HTTP_STATUS_CODES_H
22+
#define HTTP_STATUS_CODES_H
23+
24+
typedef struct _http_response_status_code_pair {
25+
const int code;
26+
const char *str;
27+
} http_response_status_code_pair;
28+
29+
static http_response_status_code_pair http_status_map[] = {
30+
{ 100, "Continue" },
31+
{ 101, "Switching Protocols" },
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+
{ 300, "Multiple Choices" },
40+
{ 301, "Moved Permanently" },
41+
{ 302, "Found" },
42+
{ 303, "See Other" },
43+
{ 304, "Not Modified" },
44+
{ 305, "Use Proxy" },
45+
{ 307, "Temporary Redirect" },
46+
{ 308, "Permanent Redirect" },
47+
{ 400, "Bad Request" },
48+
{ 401, "Unauthorized" },
49+
{ 402, "Payment Required" },
50+
{ 403, "Forbidden" },
51+
{ 404, "Not Found" },
52+
{ 405, "Method Not Allowed" },
53+
{ 406, "Not Acceptable" },
54+
{ 407, "Proxy Authentication Required" },
55+
{ 408, "Request Timeout" },
56+
{ 409, "Conflict" },
57+
{ 410, "Gone" },
58+
{ 411, "Length Required" },
59+
{ 412, "Precondition Failed" },
60+
{ 413, "Request Entity Too Large" },
61+
{ 414, "Request-URI Too Long" },
62+
{ 415, "Unsupported Media Type" },
63+
{ 416, "Requested Range Not Satisfiable" },
64+
{ 417, "Expectation Failed" },
65+
{ 426, "Upgrade Required" },
66+
{ 428, "Precondition Required" },
67+
{ 429, "Too Many Requests" },
68+
{ 431, "Request Header Fields Too Large" },
69+
{ 500, "Internal Server Error" },
70+
{ 501, "Not Implemented" },
71+
{ 502, "Bad Gateway" },
72+
{ 503, "Service Unavailable" },
73+
{ 504, "Gateway Timeout" },
74+
{ 505, "HTTP Version Not Supported" },
75+
{ 511, "Network Authentication Required" },
76+
/* to allow search with while() loop */
77+
{ 0, NULL }
78+
};
79+
80+
static const size_t http_status_map_len = (sizeof(http_status_map) / sizeof(http_response_status_code_pair)) - 1;
81+
82+
#endif /* HTTP_STATUS_CODES_H */

sapi/cgi/cgi_main.c

Lines changed: 4 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
#include "php_globals.h"
7070
#include "php_main.h"
7171
#include "fopen_wrappers.h"
72+
#include "http_status_codes.h"
7273
#include "ext/standard/php_standard.h"
7374
#include "ext/standard/url.h"
7475

@@ -353,56 +354,6 @@ static void sapi_fcgi_flush(void *server_context)
353354

354355
#define SAPI_CGI_MAX_HEADER_LENGTH 1024
355356

356-
typedef struct _http_error {
357-
int code;
358-
const char* msg;
359-
} http_error;
360-
361-
static const http_error http_error_codes[] = {
362-
{100, "Continue"},
363-
{101, "Switching Protocols"},
364-
{200, "OK"},
365-
{201, "Created"},
366-
{202, "Accepted"},
367-
{203, "Non-Authoritative Information"},
368-
{204, "No Content"},
369-
{205, "Reset Content"},
370-
{206, "Partial Content"},
371-
{300, "Multiple Choices"},
372-
{301, "Moved Permanently"},
373-
{302, "Moved Temporarily"},
374-
{303, "See Other"},
375-
{304, "Not Modified"},
376-
{305, "Use Proxy"},
377-
{400, "Bad Request"},
378-
{401, "Unauthorized"},
379-
{402, "Payment Required"},
380-
{403, "Forbidden"},
381-
{404, "Not Found"},
382-
{405, "Method Not Allowed"},
383-
{406, "Not Acceptable"},
384-
{407, "Proxy Authentication Required"},
385-
{408, "Request Time-out"},
386-
{409, "Conflict"},
387-
{410, "Gone"},
388-
{411, "Length Required"},
389-
{412, "Precondition Failed"},
390-
{413, "Request Entity Too Large"},
391-
{414, "Request-URI Too Large"},
392-
{415, "Unsupported Media Type"},
393-
{428, "Precondition Required"},
394-
{429, "Too Many Requests"},
395-
{431, "Request Header Fields Too Large"},
396-
{500, "Internal Server Error"},
397-
{501, "Not Implemented"},
398-
{502, "Bad Gateway"},
399-
{503, "Service Unavailable"},
400-
{504, "Gateway Time-out"},
401-
{505, "HTTP Version not supported"},
402-
{511, "Network Authentication Required"},
403-
{0, NULL}
404-
};
405-
406357
static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers)
407358
{
408359
char buf[SAPI_CGI_MAX_HEADER_LENGTH];
@@ -453,16 +404,16 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers)
453404
h = (sapi_header_struct*)zend_llist_get_next_ex(&sapi_headers->headers, &pos);
454405
}
455406
if (!has_status) {
456-
http_error *err = (http_error*)http_error_codes;
407+
http_response_status_code_pair *err = (http_response_status_code_pair*)http_status_map;
457408

458409
while (err->code != 0) {
459410
if (err->code == SG(sapi_headers).http_response_code) {
460411
break;
461412
}
462413
err++;
463414
}
464-
if (err->msg) {
465-
len = slprintf(buf, sizeof(buf), "Status: %d %s\r\n", SG(sapi_headers).http_response_code, err->msg);
415+
if (err->str) {
416+
len = slprintf(buf, sizeof(buf), "Status: %d %s\r\n", SG(sapi_headers).http_response_code, err->str);
466417
} else {
467418
len = slprintf(buf, sizeof(buf), "Status: %d\r\n", SG(sapi_headers).http_response_code);
468419
}

sapi/cli/php_cli_server.c

Lines changed: 6 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
#include "zend_hash.h"
6969
#include "zend_modules.h"
7070
#include "fopen_wrappers.h"
71+
#include "http_status_codes.h"
7172

7273
#include "zend_compile.h"
7374
#include "zend_execute.h"
@@ -203,55 +204,6 @@ typedef struct php_cli_server_http_response_status_code_pair {
203204
const char *str;
204205
} php_cli_server_http_response_status_code_pair;
205206

206-
static php_cli_server_http_response_status_code_pair status_map[] = {
207-
{ 100, "Continue" },
208-
{ 101, "Switching Protocols" },
209-
{ 200, "OK" },
210-
{ 201, "Created" },
211-
{ 202, "Accepted" },
212-
{ 203, "Non-Authoritative Information" },
213-
{ 204, "No Content" },
214-
{ 205, "Reset Content" },
215-
{ 206, "Partial Content" },
216-
{ 300, "Multiple Choices" },
217-
{ 301, "Moved Permanently" },
218-
{ 302, "Found" },
219-
{ 303, "See Other" },
220-
{ 304, "Not Modified" },
221-
{ 305, "Use Proxy" },
222-
{ 307, "Temporary Redirect" },
223-
{ 308, "Permanent Redirect" },
224-
{ 400, "Bad Request" },
225-
{ 401, "Unauthorized" },
226-
{ 402, "Payment Required" },
227-
{ 403, "Forbidden" },
228-
{ 404, "Not Found" },
229-
{ 405, "Method Not Allowed" },
230-
{ 406, "Not Acceptable" },
231-
{ 407, "Proxy Authentication Required" },
232-
{ 408, "Request Timeout" },
233-
{ 409, "Conflict" },
234-
{ 410, "Gone" },
235-
{ 411, "Length Required" },
236-
{ 412, "Precondition Failed" },
237-
{ 413, "Request Entity Too Large" },
238-
{ 414, "Request-URI Too Long" },
239-
{ 415, "Unsupported Media Type" },
240-
{ 416, "Requested Range Not Satisfiable" },
241-
{ 417, "Expectation Failed" },
242-
{ 426, "Upgrade Required" },
243-
{ 428, "Precondition Required" },
244-
{ 429, "Too Many Requests" },
245-
{ 431, "Request Header Fields Too Large" },
246-
{ 500, "Internal Server Error" },
247-
{ 501, "Not Implemented" },
248-
{ 502, "Bad Gateway" },
249-
{ 503, "Service Unavailable" },
250-
{ 504, "Gateway Timeout" },
251-
{ 505, "HTTP Version Not Supported" },
252-
{ 511, "Network Authentication Required" },
253-
};
254-
255207
static php_cli_server_http_response_status_code_pair template_map[] = {
256208
{ 400, "<h1>%s</h1><p>Your browser sent a request that this server could not understand.</p>" },
257209
{ 404, "<h1>%s</h1><p>The requested resource <code class=\"url\">%s</code> was not found on this server.</p>" },
@@ -324,8 +276,8 @@ static char *get_last_error() /* {{{ */
324276

325277
static int status_comp(const void *a, const void *b) /* {{{ */
326278
{
327-
const php_cli_server_http_response_status_code_pair *pa = (const php_cli_server_http_response_status_code_pair *) a;
328-
const php_cli_server_http_response_status_code_pair *pb = (const php_cli_server_http_response_status_code_pair *) b;
279+
const http_response_status_code_pair *pa = (const http_response_status_code_pair *) a;
280+
const http_response_status_code_pair *pb = (const http_response_status_code_pair *) b;
329281

330282
if (pa->code < pb->code) {
331283
return -1;
@@ -338,12 +290,10 @@ static int status_comp(const void *a, const void *b) /* {{{ */
338290

339291
static const char *get_status_string(int code) /* {{{ */
340292
{
341-
php_cli_server_http_response_status_code_pair needle, *result = NULL;
342-
343-
needle.code = code;
344-
needle.str = NULL;
293+
http_response_status_code_pair needle = {code, NULL},
294+
*result = NULL;
345295

346-
result = bsearch(&needle, status_map, sizeof(status_map) / sizeof(needle), sizeof(needle), status_comp);
296+
result = bsearch(&needle, http_status_map, http_status_map_len, sizeof(needle), status_comp);
347297

348298
if (result) {
349299
return result->str;

sapi/fpm/fpm/fpm_main.c

Lines changed: 5 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ int __riscosify_control = __RISCOSIFY_STRICT_UNIX_SPECS;
9797

9898
#include "php_getopt.h"
9999

100+
#include "http_status_codes.h"
101+
100102
#include "fastcgi.h"
101103

102104
#include <php_config.h>
@@ -341,56 +343,6 @@ static void sapi_cgibin_flush(void *server_context)
341343

342344
#define SAPI_CGI_MAX_HEADER_LENGTH 1024
343345

344-
typedef struct _http_error {
345-
int code;
346-
const char* msg;
347-
} http_error;
348-
349-
static const http_error http_error_codes[] = {
350-
{100, "Continue"},
351-
{101, "Switching Protocols"},
352-
{200, "OK"},
353-
{201, "Created"},
354-
{202, "Accepted"},
355-
{203, "Non-Authoritative Information"},
356-
{204, "No Content"},
357-
{205, "Reset Content"},
358-
{206, "Partial Content"},
359-
{300, "Multiple Choices"},
360-
{301, "Moved Permanently"},
361-
{302, "Moved Temporarily"},
362-
{303, "See Other"},
363-
{304, "Not Modified"},
364-
{305, "Use Proxy"},
365-
{400, "Bad Request"},
366-
{401, "Unauthorized"},
367-
{402, "Payment Required"},
368-
{403, "Forbidden"},
369-
{404, "Not Found"},
370-
{405, "Method Not Allowed"},
371-
{406, "Not Acceptable"},
372-
{407, "Proxy Authentication Required"},
373-
{408, "Request Time-out"},
374-
{409, "Conflict"},
375-
{410, "Gone"},
376-
{411, "Length Required"},
377-
{412, "Precondition Failed"},
378-
{413, "Request Entity Too Large"},
379-
{414, "Request-URI Too Large"},
380-
{415, "Unsupported Media Type"},
381-
{428, "Precondition Required"},
382-
{429, "Too Many Requests"},
383-
{431, "Request Header Fields Too Large"},
384-
{500, "Internal Server Error"},
385-
{501, "Not Implemented"},
386-
{502, "Bad Gateway"},
387-
{503, "Service Unavailable"},
388-
{504, "Gateway Time-out"},
389-
{505, "HTTP Version not supported"},
390-
{511, "Network Authentication Required"},
391-
{0, NULL}
392-
};
393-
394346
static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers)
395347
{
396348
char buf[SAPI_CGI_MAX_HEADER_LENGTH];
@@ -441,16 +393,16 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers)
441393
h = (sapi_header_struct*)zend_llist_get_next_ex(&sapi_headers->headers, &pos);
442394
}
443395
if (!has_status) {
444-
http_error *err = (http_error*)http_error_codes;
396+
http_response_status_code_pair *err = (http_response_status_code_pair*)http_status_map;
445397

446398
while (err->code != 0) {
447399
if (err->code == SG(sapi_headers).http_response_code) {
448400
break;
449401
}
450402
err++;
451403
}
452-
if (err->msg) {
453-
len = slprintf(buf, sizeof(buf), "Status: %d %s\r\n", SG(sapi_headers).http_response_code, err->msg);
404+
if (err->str) {
405+
len = slprintf(buf, sizeof(buf), "Status: %d %s\r\n", SG(sapi_headers).http_response_code, err->str);
454406
} else {
455407
len = slprintf(buf, sizeof(buf), "Status: %d\r\n", SG(sapi_headers).http_response_code);
456408
}

0 commit comments

Comments
 (0)