4159620236ff99c614454573f678636062d9fae2
[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 sapi_request_info *req = &SG(request_info);
104
105 /* populate form data on non-POST requests */
106 if (req->request_method && strcasecmp(req->request_method, "POST") && req->content_type && *req->content_type) {
107 char *ct_str, *ct_dup = estrdup(req->content_type);
108 size_t ct_end = strcspn(ct_dup, ";, ");
109 sapi_post_entry *post_entry = NULL;
110
111 req->content_type_dup = ct_dup;
112
113 ct_str = zend_str_tolower_dup(ct_dup, ct_end);
114 if ((post_entry = apfd_get_post_entry(ct_str, ct_end TSRMLS_CC))) {
115 struct apfd apfd;
116
117 apfd_backup(&apfd TSRMLS_CC);
118
119 req->post_entry = post_entry;
120
121 if (post_entry->post_reader) {
122 post_entry->post_reader(TSRMLS_C);
123 }
124
125 if (sapi_module.default_post_reader) {
126 sapi_module.default_post_reader(TSRMLS_C);
127 }
128
129 sapi_handle_post(APFD_SG(TRACK_VARS_POST) TSRMLS_CC);
130
131 apfd_update(&apfd TSRMLS_CC);
132 }
133 efree(ct_str);
134
135 if (req->content_type_dup) {
136 efree(req->content_type_dup);
137 req->content_type_dup = NULL;
138 }
139 }
140
141 return SUCCESS;
142 }
143
144 PHP_MINFO_FUNCTION(apfd)
145 {
146 php_info_print_table_start();
147 php_info_print_table_header(2, "apfd support", "enabled");
148 php_info_print_table_end();
149 }
150
151 const zend_function_entry apfd_functions[] = {
152 {0}
153 };
154
155 zend_module_entry apfd_module_entry = {
156 STANDARD_MODULE_HEADER,
157 "apfd",
158 apfd_functions,
159 NULL,
160 NULL,
161 PHP_RINIT(apfd),
162 NULL,
163 PHP_MINFO(apfd),
164 PHP_APFD_VERSION,
165 STANDARD_MODULE_PROPERTIES
166 };
167
168 #ifdef COMPILE_DL_APFD
169 ZEND_GET_MODULE(apfd)
170 #endif
171
172 /*
173 * Local variables:
174 * tab-width: 4
175 * c-basic-offset: 4
176 * End:
177 * vim600: noet sw=4 ts=4 fdm=marker
178 * vim<600: noet sw=4 ts=4
179 */