安全 Rust 中的新 PHP SAPI

1作者: jhavenz6 个月前
我最近发布了 ripht-php-sapi 的初始 RC 版本。<p>这是针对 PHP 嵌入式 SAPI 的安全 Rust 绑定。它允许你从 Rust 执行 PHP 脚本,而无需接触不安全代码。<p>```rust use ripht_php_sapi::prelude::*;<p>let sapi = RiphtSapi::instance(); let script = std::path::Path::new(&quot;index.php&quot;);<p>let req = WebRequest::get() .with_query_param(&quot;id&quot;, &quot;123&quot;) .with_header(&quot;User-Agent&quot;, &quot;Ripht&quot;) .build(&amp;script) .expect(&quot;build failed&quot;);<p>let res = sapi.execute(req).expect(&quot;execution failed&quot;);<p>assert_eq!(res.status_code(), 200); println!(&quot;{}&quot;, res.body_string()); ```<p>我添加的一个小福利是,你可以钩入 SAPI 的生命周期,以拦截输出、错误、日志记录等。<p>```rust struct StreamHooks; impl ExecutionHooks for StreamHooks { fn on_output(&amp;mut self, data: &amp;[u8]) -&gt; OutputAction { &#x2F;&#x2F; 在这里处理 PHP 输出...<p><pre><code> OutputAction::Done }</code></pre> } ```<p>我计划构建一些基于 Rust 的高级 PHP 工具,但需要一个众所周知的干净的开始。我也没有看到任何现有的 Rust 的 SAPI 实现,所以大约 3 个月后,它就诞生了。其中很大一部分是研究。令人惊讶的是,现有的教育材料是多么稀缺和陈旧。所以,幸好有 20 多年的经过实战检验的源代码可以学习!感谢 Nginx unit、php&#x2F;php-fpm、apache 和 Frankenphp。能够比较和对比各种实现非常有帮助。如果你对 PHP SAPI 内部结构和 Rust FFI 的内容感兴趣,也可以衡量一下兴趣:https:&#x2F;&#x2F;www.patreon.com&#x2F;posts&#x2F;gauging-php-sapi-146489023<p>GitHub: https:&#x2F;&#x2F;github.com&#x2F;jhavenz&#x2F;ripht-php-sapi<p>Crate: https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;ripht-php-sapi<p>欢迎反馈
查看原文
I recently published the initial ripht-php-sapi RC.<p>It’s safe Rust bindings for PHP&#x27;s embed SAPI. Lets you execute PHP scripts from Rust without touching unsafe code.<p>```rust use ripht_php_sapi::prelude::*;<p>let sapi = RiphtSapi::instance(); let script = std::path::Path::new(&quot;index.php&quot;);<p>let req = WebRequest::get() .with_query_param(&quot;id&quot;, &quot;123&quot;) .with_header(&quot;User-Agent&quot;, &quot;Ripht&quot;) .build(&amp;script) .expect(&quot;build failed&quot;);<p>let res = sapi.execute(req).expect(&quot;execution failed&quot;);<p>assert_eq!(res.status_code(), 200); println!(&quot;{}&quot;, res.body_string()); ```<p>A little bonus Iv’e added is that you can hook into the SAPI lifecycle to intercept output, errors, logging, etc.<p>```rust struct StreamHooks; impl ExecutionHooks for StreamHooks { fn on_output(&amp;mut self, data: &amp;[u8]) -&gt; OutputAction { &#x2F;&#x2F; Do something with the PHP output here...<p><pre><code> OutputAction::Done }</code></pre> } ```<p>I&#x27;d plan to build some higher level Rust-based PHP tooling but need the proverbial clean slate. I also didn’t see any existing SAPI implementations for Rust, so ~3 months later, here it is. A good chunk of that was research. It’s surprising how scarce and archaic the educational material is out there. So, good thing there was 20+ years of battle-tested source code to learn from! Thank you to Nginx unit, php&#x2F;php-fpm, apache, and Frankenphp. Being able to compare and contrast implementations was extremely helpful. Also gauging interest in content about PHP SAPI internals and Rust FFI if anyone&#x27;s curious about that rabbit hole: https:&#x2F;&#x2F;www.patreon.com&#x2F;posts&#x2F;gauging-php-sapi-146489023<p>GitHub: https:&#x2F;&#x2F;github.com&#x2F;jhavenz&#x2F;ripht-php-sapi<p>Crate: https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;ripht-php-sapi<p>I’m open to feedback