2 +--------------------------------------------------------------------+
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2015, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
20 #include "ext/standard/info.h"
21 #include "ext/json/php_json.h"
22 #include "php_json_post.h"
25 ZEND_DECLARE_MODULE_GLOBALS(json_post
);
28 STD_PHP_INI_ENTRY("json_post.flags", "1", PHP_INI_PERDIR
, OnUpdateLong
, flags
, zend_json_post_globals
, json_post_globals
)
29 STD_PHP_INI_ENTRY("json_post.error_response", "0", PHP_INI_PERDIR
, OnUpdateLong
, error_response
, zend_json_post_globals
, json_post_globals
)
30 STD_PHP_INI_ENTRY("json_post.error_exit", "0", PHP_INI_PERDIR
, OnUpdateBool
, error_exit
, zend_json_post_globals
, json_post_globals
)
33 static void php_json_post_init_globals(zend_json_post_globals
*json_post_globals
)
35 #if PHP_VERSION_ID >= 50400
36 json_post_globals
->flags
= PHP_JSON_OBJECT_AS_ARRAY
;
38 json_post_globals
->flags
= 1;
42 #if PHP_VERSION_ID < 70000
43 ZEND_EXTERN_MODULE_GLOBALS(json
);
44 static inline void zend_print_long_to_buf(char *p
, long l
) {
46 *--p
= (char) (l
% 10) + '0';
57 PHP_MINFO_FUNCTION(json_post
)
59 php_info_print_table_start();
60 php_info_print_table_header(2, "json_post support", "enabled");
61 php_info_print_table_end();
63 DISPLAY_INI_ENTRIES();
66 static SAPI_POST_HANDLER_FUNC(php_json_post_handler
)
68 #if PHP_VERSION_ID >= 70000
69 zend_string
*json
= NULL
;
71 if (SG(request_info
).request_body
) {
72 /* FG(stream_wrappers) not initialized yet, so we cannot use php://input */
73 php_stream_rewind(SG(request_info
).request_body
);
74 json
= php_stream_copy_to_mem(SG(request_info
).request_body
, PHP_STREAM_COPY_ALL
, 0);
80 long flags
= JSON_POST_G(flags
);
82 #ifdef PHP_JSON_THROW_ON_ERROR
83 /* there's no execute data, so we must ensure json_decode() is not throwing */
84 flags
&= ~PHP_JSON_THROW_ON_ERROR
;
88 php_json_decode_ex(&tmp
, json
->val
, json
->len
, flags
, PG(max_input_nesting_level
));
90 switch (Z_TYPE(tmp
)) {
93 if (zend_hash_num_elements(HASH_OF(&tmp
))) {
95 ZVAL_COPY_VALUE(&PG(http_globals
)[TRACK_VARS_POST
], &tmp
);
97 /* PHP-7.4 optimizes empty array */
105 zend_string_release(json
);
111 char *json_str
= NULL
;
114 # if PHP_VERSION_ID >= 50600
115 if (!SG(request_info
).request_body
) {
119 /* FG(stream_wrappers) not initialized yet, so we cannot use php://input */
120 php_stream_rewind(SG(request_info
).request_body
);
121 json_len
= php_stream_copy_to_mem(SG(request_info
).request_body
, &json_str
, PHP_STREAM_COPY_ALL
, 0);
123 json_str
= SG(request_info
).raw_post_data
;
124 json_len
= SG(request_info
).raw_post_data_length
;
132 # if PHP_VERSION_ID >= 50400
133 php_json_decode_ex(&zjson
, json_str
, json_len
, JSON_POST_G(flags
), PG(max_input_nesting_level
) TSRMLS_CC
);
134 if (Z_TYPE(zjson
) != IS_NULL
) {
136 ZVAL_COPY_VALUE(zarg
, (&zjson
));
138 php_json_decode(&zjson
, json_str
, json_len
, (zend_bool
)(JSON_POST_G(flags
)&1), PG(max_input_nesting_level
) TSRMLS_CC
);
139 if (Z_TYPE(zjson
) != IS_NULL
) {
141 zarg
->value
= zjson
.value
;
142 Z_TYPE_P(zarg
) = Z_TYPE(zjson
);
146 # if PHP_VERSION_ID >= 50600
153 if (JSON_G(error_code
)) {
154 if (JSON_POST_G(error_response
)) {
155 char header
[] = "X-JSON-Error-Code: ";
156 zend_print_long_to_buf(header
+ sizeof(header
) - 1, (JSON_G(error_code
) & 0xff));
157 sapi_header_op(SAPI_HEADER_SET_STATUS
, (void *) (long) JSON_POST_G(error_response
) TSRMLS_CC
);
158 sapi_add_header(header
, sizeof(header
)-1, 1);
160 if (JSON_POST_G(error_exit
)) {
161 sapi_send_headers(TSRMLS_C
);
164 /* ext/json in PHP-7 fails to reset error_code in RINIT */
165 JSON_G(error_code
) = 0;
169 PHP_MINIT_FUNCTION(json_post
)
171 sapi_post_entry json_post_entries
[] = {
172 { "text/json", sizeof("text/json")-1, sapi_read_standard_form_data
, php_json_post_handler
},
173 { "application/json", sizeof("application/json")-1, sapi_read_standard_form_data
, php_json_post_handler
},
174 { NULL
, 0, NULL
, NULL
}
177 sapi_register_post_entries(json_post_entries TSRMLS_CC
);
179 ZEND_INIT_MODULE_GLOBALS(json_post
, php_json_post_init_globals
, NULL
);
180 REGISTER_INI_ENTRIES();
184 PHP_MSHUTDOWN_FUNCTION(json_post
)
186 UNREGISTER_INI_ENTRIES();
191 zend_function_entry json_post_functions
[] = {
195 static zend_module_dep json_post_module_deps
[] = {
196 ZEND_MOD_REQUIRED("json")
197 {NULL
, NULL
, NULL
, 0}
200 zend_module_entry json_post_module_entry
= {
201 STANDARD_MODULE_HEADER_EX
,
203 json_post_module_deps
,
206 PHP_MINIT(json_post
),
207 PHP_MSHUTDOWN(json_post
),
210 PHP_MINFO(json_post
),
211 PHP_JSON_POST_VERSION
,
212 STANDARD_MODULE_PROPERTIES
216 #ifdef COMPILE_DL_JSON_POST
217 ZEND_GET_MODULE(json_post
)
225 * vim600: noet sw=4 ts=4 fdm=marker
226 * vim<600: noet sw=4 ts=4