move to PHP-7.4 as current GA
[m6w6/ext-apfd] / php_apfd.c
1 /*
2 +--------------------------------------------------------------------+
3 | PECL :: apfd |
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 +--------------------------------------------------------------------+
11 */
12
13 #ifdef HAVE_CONFIG_H
14 #include "config.h"
15 #endif
16
17 #include "php.h"
18 #include "php_ini.h"
19 #include "ext/standard/info.h"
20 #include "SAPI.h"
21 #include "rfc1867.h"
22 #include "php_apfd.h"
23
24 #if PHP_VERSION_ID >= 70000
25
26 struct apfd {
27 zval post;
28 zval files;
29 };
30
31 #define APFD_SG(t) &PG(http_globals)[t]
32 static inline sapi_post_entry *apfd_get_post_entry(const char *ct_str, size_t ct_len)
33 {
34 return zend_hash_str_find_ptr(&SG(known_post_content_types), ct_str, ct_len);
35 }
36
37 static inline void apfd_backup(struct apfd *apfd)
38 {
39 if (SG(rfc1867_uploaded_files)) {
40 destroy_uploaded_files_hash();
41 }
42
43 zval_ptr_dtor(APFD_SG(TRACK_VARS_POST));
44 array_init(&apfd->post);
45 ZVAL_COPY_VALUE(APFD_SG(TRACK_VARS_POST), &apfd->post);
46
47 zval_ptr_dtor(APFD_SG(TRACK_VARS_FILES));
48 array_init(&apfd->files);
49 ZVAL_COPY_VALUE(APFD_SG(TRACK_VARS_FILES), &apfd->files);
50 }
51
52 static inline void apfd_update(struct apfd *apfd)
53 {
54 zend_hash_str_update(&EG(symbol_table), "_POST", sizeof("_POST")-1, APFD_SG(TRACK_VARS_POST));
55 Z_TRY_ADDREF_P(APFD_SG(TRACK_VARS_POST));
56
57 zend_hash_str_update(&EG(symbol_table), "_FILES", sizeof("_FILES")-1, APFD_SG(TRACK_VARS_FILES));
58 Z_TRY_ADDREF_P(APFD_SG(TRACK_VARS_FILES));
59 }
60
61 #else
62
63 struct apfd {
64 zval *post;
65 zval *files;
66 };
67
68 #define APFD_SG(t) PG(http_globals)[t]
69 static inline sapi_post_entry *apfd_get_post_entry(const char *ct_str, size_t ct_len TSRMLS_DC)
70 {
71 sapi_post_entry *post_entry;
72
73 if (SUCCESS == zend_hash_find(&SG(known_post_content_types), ct_str, ct_len+1, (void *) &post_entry)) {
74 return post_entry;
75 }
76 return NULL;
77 }
78
79 static inline void apfd_backup(struct apfd *apfd TSRMLS_DC)
80 {
81 apfd->post = APFD_SG(TRACK_VARS_POST);
82 apfd->files = APFD_SG(TRACK_VARS_FILES);
83 }
84
85 static inline void apfd_update(struct apfd *apfd TSRMLS_DC)
86 {
87 if (apfd->files != APFD_SG(TRACK_VARS_FILES) && APFD_SG(TRACK_VARS_FILES)) {
88 Z_ADDREF_P(APFD_SG(TRACK_VARS_FILES));
89 zend_hash_update(&EG(symbol_table), "_FILES", sizeof("_FILES"), &APFD_SG(TRACK_VARS_FILES), sizeof(zval *), NULL);
90 if (apfd->files) {
91 zval_ptr_dtor(&apfd->files);
92 }
93 }
94 }
95 #endif
96
97 PHP_RINIT_FUNCTION(apfd)
98 {
99 #ifndef TSRMLS_C
100 # define TSRMLS_C
101 # define TSRMLS_CC
102 #endif
103 /* populate form data on non-POST requests */
104 if (SG(request_info).request_method && strcasecmp(SG(request_info).request_method, "POST") && SG(request_info).content_type && *SG(request_info).content_type) {
105 char *ct_str, *ct_dup = estrdup(SG(request_info).content_type);
106 size_t ct_end = strcspn(ct_dup, ";, ");
107 sapi_post_entry *post_entry = NULL;
108
109 SG(request_info).content_type_dup = ct_dup;
110
111 ct_str = zend_str_tolower_dup(ct_dup, ct_end);
112 if ((post_entry = apfd_get_post_entry(ct_str, ct_end TSRMLS_CC))) {
113 struct apfd apfd;
114
115 apfd_backup(&apfd TSRMLS_CC);
116
117 SG(request_info).post_entry = post_entry;
118
119 if (post_entry->post_reader) {
120 post_entry->post_reader(TSRMLS_C);
121 }
122
123 if (sapi_module.default_post_reader) {
124 sapi_module.default_post_reader(TSRMLS_C);
125 }
126
127 sapi_handle_post(APFD_SG(TRACK_VARS_POST) TSRMLS_CC);
128
129 apfd_update(&apfd TSRMLS_CC);
130 }
131 efree(ct_str);
132
133 if (SG(request_info).content_type_dup) {
134 efree(SG(request_info).content_type_dup);
135 SG(request_info).content_type_dup = NULL;
136 }
137 }
138
139 return SUCCESS;
140 }
141
142 PHP_MINFO_FUNCTION(apfd)
143 {
144 php_info_print_table_start();
145 php_info_print_table_header(2, "apfd support", "enabled");
146 php_info_print_table_end();
147 }
148
149 const zend_function_entry apfd_functions[] = {
150 {0}
151 };
152
153 zend_module_entry apfd_module_entry = {
154 STANDARD_MODULE_HEADER,
155 "apfd",
156 apfd_functions,
157 NULL,
158 NULL,
159 PHP_RINIT(apfd),
160 NULL,
161 PHP_MINFO(apfd),
162 PHP_APFD_VERSION,
163 STANDARD_MODULE_PROPERTIES
164 };
165
166 #ifdef COMPILE_DL_APFD
167 ZEND_GET_MODULE(apfd)
168 #endif
169
170 /*
171 * Local variables:
172 * tab-width: 4
173 * c-basic-offset: 4
174 * End:
175 * vim600: noet sw=4 ts=4 fdm=marker
176 * vim<600: noet sw=4 ts=4
177 */