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-2007, Michael Wallner <mike@php.net> |
10 : +--------------------------------------------------------------------+
11 : */
12 :
13 : /* $Id: http_exception_object.c,v 1.19 2007/02/07 11:50:26 mike Exp $ */
14 :
15 : #include "php_http.h"
16 :
17 : #ifdef ZEND_ENGINE_2
18 :
19 : #ifndef HTTP_DBG_EXCEPTIONS
20 : # define HTTP_DBG_EXCEPTIONS 0
21 : #endif
22 :
23 : #include "zend_interfaces.h"
24 : #include "zend_exceptions.h"
25 : #include "php_http_exception_object.h"
26 :
27 : zend_class_entry *http_exception_object_ce;
28 : zend_class_entry *HTTP_EX_CE(runtime);
29 : zend_class_entry *HTTP_EX_CE(header);
30 : zend_class_entry *HTTP_EX_CE(malformed_headers);
31 : zend_class_entry *HTTP_EX_CE(request_method);
32 : zend_class_entry *HTTP_EX_CE(message_type);
33 : zend_class_entry *HTTP_EX_CE(invalid_param);
34 : zend_class_entry *HTTP_EX_CE(encoding);
35 : zend_class_entry *HTTP_EX_CE(request);
36 : zend_class_entry *HTTP_EX_CE(request_pool);
37 : zend_class_entry *HTTP_EX_CE(socket);
38 : zend_class_entry *HTTP_EX_CE(response);
39 : zend_class_entry *HTTP_EX_CE(url);
40 : zend_class_entry *HTTP_EX_CE(querystring);
41 :
42 : #define HTTP_EMPTY_ARGS(method) HTTP_EMPTY_ARGS_EX(HttpException, method, 0)
43 : #define HTTP_EXCEPTION_ME(method, visibility) PHP_ME(HttpException, method, HTTP_ARGS(HttpException, method), visibility)
44 :
45 : HTTP_EMPTY_ARGS(__toString);
46 :
47 : zend_function_entry http_exception_object_fe[] = {
48 : HTTP_EXCEPTION_ME(__toString, ZEND_ACC_PUBLIC)
49 :
50 : EMPTY_FUNCTION_ENTRY
51 : };
52 :
53 : #if HTTP_DBG_EXCEPTIONS
54 : static void http_exception_hook(zval *ex TSRMLS_DC)
55 : {
56 : if (ex) {
57 : zval *m = zend_read_property(Z_OBJCE_P(ex), ex, "message", lenof("message"), 0 TSRMLS_CC);
58 : fprintf(stderr, "*** Threw exception '%s'\n", Z_STRVAL_P(m));
59 : } else {
60 : fprintf(stderr, "*** Threw NULL exception\n");
61 : }
62 : }
63 : #endif
64 :
65 : PHP_MINIT_FUNCTION(http_exception_object)
66 220 : {
67 220 : HTTP_REGISTER_CLASS(HttpException, http_exception_object, ZEND_EXCEPTION_GET_DEFAULT(), 0);
68 :
69 220 : zend_declare_property_null(HTTP_EX_DEF_CE, "innerException", lenof("innerException"), ZEND_ACC_PUBLIC TSRMLS_CC);
70 :
71 220 : HTTP_REGISTER_EXCEPTION(HttpRuntimeException, HTTP_EX_CE(runtime), HTTP_EX_DEF_CE);
72 220 : HTTP_REGISTER_EXCEPTION(HttpInvalidParamException, HTTP_EX_CE(invalid_param), HTTP_EX_DEF_CE);
73 220 : HTTP_REGISTER_EXCEPTION(HttpHeaderException, HTTP_EX_CE(header), HTTP_EX_DEF_CE);
74 220 : HTTP_REGISTER_EXCEPTION(HttpMalformedHeadersException, HTTP_EX_CE(malformed_headers), HTTP_EX_DEF_CE);
75 220 : HTTP_REGISTER_EXCEPTION(HttpRequestMethodException, HTTP_EX_CE(request_method), HTTP_EX_DEF_CE);
76 220 : HTTP_REGISTER_EXCEPTION(HttpMessageTypeException, HTTP_EX_CE(message_type), HTTP_EX_DEF_CE);
77 220 : HTTP_REGISTER_EXCEPTION(HttpEncodingException, HTTP_EX_CE(encoding), HTTP_EX_DEF_CE);
78 220 : HTTP_REGISTER_EXCEPTION(HttpRequestException, HTTP_EX_CE(request), HTTP_EX_DEF_CE);
79 220 : HTTP_REGISTER_EXCEPTION(HttpRequestPoolException, HTTP_EX_CE(request_pool), HTTP_EX_DEF_CE);
80 220 : HTTP_REGISTER_EXCEPTION(HttpSocketException, HTTP_EX_CE(socket), HTTP_EX_DEF_CE);
81 220 : HTTP_REGISTER_EXCEPTION(HttpResponseException, HTTP_EX_CE(response), HTTP_EX_DEF_CE);
82 220 : HTTP_REGISTER_EXCEPTION(HttpUrlException, HTTP_EX_CE(url), HTTP_EX_DEF_CE);
83 220 : HTTP_REGISTER_EXCEPTION(HttpQueryStringException, HTTP_EX_CE(querystring), HTTP_EX_DEF_CE);
84 :
85 220 : HTTP_LONG_CONSTANT("HTTP_E_RUNTIME", HTTP_E_RUNTIME);
86 220 : HTTP_LONG_CONSTANT("HTTP_E_INVALID_PARAM", HTTP_E_INVALID_PARAM);
87 220 : HTTP_LONG_CONSTANT("HTTP_E_HEADER", HTTP_E_HEADER);
88 220 : HTTP_LONG_CONSTANT("HTTP_E_MALFORMED_HEADERS", HTTP_E_MALFORMED_HEADERS);
89 220 : HTTP_LONG_CONSTANT("HTTP_E_REQUEST_METHOD", HTTP_E_REQUEST_METHOD);
90 220 : HTTP_LONG_CONSTANT("HTTP_E_MESSAGE_TYPE", HTTP_E_MESSAGE_TYPE);
91 220 : HTTP_LONG_CONSTANT("HTTP_E_ENCODING", HTTP_E_ENCODING);
92 220 : HTTP_LONG_CONSTANT("HTTP_E_REQUEST", HTTP_E_REQUEST);
93 220 : HTTP_LONG_CONSTANT("HTTP_E_REQUEST_POOL", HTTP_E_REQUEST_POOL);
94 220 : HTTP_LONG_CONSTANT("HTTP_E_SOCKET", HTTP_E_SOCKET);
95 220 : HTTP_LONG_CONSTANT("HTTP_E_RESPONSE", HTTP_E_RESPONSE);
96 220 : HTTP_LONG_CONSTANT("HTTP_E_URL", HTTP_E_URL);
97 220 : HTTP_LONG_CONSTANT("HTTP_E_QUERYSTRING", HTTP_E_QUERYSTRING);
98 :
99 : #if HTTP_DBG_EXCEPTIONS
100 : zend_throw_exception_hook=http_exception_hook;
101 : #endif
102 :
103 220 : return SUCCESS;
104 : }
105 :
106 : zend_class_entry *_http_exception_get_default()
107 286 : {
108 286 : return http_exception_object_ce;
109 : }
110 :
111 : zend_class_entry *_http_exception_get_for_code(long code)
112 16 : {
113 16 : zend_class_entry *ex = http_exception_object_ce;
114 :
115 16 : switch (code) {
116 3 : case HTTP_E_RUNTIME: ex = HTTP_EX_CE(runtime); break;
117 4 : case HTTP_E_INVALID_PARAM: ex = HTTP_EX_CE(invalid_param); break;
118 0 : case HTTP_E_HEADER: ex = HTTP_EX_CE(header); break;
119 0 : case HTTP_E_MALFORMED_HEADERS: ex = HTTP_EX_CE(malformed_headers); break;
120 0 : case HTTP_E_REQUEST_METHOD: ex = HTTP_EX_CE(request_method); break;
121 0 : case HTTP_E_MESSAGE_TYPE: ex = HTTP_EX_CE(message_type); break;
122 0 : case HTTP_E_ENCODING: ex = HTTP_EX_CE(encoding); break;
123 3 : case HTTP_E_REQUEST: ex = HTTP_EX_CE(request); break;
124 6 : case HTTP_E_REQUEST_POOL: ex = HTTP_EX_CE(request_pool); break;
125 0 : case HTTP_E_SOCKET: ex = HTTP_EX_CE(socket); break;
126 0 : case HTTP_E_RESPONSE: ex = HTTP_EX_CE(response); break;
127 0 : case HTTP_E_URL: ex = HTTP_EX_CE(url); break;
128 0 : case HTTP_E_QUERYSTRING: ex = HTTP_EX_CE(querystring); break;
129 : }
130 :
131 16 : return ex;
132 : }
133 :
134 : PHP_METHOD(HttpException, __toString)
135 2 : {
136 : phpstr full_str;
137 : zend_class_entry *ce;
138 2 : zval *zobj = getThis(), *retval = NULL, *m, *f, *l;
139 :
140 2 : phpstr_init(&full_str);
141 :
142 : do {
143 2 : ce = Z_OBJCE_P(zobj);
144 :
145 2 : m = zend_read_property(ce, zobj, "message", lenof("message"), 0 TSRMLS_CC);
146 2 : f = zend_read_property(ce, zobj, "file", lenof("file"), 0 TSRMLS_CC);
147 2 : l = zend_read_property(ce, zobj, "line", lenof("line"), 0 TSRMLS_CC);
148 :
149 2 : if (m && f && l && Z_TYPE_P(m) == IS_STRING && Z_TYPE_P(f) == IS_STRING && Z_TYPE_P(l) == IS_LONG) {
150 2 : if (zobj != getThis()) {
151 0 : phpstr_appends(&full_str, " inner ");
152 : }
153 :
154 2 : phpstr_appendf(&full_str, "exception '%.*s' with message '%.*s' in %.*s:%ld" PHP_EOL,
155 : ce->name_length, ce->name, Z_STRLEN_P(m), Z_STRVAL_P(m), Z_STRLEN_P(f), Z_STRVAL_P(f), Z_LVAL_P(l)
156 : );
157 : } else {
158 : break;
159 : }
160 :
161 2 : zobj = zend_read_property(ce, zobj, "innerException", lenof("innerException"), 0 TSRMLS_CC);
162 2 : } while (Z_TYPE_P(zobj) == IS_OBJECT);
163 :
164 2 : if (zend_call_method_with_0_params(&getThis(), Z_OBJCE_P(getThis()), NULL, "gettraceasstring", &retval) && Z_TYPE_P(retval) == IS_STRING) {
165 2 : phpstr_appends(&full_str, "Stack trace:" PHP_EOL);
166 2 : phpstr_append(&full_str, Z_STRVAL_P(retval), Z_STRLEN_P(retval));
167 2 : zval_ptr_dtor(&retval);
168 : }
169 :
170 2 : RETURN_PHPSTR_VAL(&full_str);
171 : }
172 :
173 : #endif
174 :
175 : /*
176 : * Local variables:
177 : * tab-width: 4
178 : * c-basic-offset: 4
179 : * End:
180 : * vim600: noet sw=4 ts=4 fdm=marker
181 : * vim<600: noet sw=4 ts=4
182 : */
183 :
|