@@ -8,9 +8,10 @@ use std::{
8
8
use bytes:: Buf ;
9
9
10
10
use ext_php_rs:: {
11
+ alloc:: { efree, estrdup} ,
11
12
builders:: SapiBuilder ,
12
13
embed:: SapiModule ,
13
- exception:: register_error_observer,
14
+ // exception::register_error_observer,
14
15
ffi:: {
15
16
ext_php_rs_sapi_per_thread_init, ext_php_rs_sapi_shutdown, ext_php_rs_sapi_startup,
16
17
php_module_shutdown, php_module_startup, php_register_variable, sapi_send_headers,
@@ -22,10 +23,7 @@ use ext_php_rs::{
22
23
23
24
use once_cell:: sync:: OnceCell ;
24
25
25
- use crate :: {
26
- strings:: { cstr, drop_str, reclaim_str} ,
27
- EmbedRequestError , EmbedStartError , RequestContext ,
28
- } ;
26
+ use crate :: { EmbedRequestError , EmbedStartError , RequestContext } ;
29
27
use lang_handler:: Header ;
30
28
31
29
// This is a helper to ensure that PHP is initialized and deinitialized at the
@@ -76,17 +74,17 @@ impl Sapi {
76
74
// writing to the ResponseBuilder here. When php_execute_script fails it
77
75
// should read that and could return an error or write it to the
78
76
// ResponseBuilder there.
79
- register_error_observer ( |_error_type , _file , _line , message| {
80
- message
81
- . as_str ( )
82
- . inspect ( |msg| {
83
- if let Some ( ctx ) = RequestContext :: current ( ) {
84
- ctx . response_builder ( ) . exception ( * msg) ;
85
- }
86
- } )
87
- // TODO: Report this error somehow?
88
- . ok ( ) ;
89
- } ) ;
77
+ // TODO: Having error observers registered crashes Laravel.
78
+ // register_error_observer(|error_type, file, line, message| {
79
+ // let file = file .as_str().expect("should convert zend_string to str");
80
+ // // TODO: Report this error somehow?
81
+ // if let Ok(msg ) = message.as_str () {
82
+ // println!("PHP Error #{}: {}\n\tfrom {}:{}", error_type, msg, file, line );
83
+ // if let Some(ctx) = RequestContext::current() {
84
+ // ctx.response_builder().exception(msg);
85
+ // }
86
+ // }
87
+ // });
90
88
91
89
Ok ( Sapi ( RwLock :: new ( boxed) ) )
92
90
}
@@ -130,12 +128,6 @@ impl Drop for Sapi {
130
128
fn drop ( & mut self ) {
131
129
self . shutdown ( ) . unwrap ( ) ;
132
130
133
- {
134
- let sapi = self . 0 . write ( ) . expect ( "should get writable sapi" ) ;
135
-
136
- reclaim_str ( sapi. executable_location ) ;
137
- }
138
-
139
131
unsafe {
140
132
sapi_shutdown ( ) ;
141
133
ext_php_rs_sapi_shutdown ( ) ;
@@ -239,25 +231,34 @@ pub extern "C" fn sapi_module_deactivate() -> c_int {
239
231
let mut globals = SapiGlobals :: get_mut ( ) ;
240
232
241
233
for i in 0 ..globals. request_info . argc {
242
- drop_str ( unsafe { * globals. request_info . argv . offset ( i as isize ) } ) ;
234
+ maybe_efree ( unsafe { * globals. request_info . argv . offset ( i as isize ) } . cast :: < u8 > ( ) ) ;
243
235
}
244
236
245
237
globals. request_info . argc = 0 ;
246
238
globals. request_info . argv = std:: ptr:: null_mut ( ) ;
247
239
248
- drop_str ( globals. request_info . request_method as * mut c_char ) ;
249
- drop_str ( globals. request_info . query_string as * mut c_char ) ;
250
- drop_str ( globals. request_info . request_uri as * mut c_char ) ;
251
- drop_str ( globals. request_info . path_translated as * mut c_char ) ;
252
- drop_str ( globals. request_info . content_type as * mut c_char ) ;
253
- drop_str ( globals. request_info . cookie_data as * mut c_char ) ;
254
- drop_str ( globals. request_info . auth_user as * mut c_char ) ;
255
- drop_str ( globals. request_info . auth_password as * mut c_char ) ;
256
- drop_str ( globals. request_info . auth_digest as * mut c_char ) ;
240
+ maybe_efree ( globals. request_info . request_method as * mut u8 ) ;
241
+ maybe_efree ( globals. request_info . content_type as * mut u8 ) ;
242
+ maybe_efree ( globals. request_info . query_string . cast :: < u8 > ( ) ) ;
243
+ maybe_efree ( globals. request_info . request_uri . cast :: < u8 > ( ) ) ;
244
+ maybe_efree ( globals. request_info . path_translated . cast :: < u8 > ( ) ) ;
245
+ maybe_efree ( globals. request_info . auth_user . cast :: < u8 > ( ) ) ;
246
+ maybe_efree ( globals. request_info . auth_password . cast :: < u8 > ( ) ) ;
247
+ maybe_efree ( globals. request_info . auth_digest . cast :: < u8 > ( ) ) ;
248
+
249
+ maybe_efree ( globals. request_info . cookie_data . cast :: < u8 > ( ) ) ;
257
250
258
251
ZEND_RESULT_CODE_SUCCESS
259
252
}
260
253
254
+ fn maybe_efree ( ptr : * mut u8 ) {
255
+ if !ptr. is_null ( ) {
256
+ unsafe {
257
+ efree ( ptr) ;
258
+ }
259
+ }
260
+ }
261
+
261
262
#[ no_mangle]
262
263
pub extern "C" fn sapi_module_ub_write ( str : * const c_char , str_length : usize ) -> usize {
263
264
if str. is_null ( ) || str_length == 0 {
@@ -275,14 +276,7 @@ pub extern "C" fn sapi_module_ub_write(str: *const c_char, str_length: usize) ->
275
276
276
277
#[ no_mangle]
277
278
pub extern "C" fn sapi_module_flush ( _server_context : * mut c_void ) {
278
- if let Some ( ctx) = RequestContext :: current ( ) {
279
- unsafe { sapi_send_headers ( ) } ;
280
- let mut globals = SapiGlobals :: get_mut ( ) ;
281
- globals. headers_sent = 1 ;
282
- ctx
283
- . response_builder ( )
284
- . status ( globals. sapi_headers . http_response_code ) ;
285
- }
279
+ unsafe { sapi_send_headers ( ) } ;
286
280
}
287
281
288
282
#[ no_mangle]
@@ -329,7 +323,12 @@ pub extern "C" fn sapi_module_read_post(buffer: *mut c_char, length: usize) -> u
329
323
330
324
#[ no_mangle]
331
325
pub extern "C" fn sapi_module_read_cookies ( ) -> * mut c_char {
332
- SapiGlobals :: get ( ) . request_info . cookie_data
326
+ RequestContext :: current ( )
327
+ . map ( |ctx| match ctx. request ( ) . headers ( ) . get ( "Cookie" ) {
328
+ Some ( cookie) => estrdup ( cookie) ,
329
+ None => std:: ptr:: null_mut ( ) ,
330
+ } )
331
+ . unwrap_or ( std:: ptr:: null_mut ( ) )
333
332
}
334
333
335
334
fn env_var < K , V > (
@@ -341,10 +340,9 @@ where
341
340
K : AsRef < str > ,
342
341
V : AsRef < str > ,
343
342
{
344
- let c_value = cstr ( value. as_ref ( ) )
345
- . map_err ( |_| EmbedRequestError :: FailedToSetServerVar ( key. as_ref ( ) . to_owned ( ) ) ) ?;
343
+ let c_value = estrdup ( value. as_ref ( ) ) ;
346
344
env_var_c ( vars, key, c_value) ?;
347
- reclaim_str ( c_value) ;
345
+ maybe_efree ( c_value. cast :: < u8 > ( ) ) ;
348
346
349
347
Ok ( ( ) )
350
348
}
@@ -357,12 +355,11 @@ fn env_var_c<K>(
357
355
where
358
356
K : AsRef < str > ,
359
357
{
360
- let c_key = cstr ( key. as_ref ( ) )
361
- . map_err ( |_| EmbedRequestError :: FailedToSetServerVar ( key. as_ref ( ) . to_owned ( ) ) ) ?;
358
+ let c_key = estrdup ( key. as_ref ( ) ) ;
362
359
unsafe {
363
360
php_register_variable ( c_key, c_value, vars) ;
364
361
}
365
- reclaim_str ( c_key) ;
362
+ maybe_efree ( c_key. cast :: < u8 > ( ) ) ;
366
363
367
364
Ok ( ( ) )
368
365
}
@@ -400,7 +397,7 @@ pub extern "C" fn sapi_module_register_server_variables(vars: *mut ext_php_rs::t
400
397
let req_info = & globals. request_info ;
401
398
402
399
let docroot = ctx. docroot ( ) ;
403
- let docroot_cstr = cstr ( docroot. display ( ) . to_string ( ) ) ? ;
400
+ let docroot_str = docroot. display ( ) . to_string ( ) ;
404
401
405
402
let script_filename = req_info. path_translated ;
406
403
let script_name = if !req_info. request_uri . is_null ( ) {
@@ -414,12 +411,18 @@ pub extern "C" fn sapi_module_register_server_variables(vars: *mut ext_php_rs::t
414
411
env_var ( vars, "SERVER_ADMIN" , "webmaster@localhost" ) ?;
415
412
env_var ( vars, "GATEWAY_INTERFACE" , "CGI/1.1" ) ?;
416
413
417
- env_var_c ( vars, "PHP_SELF" , script_name as * mut c_char ) ?;
418
- env_var_c ( vars, "SCRIPT_NAME" , script_name as * mut c_char ) ?;
414
+ // Laravel seems to think "/register" should be "/index.php/register"?
415
+ // env_var_c(vars, "PHP_SELF", script_name as *mut c_char)?;
416
+ env_var ( vars, "PHP_SELF" , request. url ( ) . path ( ) ) ?;
417
+
418
+ // TODO: is "/register", should be "/index.php"
419
+ env_var ( vars, "SCRIPT_NAME" , request. url ( ) . path ( ) ) ?;
420
+ // env_var_c(vars, "SCRIPT_NAME", script_name as *mut c_char)?;
421
+ env_var_c ( vars, "PATH_INFO" , script_name as * mut c_char ) ?;
419
422
env_var_c ( vars, "SCRIPT_FILENAME" , script_filename) ?;
420
423
env_var_c ( vars, "PATH_TRANSLATED" , script_filename) ?;
421
- env_var_c ( vars, "DOCUMENT_ROOT" , docroot_cstr ) ?;
422
- env_var_c ( vars, "CONTEXT_DOCUMENT_ROOT" , docroot_cstr ) ?;
424
+ env_var ( vars, "DOCUMENT_ROOT" , docroot_str . clone ( ) ) ?;
425
+ env_var ( vars, "CONTEXT_DOCUMENT_ROOT" , docroot_str ) ?;
423
426
424
427
if let Ok ( server_name) = hostname:: get ( ) {
425
428
if let Some ( server_name) = server_name. to_str ( ) {
0 commit comments