diff options
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/shirabe-php-shim/src/lib.rs | 11 | ||||
| -rw-r--r-- | crates/shirabe/src/util/http/curl_downloader.rs | 25 | ||||
| -rw-r--r-- | crates/shirabe/src/util/remote_filesystem.rs | 26 |
3 files changed, 17 insertions, 45 deletions
diff --git a/crates/shirabe-php-shim/src/lib.rs b/crates/shirabe-php-shim/src/lib.rs index 59626ea..3ec8296 100644 --- a/crates/shirabe-php-shim/src/lib.rs +++ b/crates/shirabe-php-shim/src/lib.rs @@ -1239,9 +1239,8 @@ pub fn include_file(file: &str) -> PhpMixed { todo!() } -pub fn set_error_handler(_callback: fn(i64, &str, &str, i64) -> bool) { - todo!() -} +// TODO(php-runtime): the callback should be registered in PHP runtime. +pub fn set_error_handler(_callback: fn(i64, &str, &str, i64) -> bool) {} pub fn debug_backtrace() -> Vec<IndexMap<String, Box<PhpMixed>>> { todo!() @@ -1598,12 +1597,6 @@ pub fn restore_error_handler() { todo!() } -/// Closure-capturing variant of PHP `set_error_handler()`. -pub fn set_error_handler_closure(callback: Box<dyn FnMut(i64, &str) -> bool>) { - let _ = callback; - todo!() -} - pub fn stream_get_contents_with_max(stream: PhpMixed, max_length: Option<i64>) -> Option<String> { let _ = (stream, max_length); todo!() diff --git a/crates/shirabe/src/util/http/curl_downloader.rs b/crates/shirabe/src/util/http/curl_downloader.rs index f1056cc..37993f9 100644 --- a/crates/shirabe/src/util/http/curl_downloader.rs +++ b/crates/shirabe/src/util/http/curl_downloader.rs @@ -20,9 +20,8 @@ use shirabe_php_shim::{ curl_multi_select, curl_multi_setopt, curl_setopt, curl_setopt_array, curl_share_init, curl_share_setopt, curl_strerror, curl_version, defined, explode, fclose, fopen, function_exists, implode, in_array, ini_get, is_resource, json_decode, max, parse_url, - preg_quote, rename, restore_error_handler, rewind, rtrim, set_error_handler_closure, sprintf, - str_contains, stream_get_contents, stream_get_contents_with_max, stripos, strpos, substr, - unlink_silent, usleep, var_export, + preg_quote, rename, rewind, rtrim, sprintf, str_contains, stream_get_contents, + stream_get_contents_with_max, stripos, strpos, substr, unlink_silent, usleep, var_export, }; use crate::config::Config; @@ -362,28 +361,18 @@ impl CurlDownloader { "php://temp/maxmemory:524288".to_string() }; - let error_message: std::rc::Rc<std::cell::RefCell<String>> = - std::rc::Rc::new(std::cell::RefCell::new(String::new())); - { - let error_message = error_message.clone(); - set_error_handler_closure(Box::new(move |_code: i64, msg: &str| -> bool { - let mut em = error_message.borrow_mut(); - if !em.is_empty() { - em.push_str("\n"); - } - em.push_str(&Preg::replace(r"{^fopen\(.*?\): }", "", msg).unwrap_or_default()); - true - })); - } + // TODO(phase-c): PHP wraps this fopen in a set_error_handler to capture the warning text + // (stripping the "fopen(...): " prefix) into the message. Rust I/O reports failures through + // return values, not warnings, so error_message stays empty until fopen surfaces its reason. + let error_message = String::new(); let body_handle = fopen(&body_target, "w+b"); - restore_error_handler(); if matches!(body_handle, PhpMixed::Bool(false)) { return Ok(Err(TransportException::new( format!( "The \"{}\" file could not be written to {}: {}", url, copy_to.unwrap_or("a temporary file"), - error_message.borrow() + error_message ), 0, ))); diff --git a/crates/shirabe/src/util/remote_filesystem.rs b/crates/shirabe/src/util/remote_filesystem.rs index fc26775..c510d7c 100644 --- a/crates/shirabe/src/util/remote_filesystem.rs +++ b/crates/shirabe/src/util/remote_filesystem.rs @@ -8,8 +8,8 @@ use shirabe_php_shim::{ RuntimeException, STREAM_NOTIFY_FAILURE, STREAM_NOTIFY_FILE_SIZE_IS, STREAM_NOTIFY_PROGRESS, array_replace_recursive, base64_encode, explode, extension_loaded, file_put_contents, filter_var, gethostbyname, http_clear_last_response_headers, http_get_last_response_headers, - ini_get, json_decode, parse_url, preg_quote, restore_error_handler, set_error_handler, sprintf, - strpos, strtolower, strtr, substr, trim, zlib_decode, + ini_get, json_decode, parse_url, preg_quote, sprintf, strpos, strtolower, strtr, substr, trim, + zlib_decode, }; use crate::config::Config; @@ -307,15 +307,9 @@ impl RemoteFilesystem { let mut error_message = String::new(); let error_code = 0_i64; let mut result: Option<String> = None; - // TODO(phase-c): faithfully accumulating the file_get_contents warnings into - // error_message requires PHP's set_error_handler runtime mechanism — a global handler the - // stream layer invokes per warning, appending into error_message by &-reference. - // set_error_handler / restore_error_handler are php-shim functions that must stay todo!(), - // and get_remote_contents does not surface low-level read warnings through such a side - // channel, so error_message stays empty here. Resolving this needs a thread-local - // error-handler stack wired into the I/O layer. - set_error_handler(|_code, _msg, _file, _line| true); - + // TODO(phase-c): PHP captures file_get_contents warnings here via set_error_handler. Rust + // reports I/O failures through return values rather than warnings, so error_message stays + // empty until get_remote_contents surfaces a read reason. let mut http_response_header: Vec<String> = Vec::new(); let inner_result: anyhow::Result<()> = (|| -> anyhow::Result<()> { result = self.get_remote_contents( @@ -429,7 +423,6 @@ impl RemoteFilesystem { error_message ); } - restore_error_handler(); if let Some(e) = caught_e { if !self.retry { let msg_owned = format!("{}", e); @@ -616,15 +609,12 @@ impl RemoteFilesystem { ))); } + // TODO(phase-c): PHP captures the file_put_contents warning here via set_error_handler + // (see the get() reads above); Rust reports the failure through the return value, so + // put_error_message stays empty until file_put_contents surfaces a write reason. let put_error_message = String::new(); - // TODO(phase-c): capturing the file_put_contents warning into put_error_message - // requires PHP's set_error_handler runtime mechanism (see the get() method above); - // set_error_handler is a php-shim that must stay todo!() and file_put_contents does not - // surface its warning text here, so put_error_message stays empty. - set_error_handler(|_code, _msg, _file, _line| true); let write_result = file_put_contents(file_name.as_deref().unwrap(), result_str.as_bytes()); - restore_error_handler(); if write_result.is_none() { return Err(anyhow::anyhow!(TransportException::new( format!( |
