1 /*
2    +----------------------------------------------------------------------+
3    | Yet Another Framework                                                |
4    +----------------------------------------------------------------------+
5    | This source file is subject to version 3.01 of the PHP license,      |
6    | that is bundled with this package in the file LICENSE, and is        |
7    | available through the world-wide-web at the following url:           |
8    | http://www.php.net/license/3_01.txt                                  |
9    | If you did not receive a copy of the PHP license and are unable to   |
10    | obtain it through the world-wide-web, please send a note to          |
11    | license@php.net so we can mail you a copy immediately.               |
12    +----------------------------------------------------------------------+
13    | Author: Xinchen Hui  <laruence@php.net>                              |
14    +----------------------------------------------------------------------+
15    */
16 
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20 
21 #include "php.h"
22 #include "main/SAPI.h"
23 #include "standard/php_string.h" /* for php_basename */
24 #include "Zend/zend_exceptions.h" /* for zend_exception_get_default */
25 #include "Zend/zend_interfaces.h" /* for zend_class_serialize_deny */
26 #include "Zend/zend_smart_str.h"
27 
28 #include "php_yaf.h"
29 #include "yaf_application.h"
30 #include "yaf_request.h"
31 #include "yaf_namespace.h"
32 #include "yaf_exception.h"
33 #include "yaf_loader.h"
34 #include "yaf_router.h"
35 
36 #include "requests/yaf_request_simple.h"
37 #include "requests/yaf_request_http.h"
38 
39 zend_class_entry *yaf_request_ce;
40 static zend_object_handlers yaf_request_obj_handlers;
41 
42 /** {{{ ARG_INFO
43 */
44 ZEND_BEGIN_ARG_INFO_EX(yaf_request_void_arginfo, 0, 0, 0)
ZEND_END_ARG_INFO()45 ZEND_END_ARG_INFO()
46 
47 ZEND_BEGIN_ARG_INFO_EX(yaf_request_set_routed_arginfo, 0, 0, 1)
48 	ZEND_ARG_INFO(0, flag)
49 ZEND_END_ARG_INFO()
50 
51 ZEND_BEGIN_ARG_INFO_EX(yaf_request_set_module_name_arginfo, 0, 0, 1)
52 	ZEND_ARG_INFO(0, module)
53 	ZEND_ARG_INFO(0, format_name)
54 ZEND_END_ARG_INFO()
55 
56 ZEND_BEGIN_ARG_INFO_EX(yaf_request_set_controller_arginfo, 0, 0, 1)
57 	ZEND_ARG_INFO(0, controller)
58 	ZEND_ARG_INFO(0, format_name)
59 ZEND_END_ARG_INFO()
60 
61 ZEND_BEGIN_ARG_INFO_EX(yaf_request_set_action_arginfo, 0, 0, 1)
62 	ZEND_ARG_INFO(0, action)
63 	ZEND_ARG_INFO(0, format_name)
64 ZEND_END_ARG_INFO()
65 
66 ZEND_BEGIN_ARG_INFO_EX(yaf_request_set_baseuri_arginfo, 0, 0, 1)
67 	ZEND_ARG_INFO(0, uri)
68 ZEND_END_ARG_INFO()
69 
70 ZEND_BEGIN_ARG_INFO_EX(yaf_request_set_request_uri_arginfo, 0, 0, 1)
71 	ZEND_ARG_INFO(0, uri)
72 ZEND_END_ARG_INFO()
73 
74 ZEND_BEGIN_ARG_INFO_EX(yaf_request_set_param_arginfo, 0, 0, 1)
75 	ZEND_ARG_INFO(0, name)
76 	ZEND_ARG_INFO(0, value)
77 ZEND_END_ARG_INFO()
78 
79 ZEND_BEGIN_ARG_INFO_EX(yaf_request_get_arginfo, 0, 0, 0)
80 	ZEND_ARG_INFO(0, name)
81 	ZEND_ARG_INFO(0, default)
82 ZEND_END_ARG_INFO()
83 
84 ZEND_BEGIN_ARG_INFO_EX(yaf_request_set_dispatched_arginfo, 0, 0, 1)
85     ZEND_ARG_INFO(0, dispatched)
86 ZEND_END_ARG_INFO()
87 	/* }}} */
88 
89 static zend_object *yaf_request_new(zend_class_entry *ce) /* {{{ */ {
90 	yaf_request_object *req = emalloc(sizeof(yaf_request_object) + zend_object_properties_size(ce));
91 
92 	memset(req, 0, XtOffsetOf(yaf_request_object, std));
93 	zend_object_std_init(&req->std, ce);
94 	if (ce->default_properties_count) {
95 		object_properties_init(&req->std, ce);
96 	}
97 	req->std.handlers = &yaf_request_obj_handlers;
98 	req->uri = ZSTR_EMPTY_ALLOC();
99 
100 	return &req->std;
101 }
102 /* }}} */
103 
yaf_request_object_free(zend_object * object)104 static void yaf_request_object_free(zend_object *object) /* {{{ */ {
105 	yaf_request_object *req = php_yaf_request_fetch_object(object);
106 
107 	if (req->method) {
108 		zend_string_release(req->method);
109 	}
110 	if (req->module) {
111 		zend_string_release(req->module);
112 	}
113 	if (req->controller) {
114 		zend_string_release(req->controller);
115 	}
116 	if (req->action) {
117 		zend_string_release(req->action);
118 	}
119 	if (req->uri) {
120 		zend_string_release(req->uri);
121 	}
122 	if (req->base_uri) {
123 		zend_string_release(req->base_uri);
124 	}
125 	if (req->language) {
126 		zend_string_release(req->language);
127 	}
128 
129 	if (req->params) {
130 		if (GC_DELREF(req->params) == 0) {
131 			GC_REMOVE_FROM_BUFFER(req->params);
132 			zend_array_destroy(req->params);
133 		}
134 	}
135 
136 	if (req->properties) {
137 		if (GC_DELREF(req->properties) == 0) {
138 			GC_REMOVE_FROM_BUFFER(req->properties);
139 			zend_array_destroy(req->properties);
140 		}
141 	}
142 
143 	zend_object_std_dtor(object);
144 }
145 /* }}} */
146 
yaf_request_get_gc(yaf_object * object,zval ** table,int * n)147 static HashTable *yaf_request_get_gc(yaf_object *object, zval **table, int *n) /* {{{ */
148 {
149 	yaf_request_object *request = php_yaf_request_fetch_object(yaf_strip_obj(object));
150 
151 	*table = NULL;
152 	*n = 0;
153 
154 	return request->params;
155 }
156 /* }}} */
157 
yaf_request_get_properties(yaf_object * object)158 static HashTable *yaf_request_get_properties(yaf_object *object) /* {{{ */ {
159 	zval rv;
160 	HashTable *ht;
161 	yaf_request_object *request = php_yaf_request_fetch_object(yaf_strip_obj(object));
162 
163 	if (!request->properties) {
164 		ALLOC_HASHTABLE(request->properties);
165 		zend_hash_init(request->properties, 16, NULL, ZVAL_PTR_DTOR, 0);
166 		YAF_ALLOW_VIOLATION(request->properties);
167 	}
168 
169 	ht = request->properties;
170 	ZVAL_STR_COPY(&rv, request->method);
171 	zend_hash_str_update(ht, "method", sizeof("method") - 1, &rv);
172 	if (request->module) {
173 		ZVAL_STR_COPY(&rv, request->module);
174 	} else {
175 		ZVAL_NULL(&rv);
176 	}
177 	zend_hash_str_update(ht, "module", sizeof("module") - 1, &rv);
178 	if (request->controller) {
179 		ZVAL_STR_COPY(&rv, request->controller);
180 	} else {
181 		ZVAL_NULL(&rv);
182 	}
183 	zend_hash_str_update(ht, "controller", sizeof("controller") - 1, &rv);
184 	if (request->action) {
185 		ZVAL_STR_COPY(&rv, request->action);
186 	} else {
187 		ZVAL_NULL(&rv);
188 	}
189 	zend_hash_str_update(ht, "action", sizeof("action") - 1, &rv);
190 
191 	if (request->uri) {
192 		ZVAL_STR_COPY(&rv, request->uri);
193 	} else {
194 		ZVAL_NULL(&rv);
195 	}
196 	zend_hash_str_update(ht, "uri:protected", sizeof("uri:protected") - 1, &rv);
197 
198 	if (request->base_uri) {
199 		ZVAL_STR_COPY(&rv, request->base_uri);
200 	} else {
201 		ZVAL_NULL(&rv);
202 	}
203 	zend_hash_str_update(ht, "base_uri:protected", sizeof("base_uri:protected") - 1, &rv);
204 
205 	ZVAL_BOOL(&rv, yaf_request_is_dispatched(request));
206 	zend_hash_str_update(ht, "dispatched:protected", sizeof("dispatched:protected") - 1, &rv);
207 
208 	ZVAL_BOOL(&rv, yaf_request_is_routed(request));
209 	zend_hash_str_update(ht, "routed:protected", sizeof("routed:protected") - 1, &rv);
210 
211 	if (request->language) {
212 		ZVAL_STR_COPY(&rv, request->language);
213 	} else {
214 		ZVAL_EMPTY_STRING(&rv);
215 	}
216 	zend_hash_str_update(ht, "language:protected", sizeof("language:protected") - 1, &rv);
217 
218 	if (request->params) {
219 		ZVAL_ARR(&rv, request->params);
220 		GC_ADDREF(request->params);
221 	} else {
222 #if PHP_VERSION_ID < 70400
223 		array_init(&rv);
224 #else
225 		ZVAL_EMPTY_ARRAY(&rv);
226 #endif
227 	}
228 	zend_hash_str_update(ht, "params:protected", sizeof("params:protected") - 1, &rv);
229 
230 	return ht;
231 }
232 /* }}} */
233 
yaf_request_get_method(yaf_request_object * request)234 static zend_always_inline zend_string *yaf_request_get_method(yaf_request_object *request) /* {{{ */ {
235 	return zend_string_copy(request->method);
236 }
237 /* }}} */
238 
yaf_request_get_module(yaf_request_object * request)239 static zend_always_inline zend_string *yaf_request_get_module(yaf_request_object *request) /* {{{ */ {
240 	if (request->module) {
241 		return zend_string_copy(request->module);
242 	}
243 	return NULL;
244 }
245 /* }}} */
246 
yaf_request_get_controller(yaf_request_object * request)247 static zend_always_inline zend_string *yaf_request_get_controller(yaf_request_object *request) /* {{{ */ {
248 	if (request->controller) {
249 		return zend_string_copy(request->controller);
250 	}
251 	return NULL;
252 }
253 /* }}} */
254 
yaf_request_get_action(yaf_request_object * request)255 static zend_always_inline zend_string *yaf_request_get_action(yaf_request_object *request) /* {{{ */ {
256 	if (request->action) {
257 		return zend_string_copy(request->action);
258 	}
259 	return NULL;
260 }
261 /* }}} */
262 
yaf_request_get_uri(yaf_request_object * request)263 static zend_always_inline zend_string *yaf_request_get_uri(yaf_request_object *request) /* {{{ */ {
264 	if (request->uri) {
265 		return zend_string_copy(request->uri);
266 	}
267 	return NULL;
268 }
269 /* }}} */
270 
yaf_request_get_base_uri(yaf_request_object * request)271 static zend_always_inline zend_string *yaf_request_get_base_uri(yaf_request_object *request) /* {{{ */ {
272 	if (request->base_uri) {
273 		return zend_string_copy(request->base_uri);
274 	}
275 	return NULL;
276 }
277 /* }}} */
278 
yaf_request_get_language(yaf_request_object * request)279 zend_string *yaf_request_get_language(yaf_request_object *request) /* {{{ */ {
280 	if (!request->language) {
281 		zval *accept_langs = yaf_request_query_str(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("HTTP_ACCEPT_LANGUAGE"));
282 		if (!accept_langs) {
283 			return NULL;
284 		} else if (UNEXPECTED(IS_STRING != Z_TYPE_P(accept_langs) || !Z_STRLEN_P(accept_langs))) {
285 			return NULL;
286 		} else {
287 			char *seg;
288 			char *ptrptr = NULL;
289 			unsigned prefer_len = 0;
290 			double	max_qvlaue = 0;
291 			char *prefer = NULL;
292 			char *langs = estrndup(Z_STRVAL_P(accept_langs), Z_STRLEN_P(accept_langs));
293 
294 			seg = php_strtok_r(langs, ",", &ptrptr);
295 			while (seg) {
296 				char *qvalue;
297 				while (*(seg) == ' ') {
298 					seg++;
299 				}
300 				/* Accept-Language: da, en-gb;q=0.8, en;q=0.7 */
301 				if ((qvalue = strstr(seg, "q="))) {
302 					float qval = strtod(qvalue + 2, NULL);
303 					if (qval > max_qvlaue) {
304 						max_qvlaue = qval;
305 						prefer_len = qvalue - seg - 1;
306 						prefer 	   = seg;
307 					}
308 				} else {
309 					if (max_qvlaue < 1) {
310 						max_qvlaue = 1;
311 						prefer_len = strlen(seg);
312 						prefer 	   = seg;
313 					}
314 				}
315 
316 				seg = php_strtok_r(NULL, ",", &ptrptr);
317 			}
318 
319 			if (prefer) {
320 				request->language = zend_string_init(prefer, prefer_len, 0);
321 			}
322 			efree(langs);
323 		}
324 	}
325 
326 	return zend_string_copy(request->language);
327 }
328 /* }}} */
329 
yaf_request_read_property(yaf_object * obj,void * name,int type,void ** cache_slot,zval * rv)330 static zval* yaf_request_read_property(yaf_object *obj, void/*for php8 portability*/ *name, int type, void **cache_slot, zval *rv) /* {{{ */ {
331 	zend_string *member;
332 	yaf_request_object *request = php_yaf_request_fetch_object(yaf_strip_obj(obj));
333 
334 #if PHP_VERSION_ID < 80000
335 	if (UNEXPECTED(Z_TYPE_P((zval*)name) != IS_STRING)) {
336 		return &EG(uninitialized_zval);
337 	}
338 #endif
339 
340 #if PHP_VERSION_ID < 80000
341 	member = Z_STR_P((zval*)name);
342 #else
343 	member = (zend_string*)name;
344 #endif
345 
346 	if (UNEXPECTED(type == BP_VAR_W || type == BP_VAR_RW)) {
347 		php_error_docref(NULL, E_WARNING,
348 				"Indirect modification of Yaf_Reqeust internal property '%s' is not allowed", ZSTR_VAL(member));
349 		return &EG(error_zval);
350 	}
351 
352 	switch (ZSTR_LEN(member)) {
353 		case 3:
354 			if (yaf_slip_equal(ZSTR_VAL(member), ZEND_STRS("uri"))) {
355 				zend_string *val = yaf_request_get_uri(request);
356 				if (val) {
357 					ZVAL_STR(rv, val);
358 					return rv;
359 				}
360 				return &EG(uninitialized_zval);
361 			}
362 			break;
363 		case 6:
364 			if (yaf_slip_equal(ZSTR_VAL(member), ZEND_STRL("method"))) {
365 				zend_string *val = yaf_request_get_method(request);
366 				if (val) {
367 					ZVAL_STR(rv, val);
368 					return rv;
369 				}
370 				return &EG(uninitialized_zval);
371 			}
372 			if (yaf_slip_equal(ZSTR_VAL(member), ZEND_STRL("module"))) {
373 				zend_string *val = yaf_request_get_module(request);
374 				if (val) {
375 					ZVAL_STR(rv, val);
376 					return rv;
377 				}
378 				return &EG(uninitialized_zval);
379 			}
380 			if (yaf_slip_equal(ZSTR_VAL(member), ZEND_STRL("action"))) {
381 				zend_string *val = yaf_request_get_action(request);
382 				if (val) {
383 					ZVAL_STR(rv, val);
384 					return rv;
385 				}
386 				return &EG(uninitialized_zval);
387 			}
388 			if (yaf_slip_equal(ZSTR_VAL(member), ZEND_STRL("routed"))) {
389 				ZVAL_BOOL(rv, yaf_request_is_routed(request));
390 				return rv;
391 			}
392 			break;
393 		case 8:
394 			if (yaf_slip_equal(ZSTR_VAL(member), ZEND_STRL("base_uri"))) {
395 				zend_string *val = yaf_request_get_base_uri(request);
396 				if (val) {
397 					ZVAL_STR(rv, val);
398 					return rv;
399 				}
400 				return &EG(uninitialized_zval);
401 			}
402 			if (yaf_slip_equal(ZSTR_VAL(member), ZEND_STRL("language"))) {
403 				zend_string *val = yaf_request_get_language(request);
404 				if (val) {
405 					ZVAL_STR(rv, val);
406 					return rv;
407 				}
408 				return &EG(uninitialized_zval);
409 			}
410 			break;
411 		case 10:
412 			if (yaf_slip_equal(ZSTR_VAL(member), ZEND_STRL("controller"))) {
413 				zend_string *val = yaf_request_get_controller(request);
414 				if (val) {
415 					ZVAL_STR(rv, val);
416 					return rv;
417 				}
418 				return &EG(uninitialized_zval);
419 			}
420 			if (yaf_slip_equal(ZSTR_VAL(member), ZEND_STRL("dispatched"))) {
421 				ZVAL_BOOL(rv, yaf_request_is_dispatched(request));
422 				return rv;
423 			}
424 			default:
425 			break;
426 	}
427 	return std_object_handlers.read_property(obj, name, type, cache_slot, rv);
428 }
429 /* }}} */
430 
yaf_request_set_uri(yaf_request_object * request,zend_string * uri)431 static inline void yaf_request_set_uri(yaf_request_object *request, zend_string *uri) /* {{{ */ {
432 	if (request->uri) {
433 		zend_string_release(request->uri);
434 	}
435 	request->uri = zend_string_copy(uri);
436 }
437 /* }}} */
438 
yaf_request_strip_base_uri(zend_string * uri,zend_string * base_uri,size_t * len)439 const char *yaf_request_strip_base_uri(zend_string *uri, zend_string *base_uri, size_t *len) /* {{{ */ {
440 	register const char *p = ZSTR_VAL(uri);
441 	if (strncasecmp(p, ZSTR_VAL(base_uri), ZSTR_LEN(base_uri)) == 0) {
442 		p += ZSTR_LEN(base_uri);
443 		if (*p == '\0' || *p == YAF_ROUTER_URL_DELIMIETER || *(--p) == YAF_ROUTER_URL_DELIMIETER) {
444 			*len = ZSTR_LEN(uri) - (p - ZSTR_VAL(uri));
445 			return p;
446 		}
447 	}
448 	*len = ZSTR_LEN(uri);
449 	return ZSTR_VAL(uri);
450 }
451 /* }}} */
452 
yaf_request_set_base_uri(yaf_request_object * request,zend_string * base_uri,zend_string * request_uri)453 int yaf_request_set_base_uri(yaf_request_object *request, zend_string *base_uri, zend_string *request_uri) /* {{{ */ {
454 
455 	if (UNEXPECTED(request->base_uri)) {
456 		zend_string_release(request->base_uri);
457 	}
458 
459 	if (base_uri == NULL) {
460 		zend_string *basename = NULL;
461 		zval *script_filename = yaf_request_query_str(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("SCRIPT_FILENAME"));
462 		do {
463 			if (script_filename && IS_STRING == Z_TYPE_P(script_filename)) {
464 				zend_string *file_name;
465 				char *ext;
466 				size_t ext_len;
467 				zval *script_name, *phpself_name, *orig_name;
468 				yaf_application_object *app;
469 
470 				if (UNEXPECTED((app = yaf_application_instance()) && app->ext)) {
471 					ext = ZSTR_VAL(app->ext);
472 					ext_len = ZSTR_LEN(app->ext);
473 				} else {
474 					ext = YAF_DEFAULT_EXT;
475 					ext_len = sizeof(YAF_DEFAULT_EXT) - 1;
476 				}
477 
478 				script_name = yaf_request_query_str(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("SCRIPT_NAME"));
479 				file_name = php_basename(Z_STRVAL_P(script_filename), Z_STRLEN_P(script_filename), ext, ext_len);
480 				if (script_name && EXPECTED(IS_STRING == Z_TYPE_P(script_name))) {
481 					zend_string	*script = php_basename(Z_STRVAL_P(script_name), Z_STRLEN_P(script_name), NULL, 0);
482 
483 					if (memcmp(ZSTR_VAL(file_name), ZSTR_VAL(script), MIN(ZSTR_LEN(file_name), ZSTR_LEN(script))) == 0) {
484 						basename = zend_string_copy(Z_STR_P(script_name));
485 						zend_string_release(file_name);
486 						zend_string_release(script);
487 						break;
488 					}
489 					zend_string_release(script);
490 				}
491 
492 				phpself_name = yaf_request_query_str(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("PHP_SELF"));
493 				if (phpself_name && EXPECTED(IS_STRING == Z_TYPE_P(phpself_name))) {
494 					zend_string *phpself = php_basename(Z_STRVAL_P(phpself_name), Z_STRLEN_P(phpself_name), NULL, 0);
495 					if (memcmp(ZSTR_VAL(file_name), ZSTR_VAL(phpself), MIN(ZSTR_LEN(file_name), ZSTR_LEN(file_name))) == 0) {
496 						basename = zend_string_copy(Z_STR_P(phpself_name));
497 						zend_string_release(file_name);
498 						zend_string_release(phpself);
499 						break;
500 					}
501 					zend_string_release(phpself);
502 				}
503 
504 				orig_name = yaf_request_query_str(YAF_GLOBAL_VARS_SERVER, ZEND_STRL("ORIG_SCRIPT_NAME"));
505 				if (orig_name && IS_STRING == Z_TYPE_P(orig_name)) {
506 					zend_string *orig = php_basename(Z_STRVAL_P(orig_name), Z_STRLEN_P(orig_name), NULL, 0);
507 					if (memcmp(ZSTR_VAL(file_name), ZSTR_VAL(orig), MIN(ZSTR_LEN(file_name), ZSTR_LEN(file_name))) == 0) {
508 						basename = zend_string_copy(Z_STR_P(orig_name));
509 						zend_string_release(file_name);
510 						zend_string_release(orig);
511 						break;
512 					}
513 					zend_string_release(orig);
514 				}
515 				zend_string_release(file_name);
516 			}
517 		} while (0);
518 
519 		if (basename) {
520 			if (memcmp(ZSTR_VAL(request_uri), ZSTR_VAL(basename), MIN(ZSTR_LEN(basename), ZSTR_LEN(request_uri))) == 0) {
521 				if (ZSTR_VAL(basename)[ZSTR_LEN(basename) - 1] == '/') {
522 					zend_string *sanitized_uri = zend_string_init(ZSTR_VAL(basename), ZSTR_LEN(basename) - 1, 0);
523 					zend_string_release(basename);
524 					basename = sanitized_uri;
525 				}
526 				request->base_uri = basename;
527 				return 1;
528 			} else {
529 				zend_string *dir = zend_string_init(ZSTR_VAL(basename), ZSTR_LEN(basename), 0); /* php_dirname might alter the string */
530 
531 				zend_string_release(basename);
532 				ZSTR_LEN(dir) = php_dirname(ZSTR_VAL(dir), ZSTR_LEN(dir));
533 				if (*(ZSTR_VAL(dir) + ZSTR_LEN(dir) - 1) == '/') {
534 					ZSTR_VAL(dir)[ZSTR_LEN(dir) - 1] = '\0';
535 					ZSTR_LEN(dir)--;
536 				}
537 				if (ZSTR_LEN(dir)) {
538 					if (memcmp(ZSTR_VAL(request_uri), ZSTR_VAL(dir), MIN(ZSTR_LEN(dir), ZSTR_LEN(request_uri))) == 0) {
539 						request->base_uri = dir;
540 						return 1;
541 					}
542 				}
543 				zend_string_release(dir);
544 			}
545 		}
546 		request->base_uri = NULL;
547 	} else {
548 		zend_string *sanitized_uri = NULL;
549 		if (UNEXPECTED(ZSTR_VAL(base_uri)[ZSTR_LEN(base_uri) - 1] == '/')) {
550 			sanitized_uri = zend_string_init(ZSTR_VAL(base_uri), ZSTR_LEN(base_uri) - 1, 0);
551 			base_uri = sanitized_uri;
552 		} else {
553 			zend_string_copy(base_uri);
554 		}
555 		request->base_uri = base_uri;
556 	}
557 	return 1;
558 }
559 /* }}} */
560 
yaf_request_write_property(yaf_object * obj,void * name,zval * value,void ** cache_slot)561 static YAF_WRITE_HANDLER yaf_request_write_property(yaf_object *obj, void *name, zval *value, void **cache_slot) /* {{{ */ {
562 	zend_string *member;
563 	yaf_request_object *request = php_yaf_request_fetch_object(yaf_strip_obj(obj));
564 
565 #if PHP_VERSION_ID < 80000
566 	if (UNEXPECTED(Z_TYPE_P((zval*)name) != IS_STRING)) {
567 		YAF_WHANDLER_RET(value);
568 	}
569 
570 	member = Z_STR_P((zval*)name);
571 #else
572 	member = (zend_string*)name;
573 #endif
574 
575 	if (zend_string_equals_literal(member, "method")) {
576 		if (UNEXPECTED(Z_TYPE_P(value) != IS_STRING || Z_STRLEN_P(value) == 0)) {
577 			YAF_WHANDLER_RET(value);
578 		}
579 		zend_string_release(request->method);
580 		request->method = zend_string_copy(Z_STR_P(value));
581 		YAF_WHANDLER_RET(value);
582 	}
583 
584 	if (zend_string_equals_literal(member, "module")) {
585 		if (UNEXPECTED(Z_TYPE_P(value) != IS_STRING || Z_STRLEN_P(value) == 0)) {
586 			YAF_WHANDLER_RET(value);
587 		}
588 		yaf_request_set_module(request, Z_STR_P(value));
589 		YAF_WHANDLER_RET(value);
590 	}
591 
592 	if (zend_string_equals_literal(member, "controller")) {
593 		if (UNEXPECTED(Z_TYPE_P(value) != IS_STRING || Z_STRLEN_P(value) == 0)) {
594 			YAF_WHANDLER_RET(value);
595 		}
596 		yaf_request_set_controller(request, Z_STR_P(value));
597 		YAF_WHANDLER_RET(value);
598 	}
599 
600 	if (zend_string_equals_literal(member, "action")) {
601 		if (UNEXPECTED(Z_TYPE_P(value) != IS_STRING || Z_STRLEN_P(value) == 0)) {
602 			YAF_WHANDLER_RET(value);
603 		}
604 		yaf_request_set_action(request, Z_STR_P(value));
605 		YAF_WHANDLER_RET(value);
606 	}
607 
608 	if (zend_string_equals_literal(member, "uri") ||
609 		zend_string_equals_literal(member, "base_uri") ||
610 		zend_string_equals_literal(member, "dispatched") ||
611 		zend_string_equals_literal(member, "language") ||
612 		zend_string_equals_literal(member, "routed") ||
613 		zend_string_equals_literal(member, "params")) {
614 
615 		php_error_docref(NULL, E_WARNING,
616 				"Modification of Yaf_Request internal property '%s' is not allowed", ZSTR_VAL(member));
617 		YAF_WHANDLER_RET(value);
618 	}
619 
620     return std_object_handlers.write_property(obj, name, value, cache_slot);
621 }
622 /* }}} */
623 
yaf_request_instance(yaf_request_t * this_ptr,zend_string * request_uri)624 void yaf_request_instance(yaf_request_t *this_ptr, zend_string *request_uri) /* {{{ */ {
625 	zend_object *req = yaf_request_new(yaf_request_http_ce);
626 
627 	yaf_request_http_init(php_yaf_request_fetch_object(req), NULL, request_uri);
628 
629 	ZVAL_OBJ(this_ptr, req);
630 }
631 /* }}} */
632 
yaf_request_set_mvc(yaf_request_object * request,zend_string * module,zend_string * controller,zend_string * action,zend_array * params)633 void yaf_request_set_mvc(yaf_request_object *request, zend_string *module, zend_string *controller, zend_string *action, zend_array *params) /* {{{ */ {
634 	if (module) {
635 		yaf_request_set_module(request, module);
636 	}
637 	if (controller) {
638 		yaf_request_set_controller(request, controller);
639 	}
640 	if (action) {
641 		yaf_request_set_action(request, action);
642 	}
643 	if (params) {
644 		if (!request->params) {
645 			ALLOC_HASHTABLE(request->params);
646 			zend_hash_init(request->params, zend_hash_num_elements(params), NULL, ZVAL_PTR_DTOR, 0);
647 			YAF_ALLOW_VIOLATION(request->params);
648 		}
649 		zend_hash_copy(request->params, params, (copy_ctor_func_t) zval_add_ref);
650 	}
651 }
652 /* }}} */
653 
yaf_request_clean_params(yaf_request_object * request)654 void yaf_request_clean_params(yaf_request_object *request) /* {{{ */ {
655 	if (request->params) {
656 		zend_hash_clean(request->params);
657 	}
658 }
659 /* }}} */
660 
yaf_request_fetch_container(unsigned type)661 static inline zval* yaf_request_fetch_container(unsigned type) /* {{{ */ {
662 	zval *container;
663 	zend_bool jit_initialization = PG(auto_globals_jit);
664 
665 	switch (type) {
666 		case YAF_GLOBAL_VARS_POST:
667 			container = zend_hash_find(&EG(symbol_table), YAF_KNOWN_STR(YAF_VAR_POST));
668 			break;
669 		case YAF_GLOBAL_VARS_GET:
670 			container = zend_hash_find(&EG(symbol_table), YAF_KNOWN_STR(YAF_VAR_GET));
671 			break;
672 		case YAF_GLOBAL_VARS_COOKIE:
673 			container = zend_hash_find(&EG(symbol_table), YAF_KNOWN_STR(YAF_VAR_COOKIE));
674 			break;
675 		case YAF_GLOBAL_VARS_FILES:
676 			container = zend_hash_find(&EG(symbol_table), YAF_KNOWN_STR(YAF_VAR_FILES));
677 			break;
678 		case YAF_GLOBAL_VARS_SERVER:
679 			if (jit_initialization) {
680 				zend_is_auto_global(YAF_KNOWN_STR(YAF_VAR_SERVER));
681 			}
682 			container = zend_hash_find(&EG(symbol_table), YAF_KNOWN_STR(YAF_VAR_SERVER));
683 			break;
684 		case YAF_GLOBAL_VARS_REQUEST:
685 			if (jit_initialization) {
686 				zend_is_auto_global(YAF_KNOWN_STR(YAF_VAR_REQUEST));
687 			}
688 			container = zend_hash_find(&EG(symbol_table), YAF_KNOWN_STR(YAF_VAR_REQUEST));
689 			break;
690 		case YAF_GLOBAL_VARS_ENV:
691 			if (jit_initialization) {
692 				zend_is_auto_global(YAF_KNOWN_STR(YAF_VAR_ENV));
693 			}
694 			container = zend_hash_find(&EG(symbol_table), YAF_KNOWN_STR(YAF_VAR_ENV));
695 			break;
696 		default:
697 			return NULL;
698 	}
699 
700 	if (UNEXPECTED(Z_TYPE_P(container) != IS_ARRAY)) {
701 		if (Z_TYPE_P(container) != IS_REFERENCE || Z_TYPE_P(Z_REFVAL_P(container)) != IS_ARRAY) {
702 			return NULL;
703 		}
704 		return Z_REFVAL_P(container);
705 	}
706 	return container;
707 }
708 /* }}} */
709 
yaf_request_query_str(unsigned type,const char * name,size_t len)710 ZEND_HOT zval *yaf_request_query_str(unsigned type, const char *name, size_t len) /* {{{ */ {
711 	zval *container = yaf_request_fetch_container(type);
712 
713 	if (UNEXPECTED(!container)) {
714 		return NULL;
715 	}
716 
717 	if (UNEXPECTED(name == NULL)) {
718 		return container;
719 	}
720 
721 	return zend_hash_str_find(Z_ARRVAL_P(container), name, len);
722 }
723 /* }}} */
724 
yaf_request_query(unsigned type,zend_string * name)725 ZEND_HOT zval *yaf_request_query(unsigned type, zend_string *name) /* {{{ */ {
726 	zval *container = yaf_request_fetch_container(type);
727 
728 	if (UNEXPECTED(!container)) {
729 		return NULL;
730 	}
731 
732 	if (UNEXPECTED(name == NULL)) {
733 		return container;
734 	}
735 
736 	return zend_hash_find(Z_ARRVAL_P(container), name);
737 }
738 /* }}} */
739 
yaf_request_del_str_param(yaf_request_object * request,const char * key,size_t len)740 int yaf_request_del_str_param(yaf_request_object *request, const char *key, size_t len) /* {{{ */ {
741 	if (request->params) {
742 		return zend_hash_str_del(request->params, key, len);
743 	}
744 	return 0;
745 }
746 /* }}} */
747 
yaf_request_del_param(yaf_request_object * request,zend_string * key)748 int yaf_request_del_param(yaf_request_object *request, zend_string *key) /* {{{ */ {
749 	if (request->params) {
750 		return zend_hash_del(request->params, key);
751 	}
752 	return 0;
753 }
754 /* }}} */
755 
yaf_request_set_str_params_single(yaf_request_object * request,const char * key,size_t len,zval * value)756 int yaf_request_set_str_params_single(yaf_request_object *request, const char *key, size_t len, zval *value) /* {{{ */ {
757 	if (!request->params) {
758 		ALLOC_HASHTABLE(request->params);
759 		zend_hash_init(request->params, 8, NULL, ZVAL_PTR_DTOR, 0);
760 		YAF_ALLOW_VIOLATION(request->params);
761 	}
762 	if ((zend_hash_str_update(request->params, key, len, value)) != NULL) {
763 		Z_TRY_ADDREF_P(value);
764 		return 1;
765 	}
766 	return 0;
767 }
768 /* }}} */
769 
yaf_request_set_params_single(yaf_request_object * request,zend_string * key,zval * value)770 int yaf_request_set_params_single(yaf_request_object *request, zend_string *key, zval *value) /* {{{ */ {
771 	if (!request->params) {
772 		ALLOC_HASHTABLE(request->params);
773 		zend_hash_init(request->params, 8, NULL, ZVAL_PTR_DTOR, 0);
774 		YAF_ALLOW_VIOLATION(request->params);
775 	}
776 	if ((zend_hash_update(request->params, key, value)) != NULL) {
777 		Z_TRY_ADDREF_P(value);
778 		return 1;
779 	}
780 	return 0;
781 }
782 /* }}} */
783 
yaf_request_set_params_multi(yaf_request_object * request,zval * values)784 int yaf_request_set_params_multi(yaf_request_object *request, zval *values) /* {{{ */ {
785 	zval *entry;
786 	zend_string *key;
787 	ZEND_HASH_FOREACH_STR_KEY_VAL(Z_ARRVAL_P(values), key, entry) {
788 		if (UNEXPECTED(key == NULL)) {
789 			continue;
790 		}
791 		yaf_request_set_params_single(request, key, entry);
792 	} ZEND_HASH_FOREACH_END();
793 	return 0;
794 }
795 /* }}} */
796 
yaf_request_get_param(yaf_request_object * request,zend_string * key)797 zval *yaf_request_get_param(yaf_request_object *request, zend_string *key) /* {{{ */ {
798 	if (request->params) {
799 		return zend_hash_find(request->params, key);
800 	}
801 	return NULL;
802 }
803 /* }}} */
804 
yaf_request_get_param_str(yaf_request_object * request,const char * key,size_t len)805 zval *yaf_request_get_param_str(yaf_request_object *request, const char *key, size_t len) /* {{{ */ {
806 	if (request->params) {
807 		return zend_hash_str_find(request->params, key, len);
808 	}
809 	return NULL;
810 }
811 /* }}} */
812 
yaf_request_get_request_method(void)813 const char *yaf_request_get_request_method(void) /* {{{ */ {
814 	if (SG(request_info).request_method) {
815 		return SG(request_info).request_method;
816 	}
817 #if 0
818 	else if (yaf_slip_equal(sapi_module.name, "cli", 4)) {
819 		return "CLI";
820 	} else {
821 		return "UNKNOWN";
822 	}
823 #endif
824 	return "CLI";
825 }
826 /* }}} */
827 
828 /** {{{ proto public Yaf_Request_Abstract::isGet(void)
829 */
830 YAF_REQUEST_IS_METHOD(Get);
831 /* }}} */
832 
833 /** {{{ proto public Yaf_Request_Abstract::isPost(void)
834 */
835 YAF_REQUEST_IS_METHOD(Post);
836 /* }}} */
837 
838 /** {{{ proto public Yaf_Request_Abstract::isPut(void)
839 */
840 YAF_REQUEST_IS_METHOD(Put);
841 /* }}} */
842 
843 /** {{{ proto public Yaf_Request_Abstract::isDelete(void)
844 */
845 YAF_REQUEST_IS_METHOD(Delete);
846 /* }}} */
847 
848 /** {{{ proto public Yaf_Request_Abstract::isPatch(void)
849 */
850 YAF_REQUEST_IS_METHOD(Patch);
851 /* }}} */
852 
853 /** {{{ proto public Yaf_Request_Abstract::isHead(void)
854 */
855 YAF_REQUEST_IS_METHOD(Head);
856 /* }}} */
857 
858 /** {{{ proto public Yaf_Request_Abstract::isOptions(void)
859 */
860 YAF_REQUEST_IS_METHOD(Options);
861 /* }}} */
862 
863 /** {{{ proto public Yaf_Request_Abstract::isCli(void)
864 */
865 YAF_REQUEST_IS_METHOD(Cli);
866 /* }}} */
867 
868 /** {{{ proto public Yaf_Request_Abstract::isXmlHttpRequest()
869 */
PHP_METHOD(yaf_request,isXmlHttpRequest)870 PHP_METHOD(yaf_request, isXmlHttpRequest) {
871 	zend_string *name;
872 	zval * header;
873 	name = zend_string_init("HTTP_X_REQUESTED_WITH", sizeof("HTTP_X_REQUESTED_WITH") - 1, 0);
874 	header = yaf_request_query(YAF_GLOBAL_VARS_SERVER, name);
875 	zend_string_release(name);
876 	if (header && Z_TYPE_P(header) == IS_STRING
877 			&& strncasecmp("XMLHttpRequest", Z_STRVAL_P(header), Z_STRLEN_P(header)) == 0) {
878 		RETURN_TRUE;
879 	}
880 	RETURN_FALSE;
881 }
882 /* }}} */
883 
884 /** {{{ proto public Yaf_Request_Abstract::getQuery(mixed $name, mixed $default = NULL)
885 */
886 YAF_REQUEST_METHOD(yaf_request, Query, 	YAF_GLOBAL_VARS_GET);
887 /* }}} */
888 
889 /** {{{ proto public Yaf_Request_Abstract::getPost(mixed $name, mixed $default = NULL)
890 */
891 YAF_REQUEST_METHOD(yaf_request, Post,  	YAF_GLOBAL_VARS_POST);
892 /* }}} */
893 
894 /** {{{ proto public Yaf_Request_Abstract::getRequet(mixed $name, mixed $default = NULL)
895 */
896 YAF_REQUEST_METHOD(yaf_request, Request, YAF_GLOBAL_VARS_REQUEST);
897 /* }}} */
898 
899 /** {{{ proto public Yaf_Request_Abstract::getFiles(mixed $name, mixed $default = NULL)
900 */
901 YAF_REQUEST_METHOD(yaf_request, Files, 	YAF_GLOBAL_VARS_FILES);
902 /* }}} */
903 
904 /** {{{ proto public Yaf_Request_Abstract::getCookie(mixed $name, mixed $default = NULL)
905 */
906 YAF_REQUEST_METHOD(yaf_request, Cookie, 	YAF_GLOBAL_VARS_COOKIE);
907 /* }}} */
908 
909 /** {{{ proto public Yaf_Request_Abstract::getRaw()
910 */
PHP_METHOD(yaf_request,getRaw)911 PHP_METHOD(yaf_request, getRaw) {
912 	php_stream *s;
913 	smart_str raw_data = {0};
914 
915 	if (zend_parse_parameters_none() == FAILURE) {
916 		return;
917 	}
918 
919 	s = SG(request_info).request_body;
920 	if (!s || FAILURE == php_stream_rewind(s)) {
921 		RETURN_FALSE;
922 	}
923 
924 	while (!php_stream_eof(s)) {
925 		char buf[512];
926 		size_t len = php_stream_read(s, buf, sizeof(buf));
927 
928 		if (len && len != (size_t) -1) {
929 			smart_str_appendl(&raw_data, buf, len);
930 		}
931 	}
932 
933 	if (raw_data.s) {
934 		smart_str_0(&raw_data);
935 		RETURN_STR(raw_data.s);
936 	} else {
937 		RETURN_FALSE;
938 	}
939 }
940 /* }}} */
941 
942 /** {{{ proto public Yaf_Request_Abstract::get(mixed $name, mixed $default)
943  * params -> post -> get -> cookie -> server
944  */
PHP_METHOD(yaf_request,get)945 PHP_METHOD(yaf_request, get) {
946 	zend_string	*name;
947 	zval *def = NULL;
948 
949 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|z", &name, &def) == FAILURE) {
950 		return;
951 	} else {
952 		zval *value = yaf_request_get_param(Z_YAFREQUESTOBJ_P(getThis()), name);
953 		if (value) {
954 			RETURN_ZVAL(value, 1, 0);
955 		} else {
956 			zval *params = NULL;
957 			zval *pzval	= NULL;
958 
959 			YAF_GLOBAL_VARS_TYPE methods[4] = {
960 				YAF_GLOBAL_VARS_POST,
961 				YAF_GLOBAL_VARS_GET,
962 				YAF_GLOBAL_VARS_COOKIE,
963 				YAF_GLOBAL_VARS_SERVER
964 			};
965 
966 			{
967 				int i = 0;
968 				for (;i < 4; i++) {
969 					params = &PG(http_globals)[methods[i]];
970 					if (params && Z_TYPE_P(params) == IS_ARRAY) {
971 						if ((pzval = zend_hash_find(Z_ARRVAL_P(params), name)) != NULL ){
972 							RETURN_ZVAL(pzval, 1, 0);
973 						}
974 					}
975 				}
976 
977 			}
978 			if (def) {
979 				RETURN_ZVAL(def, 1, 0);
980 			}
981 		}
982 	}
983 	RETURN_NULL();
984 }
985 /* }}} */
986 
987 /** {{{ proto public Yaf_Request_Abstract::getEnv(mixed $name, mixed $default = NULL)
988 */
989 YAF_REQUEST_METHOD(yaf_request, Env, 	YAF_GLOBAL_VARS_ENV);
990 /* }}} */
991 
992 /** {{{ proto public Yaf_Request_Abstract::getServer(mixed $name, mixed $default = NULL)
993 */
994 YAF_REQUEST_METHOD(yaf_request, Server, YAF_GLOBAL_VARS_SERVER);
995 /* }}} */
996 
997 /** {{{ proto public Yaf_Request_Abstract::getModuleName(void)
998 */
PHP_METHOD(yaf_request,getModuleName)999 PHP_METHOD(yaf_request, getModuleName) {
1000 	yaf_request_object *request = Z_YAFREQUESTOBJ_P(getThis());
1001 	zend_string *module = yaf_request_get_module(request);
1002 
1003 	if (zend_parse_parameters_none() == FAILURE) {
1004 		return;
1005 	}
1006 
1007 	if (UNEXPECTED(module == NULL)) {
1008 		RETURN_NULL();
1009 	}
1010 
1011 	RETURN_STR(module);
1012 }
1013 /* }}} */
1014 
1015 /** {{{ proto public Yaf_Request_Abstract::getControllerName(void)
1016 */
PHP_METHOD(yaf_request,getControllerName)1017 PHP_METHOD(yaf_request, getControllerName) {
1018 	yaf_request_object *request = Z_YAFREQUESTOBJ_P(getThis());
1019 	zend_string *controller = yaf_request_get_controller(request);
1020 
1021 	if (zend_parse_parameters_none() == FAILURE) {
1022 		return;
1023 	}
1024 
1025 	if (UNEXPECTED(controller == NULL)) {
1026 		RETURN_NULL();
1027 	}
1028 
1029 	RETURN_STR(controller);
1030 }
1031 /* }}} */
1032 
1033 /** {{{ proto public Yaf_Request_Abstract::getActionName(void)
1034 */
PHP_METHOD(yaf_request,getActionName)1035 PHP_METHOD(yaf_request, getActionName) {
1036 	yaf_request_object *request = Z_YAFREQUESTOBJ_P(getThis());
1037 	zend_string *action = yaf_request_get_action(request);
1038 
1039 	if (zend_parse_parameters_none() == FAILURE) {
1040 		return;
1041 	}
1042 
1043 	if (UNEXPECTED(action == NULL)) {
1044 		RETURN_NULL();
1045 	}
1046 
1047 	RETURN_STR(action);
1048 }
1049 /* }}} */
1050 
1051 /** {{{ proto public Yaf_Request_Abstract::setModuleName(string $module, bool $format_name = true)
1052 */
PHP_METHOD(yaf_request,setModuleName)1053 PHP_METHOD(yaf_request, setModuleName) {
1054 	zend_string *module;
1055 	zend_bool format_name = 1;
1056 	yaf_request_object *request = Z_YAFREQUESTOBJ_P(getThis());
1057 
1058 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|b", &module, &format_name) == FAILURE) {
1059 		return;
1060 	}
1061 
1062 	if (EXPECTED(ZSTR_LEN(module))) {
1063 		if (format_name) {
1064 			yaf_request_set_module(request, module);
1065 		} else {
1066 			if (request->module) {
1067 				zend_string_release(request->module);
1068 				request->module = zend_string_copy(module);
1069 			}
1070 		}
1071 	}
1072 
1073 	RETURN_ZVAL(getThis(), 1, 0);
1074 }
1075 /* }}} */
1076 
1077 /** {{{ proto public Yaf_Request_Abstract::setControllerName(string $controller, bool $format_name = true)
1078 */
PHP_METHOD(yaf_request,setControllerName)1079 PHP_METHOD(yaf_request, setControllerName) {
1080 	zend_string *controller;
1081 	zend_bool format_name = 1;
1082 	yaf_request_object *request = Z_YAFREQUESTOBJ_P(getThis());
1083 
1084 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|b", &controller, &format_name) == FAILURE) {
1085 		return;
1086 	}
1087 
1088 	if (EXPECTED(ZSTR_LEN(controller))) {
1089 		if (format_name) {
1090 			yaf_request_set_controller(request, controller);
1091 		} else {
1092 			if (request->controller) {
1093 				zend_string_release(request->controller);
1094 				request->controller = zend_string_copy(controller);
1095 			}
1096 		}
1097 	}
1098 
1099 	RETURN_ZVAL(getThis(), 1, 0);
1100 }
1101 /* }}} */
1102 
1103 /** {{{ proto public Yaf_Request_Abstract::setActionName(string $action, bool $format_name = true)
1104 */
PHP_METHOD(yaf_request,setActionName)1105 PHP_METHOD(yaf_request, setActionName) {
1106 	zend_string *action;
1107 	zend_bool format_name = 1;
1108 	yaf_request_object *request = Z_YAFREQUESTOBJ_P(getThis());
1109 
1110 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|b", &action, &format_name) == FAILURE) {
1111 		return;
1112 	}
1113 
1114 	if (EXPECTED(ZSTR_LEN(action))) {
1115 		if (format_name) {
1116 			yaf_request_set_action(request, action);
1117 		} else {
1118 			if (request->action) {
1119 				zend_string_release(request->action);
1120 				request->action = zend_string_copy(action);
1121 			}
1122 		}
1123 	}
1124 
1125 	RETURN_ZVAL(getThis(), 1, 0);
1126 }
1127 /* }}} */
1128 
1129 /** {{{ proto public Yaf_Request_Abstract::setParam(mixed $value)
1130 */
PHP_METHOD(yaf_request,setParam)1131 PHP_METHOD(yaf_request, setParam) {
1132 	unsigned argc;
1133 
1134 	argc = ZEND_NUM_ARGS();
1135 
1136 	if (1 == argc) {
1137 		zval *value ;
1138 		if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &value) == FAILURE) {
1139 			return;
1140 		}
1141 		if (yaf_request_set_params_multi(Z_YAFREQUESTOBJ_P(getThis()), value)) {
1142 			RETURN_ZVAL(getThis(), 1, 0);
1143 		}
1144 	} else if (2 == argc) {
1145 		zval *value;
1146 		zend_string *name;
1147 		if (zend_parse_parameters(ZEND_NUM_ARGS(), "Sz", &name, &value) == FAILURE) {
1148 			return;
1149 		}
1150 
1151 		if (yaf_request_set_params_single(Z_YAFREQUESTOBJ_P(getThis()), name, value)) {
1152 			RETURN_ZVAL(getThis(), 1, 0);
1153 		}
1154 	} else {
1155 		WRONG_PARAM_COUNT;
1156 	}
1157 
1158 	RETURN_FALSE;
1159 }
1160 /* }}} */
1161 
1162 /** {{{ proto public Yaf_Request_Abstract::getParam(string $name, $mixed $default = NULL)
1163 */
PHP_METHOD(yaf_request,getParam)1164 PHP_METHOD(yaf_request, getParam) {
1165 	zend_string *name;
1166 	zval *def = NULL;
1167 
1168 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "S|z", &name, &def) == FAILURE) {
1169 		return;
1170 	} else {
1171 		zval *value = yaf_request_get_param(Z_YAFREQUESTOBJ_P(getThis()), name);
1172 		if (value) {
1173 			RETURN_ZVAL(value, 1, 0);
1174 		}
1175 		if (def) {
1176 			RETURN_ZVAL(def, 1, 0);
1177 		}
1178 	}
1179 
1180 	RETURN_NULL();
1181 }
1182 /* }}} */
1183 
1184 /** {{{ proto public Yaf_Request_Abstract::getException(void)
1185 */
PHP_METHOD(yaf_request,getException)1186 PHP_METHOD(yaf_request, getException) {
1187 	zval *exception;
1188 	yaf_request_object *request = Z_YAFREQUESTOBJ_P(getThis());
1189 
1190 	if (zend_parse_parameters_none() == FAILURE) {
1191 		return;
1192 	}
1193 
1194 	if ((exception = yaf_request_get_param_str(request, ZEND_STRL("exception")))) {
1195 		RETURN_ZVAL(exception, 1, 0);
1196 	}
1197 
1198 	RETURN_NULL();
1199 }
1200 /* }}} */
1201 
1202 /** {{{ proto public Yaf_Request_Abstract::getParams(void)
1203 */
PHP_METHOD(yaf_request,getParams)1204 PHP_METHOD(yaf_request, getParams) {
1205 	yaf_request_object *request = Z_YAFREQUESTOBJ_P(getThis());
1206 
1207 	if (zend_parse_parameters_none() == FAILURE) {
1208 		return;
1209 	}
1210 
1211 	if (request->params) {
1212 		GC_ADDREF(request->params);
1213 		RETURN_ARR(request->params);
1214 	}
1215 #if PHP_VERSION_ID < 70400
1216 	array_init(return_value);
1217 #else
1218 	RETURN_EMPTY_ARRAY();
1219 #endif
1220 }
1221 /* }}} */
1222 
1223 /** {{{ proto public Yaf_Request_Abstract::clearParams(void)
1224 */
PHP_METHOD(yaf_request,clearParams)1225 PHP_METHOD(yaf_request, clearParams) {
1226 	yaf_request_object *request = Z_YAFREQUESTOBJ_P(getThis());
1227 
1228 	if (zend_parse_parameters_none() == FAILURE) {
1229 		return;
1230 	}
1231 
1232 	yaf_request_clean_params(request);
1233 	RETURN_ZVAL(getThis(), 1, 0);
1234 }
1235 /* }}} */
1236 
1237 /** {{{ proto public Yaf_Request_Abstract::getLanguage(void)
1238 */
PHP_METHOD(yaf_request,getLanguage)1239 PHP_METHOD(yaf_request, getLanguage) {
1240 	yaf_request_object *request = Z_YAFREQUESTOBJ_P(getThis());
1241 	zend_string *language = yaf_request_get_language(request);
1242 
1243 	if (zend_parse_parameters_none() == FAILURE) {
1244 		return;
1245 	}
1246 
1247 	if (UNEXPECTED(language == NULL)) {
1248 		RETURN_NULL();
1249 	}
1250 
1251 	RETURN_STR(language);
1252 }
1253 /* }}} */
1254 
1255 /** {{{ proto public Yaf_Request_Abstract::getMethod(void)
1256 */
PHP_METHOD(yaf_request,getMethod)1257 PHP_METHOD(yaf_request, getMethod) {
1258 	if (zend_parse_parameters_none() == FAILURE) {
1259 		return;
1260 	}
1261 	RETURN_STR(yaf_request_get_method(Z_YAFREQUESTOBJ_P(getThis())));
1262 }
1263 /* }}} */
1264 
1265 /** {{{ proto public Yaf_Request_Abstract::isDispatched(void)
1266 */
PHP_METHOD(yaf_request,isDispatched)1267 PHP_METHOD(yaf_request, isDispatched) {
1268 	if (zend_parse_parameters_none() == FAILURE) {
1269 		return;
1270 	}
1271 	RETURN_BOOL(yaf_request_is_dispatched(Z_YAFREQUESTOBJ_P(getThis())));
1272 }
1273 /* }}} */
1274 
1275 /** {{{ proto public Yaf_Request_Abstract::setDispatched(bool $dispatched = true)
1276 */
PHP_METHOD(yaf_request,setDispatched)1277 PHP_METHOD(yaf_request, setDispatched) {
1278 	zend_bool state = 1;
1279 
1280 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &state) == FAILURE){
1281 		return;
1282 	}
1283 
1284 	yaf_request_set_dispatched(Z_YAFREQUESTOBJ_P(getThis()), state);
1285 
1286 	RETURN_ZVAL(getThis(), 1, 0);
1287 }
1288 /* }}} */
1289 
1290 /** {{{ proto public Yaf_Request_Abstract::setBaseUri(string $name)
1291 */
PHP_METHOD(yaf_request,setBaseUri)1292 PHP_METHOD(yaf_request, setBaseUri) {
1293 	zend_string *uri;
1294 
1295 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &uri) == FAILURE) {
1296 		return;
1297 	}
1298 
1299 	if (ZSTR_LEN(uri) == 0) {
1300 		RETURN_FALSE;
1301 	}
1302 
1303 	if (yaf_request_set_base_uri(Z_YAFREQUESTOBJ_P(getThis()), uri, NULL)) {
1304 		RETURN_ZVAL(getThis(), 1, 0);
1305 	}
1306 
1307 	RETURN_FALSE;
1308 }
1309 /* }}} */
1310 
1311 /** {{{ proto public Yaf_Request_Abstract::getBaseUri(void)
1312 */
PHP_METHOD(yaf_request,getBaseUri)1313 PHP_METHOD(yaf_request, getBaseUri) {
1314 	yaf_request_object *request = Z_YAFREQUESTOBJ_P(getThis());
1315 	zend_string *base_uri = yaf_request_get_base_uri(request);
1316 
1317 	if (zend_parse_parameters_none() == FAILURE) {
1318 		return;
1319 	}
1320 
1321 	if (UNEXPECTED(base_uri == NULL)) {
1322 		RETURN_EMPTY_STRING();
1323 	}
1324 
1325 	RETURN_STR(base_uri);
1326 }
1327 /* }}} */
1328 
1329 /** {{{ proto public Yaf_Request_Abstract::getRequestUri(void)
1330 */
PHP_METHOD(yaf_request,getRequestUri)1331 PHP_METHOD(yaf_request, getRequestUri) {
1332 	yaf_request_object *request = Z_YAFREQUESTOBJ_P(getThis());
1333 	zend_string *uri = yaf_request_get_uri(request);
1334 
1335 	if (zend_parse_parameters_none() == FAILURE) {
1336 		return;
1337 	}
1338 
1339 	if (UNEXPECTED(uri == NULL)) {
1340 		RETURN_EMPTY_STRING();
1341 	}
1342 
1343 	RETURN_STR(uri);
1344 }
1345 /* }}} */
1346 
1347 /** {{{ proto public Yaf_Request_Abstract::setRequestUri(string $name)
1348 */
PHP_METHOD(yaf_request,setRequestUri)1349 PHP_METHOD(yaf_request, setRequestUri) {
1350 	zend_string *uri;
1351 	yaf_request_object *req = Z_YAFREQUESTOBJ_P(getThis());
1352 
1353 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &uri) == FAILURE) {
1354 		return;
1355 	}
1356 
1357 	yaf_request_set_uri(req, uri);
1358 
1359 	RETURN_ZVAL(getThis(), 1, 0);
1360 }
1361 /* }}} */
1362 
1363 /** {{{ proto public Yaf_Request_Abstract::isRouted(void)
1364 */
PHP_METHOD(yaf_request,isRouted)1365 PHP_METHOD(yaf_request, isRouted) {
1366 	if (zend_parse_parameters_none() == FAILURE) {
1367 		return;
1368 	}
1369 	RETURN_BOOL(yaf_request_is_routed(Z_YAFREQUESTOBJ_P(getThis())));
1370 }
1371 /* }}} */
1372 
1373 /** {{{ proto public Yaf_Request_Abstract::setRouted(bool $routed = true)
1374 */
PHP_METHOD(yaf_request,setRouted)1375 PHP_METHOD(yaf_request, setRouted) {
1376 	zend_bool state = 1;
1377 
1378 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &state) == FAILURE){
1379 		return;
1380 	}
1381 
1382 	yaf_request_set_routed(Z_YAFREQUESTOBJ_P(getThis()), state);
1383 	RETURN_ZVAL(getThis(), 1, 0);
1384 }
1385 /* }}} */
1386 
1387 /** {{{ yaf_request_methods
1388 */
1389 zend_function_entry yaf_request_methods[] = {
1390 	PHP_ME(yaf_request, isGet, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1391 	PHP_ME(yaf_request, isPost, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1392 	PHP_ME(yaf_request, isDelete, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1393 	PHP_ME(yaf_request, isPatch, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1394 	PHP_ME(yaf_request, isPut, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1395 	PHP_ME(yaf_request, isHead, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1396 	PHP_ME(yaf_request, isOptions, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1397 	PHP_ME(yaf_request, isCli, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1398 	PHP_ME(yaf_request, isXmlHttpRequest, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1399 	PHP_ME(yaf_request, getQuery, yaf_request_get_arginfo, ZEND_ACC_PUBLIC)
1400 	PHP_ME(yaf_request, getRequest, yaf_request_get_arginfo, ZEND_ACC_PUBLIC)
1401 	PHP_ME(yaf_request, getPost, yaf_request_get_arginfo, ZEND_ACC_PUBLIC)
1402 	PHP_ME(yaf_request, getCookie, yaf_request_get_arginfo, ZEND_ACC_PUBLIC)
1403 	PHP_ME(yaf_request, getRaw, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1404 	PHP_ME(yaf_request, getFiles, yaf_request_get_arginfo, ZEND_ACC_PUBLIC)
1405 	PHP_ME(yaf_request, get, yaf_request_get_arginfo, ZEND_ACC_PUBLIC)
1406 	PHP_ME(yaf_request, getServer, yaf_request_get_arginfo, ZEND_ACC_PUBLIC)
1407 	PHP_ME(yaf_request, getEnv, yaf_request_get_arginfo, ZEND_ACC_PUBLIC)
1408 	PHP_ME(yaf_request, setParam, yaf_request_set_param_arginfo, ZEND_ACC_PUBLIC)
1409 	PHP_ME(yaf_request, getParam, yaf_request_get_arginfo, ZEND_ACC_PUBLIC)
1410 	PHP_ME(yaf_request, getParams, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1411 	PHP_ME(yaf_request, clearParams, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1412 	PHP_ME(yaf_request, getException, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1413 	PHP_ME(yaf_request, getModuleName, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1414 	PHP_ME(yaf_request, getControllerName, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1415 	PHP_ME(yaf_request, getActionName, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1416 	PHP_ME(yaf_request, setModuleName, yaf_request_set_module_name_arginfo, ZEND_ACC_PUBLIC)
1417 	PHP_ME(yaf_request, setControllerName, yaf_request_set_controller_arginfo, ZEND_ACC_PUBLIC)
1418 	PHP_ME(yaf_request, setActionName, yaf_request_set_action_arginfo, ZEND_ACC_PUBLIC)
1419 	PHP_ME(yaf_request, getMethod, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1420 	PHP_ME(yaf_request, getLanguage, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1421 	PHP_ME(yaf_request, setBaseUri, yaf_request_set_baseuri_arginfo, ZEND_ACC_PUBLIC)
1422 	PHP_ME(yaf_request, getBaseUri, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1423 	PHP_ME(yaf_request, getRequestUri, yaf_request_void_arginfo, ZEND_ACC_PUBLIC)
1424 	PHP_ME(yaf_request, setRequestUri, yaf_request_set_request_uri_arginfo, ZEND_ACC_PUBLIC)
1425 	PHP_ME(yaf_request, isDispatched, yaf_request_void_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
1426 	PHP_ME(yaf_request, setDispatched, yaf_request_set_dispatched_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
1427 	PHP_ME(yaf_request, isRouted, yaf_request_void_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
1428 	PHP_ME(yaf_request, setRouted, yaf_request_set_routed_arginfo, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL)
1429 	{NULL, NULL, NULL}
1430 };
1431 /* }}} */
1432 
1433 /** {{{ YAF_STARTUP_FUNCTION
1434 */
YAF_STARTUP_FUNCTION(request)1435 YAF_STARTUP_FUNCTION(request){
1436 	zend_class_entry ce;
1437 
1438 	YAF_INIT_CLASS_ENTRY(ce, "Yaf_Request_Abstract", "Yaf\\Request_Abstract", yaf_request_methods);
1439 	yaf_request_ce	= zend_register_internal_class_ex(&ce, NULL);
1440 	yaf_request_ce->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;
1441 
1442 	yaf_request_ce->create_object = yaf_request_new;
1443 	yaf_request_ce->serialize = zend_class_serialize_deny;
1444 	yaf_request_ce->unserialize = zend_class_unserialize_deny;
1445 
1446 	memcpy(&yaf_request_obj_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
1447 	yaf_request_obj_handlers.offset = XtOffsetOf(yaf_request_object, std);
1448 	yaf_request_obj_handlers.free_obj = yaf_request_object_free;
1449 	yaf_request_obj_handlers.get_properties = yaf_request_get_properties;;
1450 	yaf_request_obj_handlers.read_property = (zend_object_read_property_t)yaf_request_read_property;
1451 	yaf_request_obj_handlers.write_property = (zend_object_write_property_t)yaf_request_write_property;
1452 	yaf_request_obj_handlers.get_gc = yaf_request_get_gc;
1453 	yaf_request_obj_handlers.clone_obj = NULL;
1454 
1455 	YAF_STARTUP(request_http);
1456 	YAF_STARTUP(request_simple);
1457 
1458 	return SUCCESS;
1459 }
1460 /* }}} */
1461 
1462 /*
1463  * Local variables:
1464  * tab-width: 4
1465  * c-basic-offset: 4
1466  * End:
1467  * vim600: noet sw=4 ts=4 fdm=marker
1468  * vim<600: noet sw=4 ts=4
1469  */
1470