@@ -8,7 +8,7 @@ use std::{
8
8
9
9
use ext_php_rs:: {
10
10
error:: Error ,
11
- ffi:: { php_execute_script, php_module_shutdown , sapi_get_default_content_type} ,
11
+ ffi:: { php_execute_script, sapi_get_default_content_type} ,
12
12
zend:: { try_catch, try_catch_first, ExecutorGlobals , SapiGlobals } ,
13
13
} ;
14
14
@@ -17,8 +17,8 @@ use lang_handler::{Handler, Request, Response};
17
17
use super :: {
18
18
sapi:: { ensure_sapi, Sapi } ,
19
19
scopes:: { FileHandleScope , RequestScope } ,
20
- strings:: { cstr, nullable_cstr, str_from_cstr , translate_path} ,
21
- EmbedException , RequestContext ,
20
+ strings:: { cstr, nullable_cstr, translate_path} ,
21
+ EmbedRequestError , EmbedStartError , RequestContext ,
22
22
} ;
23
23
24
24
/// Embed a PHP script into a Rust application to handle HTTP requests.
@@ -51,7 +51,7 @@ impl Embed {
51
51
///
52
52
/// let embed = Embed::new(docroot);
53
53
/// ```
54
- pub fn new < C : AsRef < Path > > ( docroot : C ) -> Result < Self , EmbedException > {
54
+ pub fn new < C : AsRef < Path > > ( docroot : C ) -> Result < Self , EmbedStartError > {
55
55
Embed :: new_with_argv :: < C , String > ( docroot, vec ! [ ] )
56
56
}
57
57
@@ -68,7 +68,7 @@ impl Embed {
68
68
///
69
69
/// let embed = Embed::new_with_args(docroot, args());
70
70
/// ```
71
- pub fn new_with_args < C > ( docroot : C , args : Args ) -> Result < Self , EmbedException >
71
+ pub fn new_with_args < C > ( docroot : C , args : Args ) -> Result < Self , EmbedStartError >
72
72
where
73
73
C : AsRef < Path > ,
74
74
{
@@ -90,15 +90,15 @@ impl Embed {
90
90
/// "foo"
91
91
/// ]);
92
92
/// ```
93
- pub fn new_with_argv < C , S > ( docroot : C , argv : Vec < S > ) -> Result < Self , EmbedException >
93
+ pub fn new_with_argv < C , S > ( docroot : C , argv : Vec < S > ) -> Result < Self , EmbedStartError >
94
94
where
95
95
C : AsRef < Path > ,
96
96
S : AsRef < str > + std:: fmt:: Debug ,
97
97
{
98
98
let docroot_path = docroot. as_ref ( ) ;
99
99
let docroot = docroot_path
100
100
. canonicalize ( )
101
- . map_err ( |_| EmbedException :: DocRootNotFound ( docroot_path. display ( ) . to_string ( ) ) ) ?;
101
+ . map_err ( |_| EmbedStartError :: DocRootNotFound ( docroot_path. display ( ) . to_string ( ) ) ) ?;
102
102
103
103
Ok ( Embed {
104
104
docroot,
@@ -129,7 +129,7 @@ impl Embed {
129
129
}
130
130
131
131
impl Handler for Embed {
132
- type Error = EmbedException ;
132
+ type Error = EmbedRequestError ;
133
133
134
134
/// Handles an HTTP request.
135
135
///
@@ -169,34 +169,40 @@ impl Handler for Embed {
169
169
let translated_path = translate_path ( & self . docroot , request_uri) ?
170
170
. display ( )
171
171
. to_string ( ) ;
172
- let path_translated = cstr ( translated_path. clone ( ) ) ?;
173
- let request_uri = cstr ( request_uri) ?;
172
+ let path_translated = cstr ( translated_path. clone ( ) )
173
+ . map_err ( |_| EmbedRequestError :: FailedToSetRequestInfo ( "path_translated" . into ( ) ) ) ?;
174
+ let request_uri = cstr ( request_uri)
175
+ . map_err ( |_| EmbedRequestError :: FailedToSetRequestInfo ( "request_uri" . into ( ) ) ) ?;
174
176
175
177
// Extract request method, query string, and headers
176
- let request_method = cstr ( request. method ( ) ) ?;
177
- let query_string = cstr ( url. query ( ) . unwrap_or ( "" ) ) ?;
178
+ let request_method = cstr ( request. method ( ) )
179
+ . map_err ( |_| EmbedRequestError :: FailedToSetRequestInfo ( "request_method" . into ( ) ) ) ?;
180
+ let query_string = cstr ( url. query ( ) . unwrap_or ( "" ) )
181
+ . map_err ( |_| EmbedRequestError :: FailedToSetRequestInfo ( "query_string" . into ( ) ) ) ?;
178
182
179
183
let headers = request. headers ( ) ;
180
- let content_type = nullable_cstr ( headers. get ( "Content-Type" ) ) ?;
184
+ let content_type = nullable_cstr ( headers. get ( "Content-Type" ) )
185
+ . map_err ( |_| EmbedRequestError :: FailedToSetRequestInfo ( "content_type" . into ( ) ) ) ?;
181
186
let content_length = headers
182
187
. get ( "Content-Length" )
183
188
. map ( |v| v. parse :: < i64 > ( ) . unwrap_or ( 0 ) )
184
189
. unwrap_or ( 0 ) ;
185
- let cookie_data = nullable_cstr ( headers. get ( "Cookie" ) ) ?;
190
+ let cookie_data = nullable_cstr ( headers. get ( "Cookie" ) )
191
+ . map_err ( |_| EmbedRequestError :: FailedToSetRequestInfo ( "cookie_data" . into ( ) ) ) ?;
186
192
187
193
// Prepare argv and argc
188
194
let argc = self . args . len ( ) as i32 ;
189
195
let mut argv_ptrs = vec ! [ ] ;
190
196
for arg in self . args . iter ( ) {
191
197
let string = CString :: new ( arg. as_bytes ( ) )
192
- . map_err ( |_| EmbedException :: CStringEncodeFailed ( arg . to_owned ( ) ) ) ?;
198
+ . map_err ( |_| EmbedRequestError :: FailedToSetRequestInfo ( "argv" . into ( ) ) ) ?;
193
199
argv_ptrs. push ( string. into_raw ( ) ) ;
194
200
}
195
201
196
202
let script_name = translated_path. clone ( ) ;
197
203
198
204
let response = try_catch_first ( || {
199
- RequestContext :: for_request ( request. clone ( ) ) ;
205
+ RequestContext :: for_request ( request. clone ( ) , self . docroot . clone ( ) ) ;
200
206
201
207
// Set server context
202
208
{
@@ -247,12 +253,12 @@ impl Handler for Embed {
247
253
248
254
// TODO: Should exceptions be raised or only captured on
249
255
// the response builder?
250
- return Err ( EmbedException :: Exception ( ex. to_string ( ) ) ) ;
256
+ return Err ( EmbedRequestError :: Exception ( ex. to_string ( ) ) ) ;
251
257
}
252
258
253
259
Ok ( ( ) )
254
260
} )
255
- . unwrap_or ( Err ( EmbedException :: Bailout ) ) ?;
261
+ . unwrap_or ( Err ( EmbedRequestError :: Bailout ) ) ?;
256
262
257
263
let ( mimetype, http_response_code) = {
258
264
let globals = SapiGlobals :: get ( ) ;
@@ -262,13 +268,13 @@ impl Handler for Embed {
262
268
)
263
269
} ;
264
270
265
- let default_mime = str_from_cstr ( unsafe { sapi_get_default_content_type ( ) } ) ?;
271
+ let mime_ptr = unsafe { ( mimetype as * mut std:: ffi:: c_char ) . as_ref ( ) }
272
+ . or ( unsafe { sapi_get_default_content_type ( ) . as_ref ( ) } )
273
+ . ok_or ( EmbedRequestError :: FailedToDetermineContentType ) ?;
266
274
267
- let mime = if mimetype. is_null ( ) {
268
- default_mime
269
- } else {
270
- str_from_cstr ( mimetype) . unwrap_or ( default_mime)
271
- } ;
275
+ let mime = unsafe { std:: ffi:: CStr :: from_ptr ( mime_ptr) }
276
+ . to_str ( )
277
+ . map_err ( |_| EmbedRequestError :: FailedToDetermineContentType ) ?;
272
278
273
279
RequestContext :: current ( )
274
280
. map ( |ctx| {
@@ -277,12 +283,12 @@ impl Handler for Embed {
277
283
. status ( http_response_code)
278
284
. header ( "Content-Type" , mime)
279
285
} )
280
- . ok_or ( EmbedException :: ResponseBuildError ) ?
286
+ . ok_or ( EmbedRequestError :: ResponseBuildError ) ?
281
287
} ;
282
288
283
289
Ok ( response_builder. build ( ) )
284
290
} )
285
- . unwrap_or ( Err ( EmbedException :: Bailout ) ) ?;
291
+ . unwrap_or ( Err ( EmbedRequestError :: Bailout ) ) ?;
286
292
287
293
RequestContext :: reclaim ( ) ;
288
294
0 commit comments