import 2.0 devl branch, suitable for PHP-trunk
[m6w6/ext-http] / php_http_request_method.c
1 /*
2 +--------------------------------------------------------------------+
3 | PECL :: http |
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) 2004-2010, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 /* $Id: http_request_method_api.c 292841 2009-12-31 08:48:57Z mike $ */
14
15 #include "php_http.h"
16
17 static PHP_HTTP_STRLIST(php_http_request_methods) =
18 PHP_HTTP_STRLIST_ITEM("UNKNOWN")
19 /* HTTP/1.1 */
20 PHP_HTTP_STRLIST_ITEM("GET")
21 PHP_HTTP_STRLIST_ITEM("HEAD")
22 PHP_HTTP_STRLIST_ITEM("POST")
23 PHP_HTTP_STRLIST_ITEM("PUT")
24 PHP_HTTP_STRLIST_ITEM("DELETE")
25 PHP_HTTP_STRLIST_ITEM("OPTIONS")
26 PHP_HTTP_STRLIST_ITEM("TRACE")
27 PHP_HTTP_STRLIST_ITEM("CONNECT")
28 /* WebDAV - RFC 2518 */
29 PHP_HTTP_STRLIST_ITEM("PROPFIND")
30 PHP_HTTP_STRLIST_ITEM("PROPPATCH")
31 PHP_HTTP_STRLIST_ITEM("MKCOL")
32 PHP_HTTP_STRLIST_ITEM("COPY")
33 PHP_HTTP_STRLIST_ITEM("MOVE")
34 PHP_HTTP_STRLIST_ITEM("LOCK")
35 PHP_HTTP_STRLIST_ITEM("UNLOCK")
36 /* WebDAV Versioning - RFC 3253 */
37 PHP_HTTP_STRLIST_ITEM("VERSION-CONTROL")
38 PHP_HTTP_STRLIST_ITEM("REPORT")
39 PHP_HTTP_STRLIST_ITEM("CHECKOUT")
40 PHP_HTTP_STRLIST_ITEM("CHECKIN")
41 PHP_HTTP_STRLIST_ITEM("UNCHECKOUT")
42 PHP_HTTP_STRLIST_ITEM("MKWORKSPACE")
43 PHP_HTTP_STRLIST_ITEM("UPDATE")
44 PHP_HTTP_STRLIST_ITEM("LABEL")
45 PHP_HTTP_STRLIST_ITEM("MERGE")
46 PHP_HTTP_STRLIST_ITEM("BASELINE-CONTROL")
47 PHP_HTTP_STRLIST_ITEM("MKACTIVITY")
48 /* WebDAV Access Control - RFC 3744 */
49 PHP_HTTP_STRLIST_ITEM("ACL")
50 PHP_HTTP_STRLIST_STOP
51 ;
52
53 PHP_HTTP_API const char *php_http_request_method_name(php_http_request_method_t meth)
54 {
55 if (meth > PHP_HTTP_NO_REQUEST_METHOD && meth < PHP_HTTP_MAX_REQUEST_METHOD) {
56 return php_http_strlist_find(php_http_request_methods, 1, meth);
57 } else {
58 zval **val, *cmp, res;
59 HashPosition pos;
60 php_http_array_hashkey_t key = php_http_array_hashkey_init(0);
61
62 INIT_PZVAL(&res);
63 FOREACH_HASH_KEYVAL(pos, &php_http_request_class_entry->constants_table, key, val) {
64 MAKE_STD_ZVAL(cmp);
65 ZVAL_LONG(cmp, meth);
66 is_equal_function(&res, *val, cmp TSRMLS_CC);
67 zval_ptr_dtor(&cmp);
68
69 if (Z_LVAL(res)) {
70 return key.str;
71 }
72 }
73 }
74 return NULL;
75 }
76
77 PHP_HTTP_API STATUS php_http_request_method_register(const char *meth_str, size_t meth_len, long *id TSRMLS_DC)
78 {
79 long num = zend_hash_num_elements(&php_http_request_class_entry->constants_table);
80
81 if (SUCCESS == zend_declare_class_constant_long(php_http_request_method_class_entry, meth_str, meth_len, num TSRMLS_CC)) {
82 if (id) {
83 *id = num;
84 }
85 return SUCCESS;
86 }
87 return FAILURE;
88 }
89
90 zend_class_entry *php_http_request_method_class_entry;
91
92 #define PHP_HTTP_BEGIN_ARGS(method, req_args) PHP_HTTP_BEGIN_ARGS_EX(HttpRequestMethod, method, 0, req_args)
93 #define PHP_HTTP_EMPTY_ARGS(method) PHP_HTTP_EMPTY_ARGS_EX(HttpRequestMethod, method, 0)
94 #define PHP_HTTP_REQMETH_ME(method, visibility) PHP_ME(HttpRequestMethod, method, PHP_HTTP_ARGS(HttpRequestMethod, method), visibility)
95
96 #ifdef register
97 # undef register
98 #endif
99
100 PHP_HTTP_BEGIN_ARGS(__construct, 1)
101 PHP_HTTP_ARG_VAL(name, 0)
102 PHP_HTTP_END_ARGS;
103
104 PHP_HTTP_EMPTY_ARGS(__toString);
105
106 PHP_HTTP_EMPTY_ARGS(getId);
107
108 PHP_HTTP_BEGIN_ARGS(exists, 1)
109 PHP_HTTP_ARG_VAL(method, 0)
110 PHP_HTTP_END_ARGS;
111
112 PHP_HTTP_BEGIN_ARGS(register, 1)
113 PHP_HTTP_ARG_VAL(method, 0)
114 PHP_HTTP_END_ARGS;
115
116 zend_function_entry php_http_request_method_method_entry[] = {
117 PHP_HTTP_REQMETH_ME(__construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
118 PHP_HTTP_REQMETH_ME(__toString, ZEND_ACC_PUBLIC)
119 PHP_HTTP_REQMETH_ME(getId, ZEND_ACC_PUBLIC)
120 PHP_HTTP_REQMETH_ME(exists, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
121 PHP_HTTP_REQMETH_ME(register, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
122
123 EMPTY_FUNCTION_ENTRY
124 };
125
126 PHP_METHOD(HttpRequestMethod, __construct)
127 {
128 with_error_handling(EH_THROW, PHP_HTTP_EX_CE(runtime)) {
129 char *meth_str;
130 int meth_len;
131
132 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &meth_str, &meth_len)) {
133 with_error_handling(EH_THROW, PHP_HTTP_EX_CE(request_method)) {
134 zval *zarg, *zret;
135
136 if (SUCCESS == zend_get_parameters(ZEND_NUM_ARGS(), 1, &zarg)) {
137 if (zend_call_method_with_1_params(&getThis(), php_http_request_method_class_entry, NULL, "exists", &zret, zarg)) {
138 if (i_zend_is_true(zret)) {
139 zend_update_property_stringl(php_http_request_method_class_entry, getThis(), ZEND_STRL("name"), meth_str, meth_len TSRMLS_CC);
140 } else {
141 php_http_error(HE_THROW, PHP_HTTP_E_REQUEST_METHOD, "Unknown request method '%s'", meth_str);
142 }
143 zval_ptr_dtor(&zret);
144 }
145 }
146 } end_error_handling();
147 }
148 } end_error_handling();
149 }
150
151 PHP_METHOD(HttpRequestMethod, __toString)
152 {
153 if (SUCCESS == zend_parse_parameters_none()) {
154 zval *retval = php_http_zsep(IS_STRING, zend_read_property(php_http_request_method_class_entry, getThis(), ZEND_STRL("name"), 0 TSRMLS_CC));
155
156 RETURN_ZVAL(retval, 0, 0);
157 }
158 RETURN_EMPTY_STRING();
159 }
160
161 PHP_METHOD(HttpRequestMethod, getId)
162 {
163 if (SUCCESS == zend_parse_parameters_none()) {
164 zval **data, *meth = php_http_zsep(IS_STRING, zend_read_property(php_http_request_method_class_entry, getThis(), ZEND_STRL("name"), 0 TSRMLS_CC));
165
166 if (SUCCESS == zend_hash_find(&php_http_request_method_class_entry->constants_table, Z_STRVAL_P(meth), Z_STRLEN_P(meth) + 1, (void *) &data)) {
167 zval_ptr_dtor(&meth);
168 RETURN_ZVAL(*data, 1, 0);
169 }
170 zval_ptr_dtor(&meth);
171 }
172 RETURN_FALSE;
173 }
174
175 PHP_METHOD(HttpRequestMethod, exists)
176 {
177 char *meth_str;
178 int meth_len;
179
180 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &meth_str, &meth_len)) {
181 zval **data;
182
183 if (SUCCESS == zend_hash_find(&php_http_request_method_class_entry->constants_table, meth_str, meth_len + 1, (void *) &data)) {
184 RETURN_ZVAL(*data, 1, 0);
185 }
186 }
187 RETURN_FALSE;
188 }
189
190 PHP_METHOD(HttpRequestMethod, register)
191 {
192 char *meth_str;
193 int meth_len;
194
195 if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &meth_str, &meth_len)) {
196 RETURN_SUCCESS(zend_declare_class_constant_long(php_http_request_method_class_entry, meth_str, meth_len, zend_hash_num_elements(&php_http_request_class_entry->constants_table) TSRMLS_CC));
197 }
198 RETURN_FALSE;
199 }
200
201 PHP_MINIT_FUNCTION(http_request_method)
202 {
203 php_http_strlist_iterator_t std;
204
205 PHP_HTTP_REGISTER_CLASS(http\\request, Method, http_request_method, php_http_object_class_entry, 0);
206
207 zend_declare_property_null(php_http_request_method_class_entry, ZEND_STRL("name"), ZEND_ACC_PROTECTED TSRMLS_CC);
208
209 php_http_strlist_iterator_init(&std, php_http_request_methods, 1);
210 do {
211 unsigned id;
212 const char *meth = php_http_strlist_iterator_this(&std, &id);
213
214 zend_declare_class_constant_long(php_http_request_method_class_entry, meth, strlen(meth), id TSRMLS_CC);
215 } while (*php_http_strlist_iterator_next(&std));
216
217 return SUCCESS;
218 }
219
220
221 /*
222 * Local variables:
223 * tab-width: 4
224 * c-basic-offset: 4
225 * End:
226 * vim600: noet sw=4 ts=4 fdm=marker
227 * vim<600: noet sw=4 ts=4
228 */
229