Пример #1
0
static int yaf_route_pathinfo_route(yaf_request_t *request, char *req_uri, int req_uri_len TSRMLS_DC) /* {{{ */ {
	zval *params;
	char *module = NULL, *controller = NULL, *action = NULL, *rest = NULL;

	do {
#define strip_slashs(p) while (*p == ' ' || *p == '/') { ++p; }
		char *s, *p, *q;
		char *uri;

		if (req_uri_len == 0
				|| (req_uri_len == 1 && *req_uri == '/')) {
			break;
		}

		uri = req_uri;
		s = p = uri;
		q = req_uri + req_uri_len - 1;

		while (*q == ' ' || *q == '/') {
			*q-- = '\0';
		}

		strip_slashs(p);

		if ((s = strstr(p, "/")) != NULL) {
			if (yaf_application_is_module_name(p, s-p TSRMLS_CC)) {
				module = estrndup(p, s - p);
				p  = s + 1;
		        strip_slashs(p);
				if ((s = strstr(p, "/")) != NULL) {
					controller = estrndup(p, s - p);
					p  = s + 1;
				}
			} else {
				controller = estrndup(p, s - p);
				p  = s + 1;
			}
		}

		strip_slashs(p);
		if ((s = strstr(p, "/")) != NULL) {
			action = estrndup(p, s - p);
			p  = s + 1;
		}

		strip_slashs(p);
		if (*p != '\0') {
			do {
				if (!module && !controller && !action) {
					if (yaf_application_is_module_name(p, strlen(p) TSRMLS_CC)) {
						module = estrdup(p);
						break;
					}
				}

				if (!controller) {
					controller = estrdup(p);
					break;
				}

				if (!action) {
					action = estrdup(p);
					break;
				}

				rest = estrdup(p);
			} while (0);
		}

		if (module && controller == NULL) {
			controller = module;
			module = NULL;
		} else if (module && action == NULL) {
			action = controller;
			controller = module;
			module = NULL;
	    } else if (controller && action == NULL ) {
			/* /controller */
			if (YAF_G(action_prefer)) {
				action = controller;
				controller = NULL;
			}
		}
	} while (0);

	if (module != NULL) {
		zend_update_property_string(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_MODULE), module TSRMLS_CC);
		efree(module);
	}
	if (controller != NULL) {
		zend_update_property_string(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), controller TSRMLS_CC);
		efree(controller);
	}

	if (action != NULL) {
		zend_update_property_string(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), action TSRMLS_CC);
		efree(action);
	}

	if (rest) {
		params = yaf_router_parse_parameters(rest TSRMLS_CC);
		(void)yaf_request_set_params_multi(request, params TSRMLS_CC);
		zval_ptr_dtor(&params);
		efree(rest);
	}

}
Пример #2
0
/** {{{ int yaf_route_map_route(yaf_route_t *route, yaf_request_t *request)
*/
int yaf_route_map_route(yaf_route_t *route, yaf_request_t *request) {
	zval *ctl_prefer, *delimer, *zuri, *base_uri, params;
	char *req_uri, *tmp, *rest, *ptrptr, *seg;
	char *query_str = NULL;
	uint seg_len = 0;

	smart_str route_result = {0};

	zuri = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_URI), 1, NULL);
	base_uri = zend_read_property(yaf_request_ce, request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_BASE), 1, NULL);

	ctl_prefer = zend_read_property(yaf_route_map_ce, route, ZEND_STRL(YAF_ROUTE_MAP_VAR_NAME_CTL_PREFER), 1, NULL);
	delimer	   = zend_read_property(yaf_route_map_ce, route, ZEND_STRL(YAF_ROUTE_MAP_VAR_NAME_DELIMETER), 1, NULL);

	if (base_uri && IS_STRING == Z_TYPE_P(base_uri)
			&& !strncasecmp(Z_STRVAL_P(zuri), Z_STRVAL_P(base_uri), Z_STRLEN_P(base_uri))) {
		req_uri  = estrdup(Z_STRVAL_P(zuri) + Z_STRLEN_P(base_uri));
	} else {
		req_uri  = estrdup(Z_STRVAL_P(zuri));
	}

	if (Z_TYPE_P(delimer) == IS_STRING
			&& Z_STRLEN_P(delimer)) {
		if ((query_str = strstr(req_uri, Z_STRVAL_P(delimer))) != NULL
			&& *(query_str - 1) == '/') {
			tmp  = req_uri;
			rest = query_str + Z_STRLEN_P(delimer);
			if (*rest == '\0') {
				req_uri 	= estrndup(req_uri, query_str - req_uri);
				query_str 	= NULL;
				efree(tmp);
			} else if (*rest == '/') {
				req_uri 	= estrndup(req_uri, query_str - req_uri);
				query_str   = estrdup(rest);
				efree(tmp);
			} else {
				query_str = NULL;
			}
		} else {
			query_str = NULL;
		}
	}

	seg = php_strtok_r(req_uri, YAF_ROUTER_URL_DELIMIETER, &ptrptr);
	while (seg) {
		seg_len = strlen(seg);
		if (seg_len) {
			smart_str_appendl(&route_result, seg, seg_len);
		}
		smart_str_appendc(&route_result, '_');
		seg = php_strtok_r(NULL, YAF_ROUTER_URL_DELIMIETER, &ptrptr);
	}

	if (route_result.s) {
		ZSTR_LEN(route_result.s)--;
		ZSTR_VAL(route_result.s)[ZSTR_LEN(route_result.s)] = '\0';
		if (Z_TYPE_P(ctl_prefer) == IS_TRUE) {
			zend_update_property_str(yaf_request_ce,
					request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_CONTROLLER), route_result.s);
		} else {
			zend_update_property_str(yaf_request_ce,
					request, ZEND_STRL(YAF_REQUEST_PROPERTY_NAME_ACTION), route_result.s);
		}
		smart_str_free(&route_result);
	}

	if (query_str) {
		(void)yaf_router_parse_parameters(query_str, &params);
		(void)yaf_request_set_params_multi(request, &params);
		zval_ptr_dtor(&params);
		efree(query_str);
	}

	efree(req_uri);

	return 1;
}
Пример #3
0
static bool yaf_route_map_route(const Object& o, const Object& request)
{
    auto ptr_uri = request->o_realProp(YAF_REQUEST_PROPERTY_NAME_URI, 
            ObjectData::RealPropUnchecked, "Yaf_Request_Abstract");

    auto ptr_base_uri = request->o_realProp(YAF_REQUEST_PROPERTY_NAME_BASE, 
            ObjectData::RealPropUnchecked, "Yaf_Request_Abstract");

    auto ptr_ctl_prefer = o->o_realProp(YAF_ROUTE_MAP_VAR_NAME_CTL_PREFER, 
             ObjectData::RealPropUnchecked, "Yaf_Route_Map");

    auto ptr_delim = o->o_realProp(YAF_ROUTE_MAP_VAR_NAME_DELIMETER, 
             ObjectData::RealPropUnchecked, "Yaf_Route_Map");

    if (ptr_uri == NULL) {
        raise_warning("invalid uri:%p", ptr_uri);
        return false;
    }

    std::string req_uri;
    if (ptr_uri && ptr_uri->isString() && 
        ptr_base_uri && 
        ptr_base_uri->isString()&&
        strncasecmp(ptr_uri->toString().c_str(), 
            ptr_base_uri->toString().c_str(), ptr_base_uri->toString().length()) == 0) {
        req_uri = std::string(ptr_uri->toString().c_str() + ptr_base_uri->toString().length()); 
    } else {
        req_uri = std::string(ptr_uri->toString().c_str());
    }

    if (req_uri.length() == 0) {
        return false;
    }

    std::string str_query_str;
    if (ptr_delim->isString() && ptr_delim->toString().length()) {
        const char* str_delim = ptr_delim->toString().c_str();
        char* tmp_req_uri = strdup(req_uri.c_str());
        char* query_str = strstr(tmp_req_uri, str_delim);
        if (query_str && *(query_str - 1) == '/') {
            char* rest = query_str + strlen(str_delim);
            if (*rest == '\0') {
                req_uri = std::string(req_uri, query_str - tmp_req_uri);
                query_str = NULL;
            } else if(*rest == '/') {
                req_uri = std::string(req_uri, query_str - tmp_req_uri);
                str_query_str  = std::string(rest);
            } else {
                query_str = NULL;
            }
        }
        
        free(tmp_req_uri);
    }

    std::string route_result;
    char* save_ptr = NULL;
    char* tmp = strdup(req_uri.c_str());
    char* seg = strtok_r(tmp, YAF_ROUTER_URL_DELIMIETER, &save_ptr);
    while (seg) {
        int seg_len = strlen(seg);
        if (seg_len) {
            route_result += seg;
        }

        route_result += "_";
        seg = strtok_r(NULL, YAF_ROUTER_URL_DELIMIETER, &save_ptr);
    }

    free(tmp);
    if (route_result.length()) {
        if (route_result[route_result.length() - 1] == '_') {
            route_result.pop_back();
        }

        if (ptr_ctl_prefer->toBoolean()) {
            auto ptr_controller = request->o_realProp(YAF_REQUEST_PROPERTY_NAME_CONTROLLER, 
                        ObjectData::RealPropUnchecked, "Yaf_Request_Abstract");
            *ptr_controller = String(route_result);
        } else {
            auto ptr_action = request->o_realProp(YAF_REQUEST_PROPERTY_NAME_ACTION, 
                        ObjectData::RealPropUnchecked, "Yaf_Request_Abstract");
            *ptr_action = String(route_result);
        }
    }

    if (str_query_str.length()) {
        Array arr = yaf_router_parse_parameters(str_query_str.c_str()); 
        yaf_request_set_params_multi(&request, arr);
    }

    return true;
}
Пример #4
0
static Variant yaf_route_rewrite_match(const Object& o, 
        const char* req_uri, int req_uri_len)
{
    char match[8192];
    auto ptr_match = o->o_realProp(YAF_ROUTE_PROPETY_NAME_MATCH,
                    ObjectData::RealPropUnchecked, "Yaf_Route_Rewrite");
    snprintf(match, sizeof(match), "%s", ptr_match->toString().c_str());

    std::string pattern;
    pattern.append(YAF_ROUTE_REGEX_DILIMITER_STR);
    pattern.append("^");

    char* save_ptr;
    char* seg = strtok_r(match, YAF_ROUTER_URL_DELIMIETER, &save_ptr);
    while (seg != NULL) {
        int len = strlen(seg);
        if (len) {
            pattern.append(YAF_ROUTER_URL_DELIMIETER);
            if (*seg == '*') {
                pattern.append("(?P<__yaf_route_rest>.*)");
                break;
            }

            if (*seg == ':') {
                pattern.append("(?P<");
                pattern.append(std::string(seg+1));
                pattern.append(std::string(">[^") + YAF_ROUTER_URL_DELIMIETER + "]+)");
            } else {
                pattern.append(seg);
            }
        }

        seg = strtok_r(NULL, YAF_ROUTER_URL_DELIMIETER, &save_ptr);
    }

    pattern.append(YAF_ROUTE_REGEX_DILIMITER_STR);
    pattern.append("i");

    Variant matches;
    Variant ret = preg_match_all(String(pattern), 
                   String(std::string(req_uri, req_uri_len)), matches);
    int match_count = 0;
    if (ret.isIntVal() ) {
        match_count = ret.toInt32();
    }

    if (match_count <= 0) {
        return init_null_variant;
    }

    if (!matches.isArray()) {
        return init_null_variant;
    }

    Array args = Array::Create();
    Array& arr_matches = matches.toArrRef();
    ArrayIter iter = arr_matches.begin();
    while (!iter.end()) {
        Variant key = iter.first();
        Variant value = iter.second();
        
        if (!key.isString()) {
            iter.next();
            continue;
        }

        if (!strncmp(key.toString().c_str(), "__yaf_route_rest", key.toString().length())) {
            Variant retval = yaf_router_parse_parameters(value.toArrRef()[0].toString().c_str());
            if (retval.isArray()) {
                args.merge(retval.toArray());
            }
        } else {
            args.set(key, value.toArrRef()[0]);
        }

        iter.next();
    }

    return args;
}