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 +--------------------------------------------------------------------+
19 #include "ext/standard/info.h"
22 #include "php_content_types.h"
25 typedef void (*apfd_enumerate_post_entry_fn
)(sapi_post_entry
*);
27 #if PHP_VERSION_ID >= 70000
34 #define APFD_SG(t) &PG(http_globals)[t]
35 static inline sapi_post_entry
*apfd_get_post_entry(const char *ct_str
, size_t ct_len
)
37 return zend_hash_str_find_ptr(&SG(known_post_content_types
), ct_str
, ct_len
);
40 static inline void apfd_enumerate_post_entries(apfd_enumerate_post_entry_fn fn
)
44 ZEND_HASH_FOREACH_PTR(&SG(known_post_content_types
), pe
)
48 ZEND_HASH_FOREACH_END();
51 static inline void apfd_backup(struct apfd
*apfd
)
53 if (SG(rfc1867_uploaded_files
)) {
54 destroy_uploaded_files_hash();
57 zval_ptr_dtor(APFD_SG(TRACK_VARS_POST
));
58 array_init(&apfd
->post
);
59 ZVAL_COPY_VALUE(APFD_SG(TRACK_VARS_POST
), &apfd
->post
);
61 zval_ptr_dtor(APFD_SG(TRACK_VARS_FILES
));
62 array_init(&apfd
->files
);
63 ZVAL_COPY_VALUE(APFD_SG(TRACK_VARS_FILES
), &apfd
->files
);
66 static inline void apfd_update(struct apfd
*apfd
)
68 zend_hash_str_update(&EG(symbol_table
), "_POST", sizeof("_POST")-1, APFD_SG(TRACK_VARS_POST
));
69 Z_TRY_ADDREF_P(APFD_SG(TRACK_VARS_POST
));
71 zend_hash_str_update(&EG(symbol_table
), "_FILES", sizeof("_FILES")-1, APFD_SG(TRACK_VARS_FILES
));
72 Z_TRY_ADDREF_P(APFD_SG(TRACK_VARS_FILES
));
82 #define APFD_SG(t) PG(http_globals)[t]
83 static inline sapi_post_entry
*apfd_get_post_entry(const char *ct_str
, size_t ct_len TSRMLS_DC
)
85 sapi_post_entry
*post_entry
;
87 if (SUCCESS
== zend_hash_find(&SG(known_post_content_types
), ct_str
, ct_len
+1, (void *) &post_entry
)) {
93 static inline void apfd_enumerate_post_entries(apfd_enumerate_post_entry_fn fn TSRMLS_DC
)
96 HashTable
*ht
= &SG(known_post_content_types
);
100 zend_hash_internal_pointer_reset_ex(ht
, &pos
);
101 zend_hash_get_current_data_ex(ht
, (void **) &pe
, &pos
) == SUCCESS
;
102 zend_hash_move_forward_ex(ht
, &pos
)
108 static inline void apfd_backup(struct apfd
*apfd TSRMLS_DC
)
110 apfd
->post
= APFD_SG(TRACK_VARS_POST
);
111 apfd
->files
= APFD_SG(TRACK_VARS_FILES
);
114 static inline void apfd_update(struct apfd
*apfd TSRMLS_DC
)
116 if (apfd
->files
!= APFD_SG(TRACK_VARS_FILES
) && APFD_SG(TRACK_VARS_FILES
)) {
117 Z_ADDREF_P(APFD_SG(TRACK_VARS_FILES
));
118 zend_hash_update(&EG(symbol_table
), "_FILES", sizeof("_FILES"), &APFD_SG(TRACK_VARS_FILES
), sizeof(zval
*), NULL
);
120 zval_ptr_dtor(&apfd
->files
);
126 PHP_RINIT_FUNCTION(apfd
)
133 sapi_request_info
*req
= &SG(request_info
);
135 /* populate form data on non-POST requests */
136 if (req
->request_method
&& strcasecmp(req
->request_method
, "POST") && req
->content_type
&& *req
->content_type
) {
137 char *ct_str
, *ct_dup
= estrdup(req
->content_type
);
138 size_t ct_end
= strcspn(ct_dup
, ";, ");
139 sapi_post_entry
*post_entry
= NULL
;
141 req
->content_type_dup
= ct_dup
;
143 ct_str
= zend_str_tolower_dup(ct_dup
, ct_end
);
144 if ((post_entry
= apfd_get_post_entry(ct_str
, ct_end TSRMLS_CC
))) {
147 apfd_backup(&apfd TSRMLS_CC
);
149 req
->post_entry
= post_entry
;
151 if (post_entry
->post_reader
) {
152 post_entry
->post_reader(TSRMLS_C
);
155 if (sapi_module
.default_post_reader
) {
156 sapi_module
.default_post_reader(TSRMLS_C
);
159 sapi_handle_post(APFD_SG(TRACK_VARS_POST
) TSRMLS_CC
);
161 apfd_update(&apfd TSRMLS_CC
);
165 if (req
->content_type_dup
) {
166 efree(req
->content_type_dup
);
167 req
->content_type_dup
= NULL
;
174 #define CUSTOM_OR_DEFAULT(ptr, def) ((ptr) && ((ptr) != (def)) ? "custom" : "default")
175 static void apfd_enumerate_post_entry(sapi_post_entry
*pe
)
177 php_info_print_table_row(3, pe
->content_type
,
178 CUSTOM_OR_DEFAULT(pe
->post_reader
, sapi_read_standard_form_data
),
179 CUSTOM_OR_DEFAULT(pe
->post_handler
, php_std_post_handler
)
183 PHP_MINFO_FUNCTION(apfd
)
185 php_info_print_table_start();
186 php_info_print_table_header(2, "APFD Support", "enabled");
187 php_info_print_table_row(2, "Extension Version", PHP_APFD_VERSION
);
188 php_info_print_table_end();
189 php_info_print_table_start();
190 php_info_print_table_header(3, "Content type", "Reader", "Handler");
191 apfd_enumerate_post_entries(apfd_enumerate_post_entry TSRMLS_CC
);
192 php_info_print_table_end();
195 const zend_function_entry apfd_functions
[] = {
199 zend_module_entry apfd_module_entry
= {
200 STANDARD_MODULE_HEADER
,
209 STANDARD_MODULE_PROPERTIES
212 #ifdef COMPILE_DL_APFD
213 ZEND_GET_MODULE(apfd
)
221 * vim600: noet sw=4 ts=4 fdm=marker
222 * vim<600: noet sw=4 ts=4