-
-
Save ereslibre/fdf25c2a0c322483ecd074a3676e8571 to your computer and use it in GitHub Desktop.
Apache APR through Wasm example run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
======================================================================= | |
Step 1 'Same PHP script, which prints headers is configured to serve at two locations:': | |
======================================================================= | |
Alias /sample-mod-headers /usr/local/apache2/headers-filter/php-sample | |
Alias /sample-mod-wasm /usr/local/apache2/headers-filter/php-sample | |
$ curl localhost:8080/sample-mod-headers/index.php | |
<h1> HTTP Headers: </h1><ul> | |
<li><pre>Accept : */*</pre></li> | |
<li><pre>User-Agent : curl/7.74.0</pre></li> | |
<li><pre>Host : localhost:8080</pre></li> | |
</ul> | |
----------------------------------------------------------------------- | |
$ curl localhost:8080/sample-mod-wasm/index.php | |
<h1> HTTP Headers: </h1><ul> | |
<li><pre>Accept : */*</pre></li> | |
<li><pre>User-Agent : curl/7.74.0</pre></li> | |
<li><pre>Host : localhost:8080</pre></li> | |
</ul> | |
----------------------------------------------------------------------- | |
======================================================================= | |
Step 2 'Modifying 'target' header based on value of 'operation' header with mod_headers': | |
======================================================================= | |
httpd.conf: | |
<Location /sample-mod-headers> | |
SetEnvIf Operation "^add$" OPERATION_add | |
RequestHeader set "added" "added_value" env=OPERATION_add | |
SetEnvIf Operation "^modify$" OPERATION_modify | |
RequestHeader set "target" "modified_value" env=OPERATION_modify | |
SetEnvIf Operation "^delete$" OPERATION_delete | |
RequestHeader unset "target" env=OPERATION_delete | |
</Location> | |
$ curl localhost:8080/sample-mod-headers/index.php --no-progress-meter -H operation:add | |
<h1> HTTP Headers: </h1><ul> | |
<li><pre>Added : added_value</pre></li> | |
<li><pre>Operation : add</pre></li> | |
<li><pre>Accept : */*</pre></li> | |
<li><pre>User-Agent : curl/7.74.0</pre></li> | |
<li><pre>Host : localhost:8080</pre></li> | |
</ul> | |
----------------------------------------------------------------------- | |
$ curl localhost:8080/sample-mod-headers/index.php --no-progress-meter -H operation:delete -H target:value | |
<h1> HTTP Headers: </h1><ul> | |
<li><pre>Operation : delete</pre></li> | |
<li><pre>Accept : */*</pre></li> | |
<li><pre>User-Agent : curl/7.74.0</pre></li> | |
<li><pre>Host : localhost:8080</pre></li> | |
</ul> | |
----------------------------------------------------------------------- | |
$ curl localhost:8080/sample-mod-headers/index.php --no-progress-meter -H operation:modify -H target:value | |
<h1> HTTP Headers: </h1><ul> | |
<li><pre>Target : modified_value</pre></li> | |
<li><pre>Operation : modify</pre></li> | |
<li><pre>Accept : */*</pre></li> | |
<li><pre>User-Agent : curl/7.74.0</pre></li> | |
<li><pre>Host : localhost:8080</pre></li> | |
</ul> | |
----------------------------------------------------------------------- | |
======================================================================= | |
Step 3 'Modifying 'target' header based on value of 'operation' header with mod_wasm and edit_headers.wasm': | |
======================================================================= | |
httpd.conf: | |
<IfModule wasm_module> | |
<Location /sample-mod-wasm> | |
WasmFilter /usr/local/apache2/wasm_modules/rust-wasm/edit_headers.wasm | |
</Location> | |
</IfModule> | |
Rust source: | |
fn handle_operation_header(headers_handle: u64) { | |
if let Some(op) = apr::get_header(headers_handle, "operation") { | |
if op == "add" { | |
apr::set_header(headers_handle, "added", "added_value"); | |
} else if op == "modify" { | |
apr::set_header(headers_handle, "target", "modified_value"); | |
} else if op == "delete" { | |
apr::delete_header(headers_handle, "target"); | |
} | |
} | |
} | |
======================================================================= | |
Step 4 'Evaluating a header's value with mod_wasm and edit_headers.wasm. Can't do with mod_headers': | |
======================================================================= | |
Rust source: | |
fn handle_eval_header(headers_handle: u64) { | |
if let Some(eval_me) = apr::get_header(headers_handle, "evaluate-me") { | |
let result = match eval(eval_me.as_str()) { | |
Ok(result) => result.to_string(), | |
Err(e) => format!("ERROR: {}", e.to_string()), | |
}; | |
apr::set_header(headers_handle, "evaluate-result", result.as_str()); | |
} | |
} | |
$ curl localhost:8080/sample-mod-wasm/index.php --no-progress-meter -H evaluate-me:3*8-2*7 | |
<h1> HTTP Headers: </h1><ul> | |
<li><pre>Evaluate-Result : 10</pre></li> | |
<li><pre>Evaluate-Me : 3*8-2*7</pre></li> | |
<li><pre>Accept : */*</pre></li> | |
<li><pre>User-Agent : curl/7.74.0</pre></li> | |
<li><pre>Host : localhost:8080</pre></li> | |
</ul> | |
----------------------------------------------------------------------- | |
======================================================================= | |
Step 5 'Hash a header's value with mod_wasm and edit_headers.wasm. Can't do with mod_headers': | |
======================================================================= | |
Rust source: | |
fn handle_hash_header(headers_handle: u64) { | |
if let Some(hash_me) = apr::get_header(headers_handle, "hash-me") { | |
let result = compute(hash_me.as_bytes()); | |
apr::set_header(headers_handle, "hash-result", format!("{:x}", result).as_str()); | |
} | |
} | |
$ curl localhost:8080/sample-mod-wasm/index.php --no-progress-meter -H hash-me:The quick brown fox | |
<h1> HTTP Headers: </h1><ul> | |
<li><pre>Hash-Result : a2004f37730b9445670a738fa0fc9ee5</pre></li> | |
<li><pre>Hash-Me : The quick brown fox</pre></li> | |
<li><pre>Accept : */*</pre></li> | |
<li><pre>User-Agent : curl/7.74.0</pre></li> | |
<li><pre>Host : localhost:8080</pre></li> | |
</ul> | |
----------------------------------------------------------------------- | |
======================================================================= | |
Step 6 'Failures in mod_wasm and edit_headers.wasm don't affect Apache's stability. Can't do with a traditional module': | |
======================================================================= | |
Rust source: | |
fn handle_failure_header(headers_handle: u64) { | |
if let Some(fail_me) = apr::get_header(headers_handle, "fail-me") { | |
eprintln!("Simulating error '{}'...", fail_me); | |
if fail_me == "division-by-zero" { | |
let no_result = 1234 / 0; | |
apr::set_header(headers_handle, "dummy", format!("{}", no_result).as_str()); | |
} else if fail_me == "filesystem-access" { | |
let no_contents = fs::read_to_string("/usr/local/apache2/conf/httpd.conf").unwrap(); | |
apr::set_header(headers_handle, "dummy", no_contents.as_str()); | |
} ... | |
} | |
} | |
$ curl localhost:8080/sample-mod-wasm/index.php --no-progress-meter -H fail-me:division-by-zero | |
curl: (52) Empty reply from server | |
----------------------------------------------------------------------- | |
$ tail -n 4 /usr/local/apache2/logs/error_log | |
Simulating error 'division-by-zero'... | |
thread '<unnamed>' panicked at 'attempt to divide by zero', src/lib.rs:46:29 | |
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace | |
qemu: uncaught target signal 4 (Illegal instruction) - core dumped | |
----------------------------------------------------------------------- | |
$ curl localhost:8080/sample-mod-wasm/index.php --no-progress-meter -H fail-me:filesystem-access | |
curl: (52) Empty reply from server | |
----------------------------------------------------------------------- | |
$ tail -n 4 /usr/local/apache2/logs/error_log | |
Simulating error 'filesystem-access'... | |
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: Custom { kind: Uncategorized, error: "failed to find a pre-opened file descriptor through which \"/usr/local/apache2/conf/httpd.conf\" could be opened" }', src/lib.rs:50:88 | |
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace | |
qemu: uncaught target signal 4 (Illegal instruction) - core dumped | |
----------------------------------------------------------------------- | |
Apache is still up even with the fatal failures in the Wasm code: | |
ps -eo comm,etime,user | grep root | grep httpd | |
httpd 00:15 root | |
^^^^^^^^^ Scroll back through the above output. It is self descriptive! ^^^^^^^^^^ | |
mod-wasm-apr-demo |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
======================================================================= | |
Step 1 'Same PHP script, which prints headers is configured to serve at two locations:': | |
======================================================================= | |
Alias /sample-mod-headers /usr/local/apache2/headers-filter/php-sample | |
Alias /sample-mod-wasm /usr/local/apache2/headers-filter/php-sample | |
$ curl localhost:8080/sample-mod-headers/index.php | |
<h1> HTTP Headers: </h1><ul> | |
<li><pre>Host : localhost:8080</pre></li> | |
<li><pre>User-Agent : curl/7.74.0</pre></li> | |
<li><pre>Accept : */*</pre></li> | |
</ul> | |
----------------------------------------------------------------------- | |
$ curl localhost:8080/sample-mod-wasm/index.php | |
<h1> HTTP Headers: </h1><ul> | |
<li><pre>Host : localhost:8080</pre></li> | |
<li><pre>User-Agent : curl/7.74.0</pre></li> | |
<li><pre>Accept : */*</pre></li> | |
</ul> | |
----------------------------------------------------------------------- | |
======================================================================= | |
Step 2 'Modifying 'target' header based on value of 'operation' header with mod_headers': | |
======================================================================= | |
httpd.conf: | |
<Location /sample-mod-headers> | |
SetEnvIf Operation "^add$" OPERATION_add | |
RequestHeader set "added" "added_value" env=OPERATION_add | |
SetEnvIf Operation "^modify$" OPERATION_modify | |
RequestHeader set "target" "modified_value" env=OPERATION_modify | |
SetEnvIf Operation "^delete$" OPERATION_delete | |
RequestHeader unset "target" env=OPERATION_delete | |
</Location> | |
$ curl localhost:8080/sample-mod-headers/index.php --no-progress-meter -H operation:add | |
<h1> HTTP Headers: </h1><ul> | |
<li><pre>Host : localhost:8080</pre></li> | |
<li><pre>User-Agent : curl/7.74.0</pre></li> | |
<li><pre>Accept : */*</pre></li> | |
<li><pre>Operation : add</pre></li> | |
<li><pre>Added : added_value</pre></li> | |
</ul> | |
----------------------------------------------------------------------- | |
$ curl localhost:8080/sample-mod-headers/index.php --no-progress-meter -H operation:delete -H target:value | |
<h1> HTTP Headers: </h1><ul> | |
<li><pre>Host : localhost:8080</pre></li> | |
<li><pre>User-Agent : curl/7.74.0</pre></li> | |
<li><pre>Accept : */*</pre></li> | |
<li><pre>Operation : delete</pre></li> | |
</ul> | |
----------------------------------------------------------------------- | |
$ curl localhost:8080/sample-mod-headers/index.php --no-progress-meter -H operation:modify -H target:value | |
<h1> HTTP Headers: </h1><ul> | |
<li><pre>Host : localhost:8080</pre></li> | |
<li><pre>User-Agent : curl/7.74.0</pre></li> | |
<li><pre>Accept : */*</pre></li> | |
<li><pre>Operation : modify</pre></li> | |
<li><pre>Target : modified_value</pre></li> | |
</ul> | |
----------------------------------------------------------------------- | |
======================================================================= | |
Step 3 'Modifying 'target' header based on value of 'operation' header with mod_wasm and edit_headers.wasm': | |
======================================================================= | |
httpd.conf: | |
<IfModule wasm_module> | |
<Location /sample-mod-wasm> | |
WasmFilter /usr/local/apache2/wasm_modules/rust-wasm/edit_headers.wasm | |
</Location> | |
</IfModule> | |
Rust source: | |
fn handle_operation_header(headers_handle: u64) { | |
if let Some(op) = apr::get_header(headers_handle, "operation") { | |
if op == "add" { | |
apr::set_header(headers_handle, "added", "added_value"); | |
} else if op == "modify" { | |
apr::set_header(headers_handle, "target", "modified_value"); | |
} else if op == "delete" { | |
apr::delete_header(headers_handle, "target"); | |
} | |
} | |
} | |
======================================================================= | |
Step 4 'Evaluating a header's value with mod_wasm and edit_headers.wasm. Can't do with mod_headers': | |
======================================================================= | |
Rust source: | |
fn handle_eval_header(headers_handle: u64) { | |
if let Some(eval_me) = apr::get_header(headers_handle, "evaluate-me") { | |
let result = match eval(eval_me.as_str()) { | |
Ok(result) => result.to_string(), | |
Err(e) => format!("ERROR: {}", e.to_string()), | |
}; | |
apr::set_header(headers_handle, "evaluate-result", result.as_str()); | |
} | |
} | |
$ curl localhost:8080/sample-mod-wasm/index.php --no-progress-meter -H evaluate-me:3*8-2*7 | |
<h1> HTTP Headers: </h1><ul> | |
<li><pre>Host : localhost:8080</pre></li> | |
<li><pre>User-Agent : curl/7.74.0</pre></li> | |
<li><pre>Accept : */*</pre></li> | |
<li><pre>Evaluate-Me : 3*8-2*7</pre></li> | |
<li><pre>Evaluate-Result : 10</pre></li> | |
</ul> | |
----------------------------------------------------------------------- | |
======================================================================= | |
Step 5 'Hash a header's value with mod_wasm and edit_headers.wasm. Can't do with mod_headers': | |
======================================================================= | |
Rust source: | |
fn handle_hash_header(headers_handle: u64) { | |
if let Some(hash_me) = apr::get_header(headers_handle, "hash-me") { | |
let result = compute(hash_me.as_bytes()); | |
apr::set_header(headers_handle, "hash-result", format!("{:x}", result).as_str()); | |
} | |
} | |
$ curl localhost:8080/sample-mod-wasm/index.php --no-progress-meter -H hash-me:The quick brown fox | |
<h1> HTTP Headers: </h1><ul> | |
<li><pre>Host : localhost:8080</pre></li> | |
<li><pre>User-Agent : curl/7.74.0</pre></li> | |
<li><pre>Accept : */*</pre></li> | |
<li><pre>Hash-Me : The quick brown fox</pre></li> | |
<li><pre>Hash-Result : a2004f37730b9445670a738fa0fc9ee5</pre></li> | |
</ul> | |
----------------------------------------------------------------------- | |
======================================================================= | |
Step 6 'Failures in mod_wasm and edit_headers.wasm don't affect Apache's stability. Can't do with a traditional module': | |
======================================================================= | |
Rust source: | |
fn handle_failure_header(headers_handle: u64) { | |
if let Some(fail_me) = apr::get_header(headers_handle, "fail-me") { | |
eprintln!("Simulating error '{}'...", fail_me); | |
if fail_me == "division-by-zero" { | |
let no_result = 1234 / 0; | |
apr::set_header(headers_handle, "dummy", format!("{}", no_result).as_str()); | |
} else if fail_me == "filesystem-access" { | |
let no_contents = fs::read_to_string("/usr/local/apache2/conf/httpd.conf").unwrap(); | |
apr::set_header(headers_handle, "dummy", no_contents.as_str()); | |
} ... | |
} | |
} | |
$ curl localhost:8080/sample-mod-wasm/index.php --no-progress-meter -H fail-me:division-by-zero | |
curl: (52) Empty reply from server | |
----------------------------------------------------------------------- | |
$ tail -n 4 /usr/local/apache2/logs/error_log | |
[Tue May 23 13:19:26.247359 2023] [wasm:error] [pid 14:tid 140149312698112] (-1)Unknown error -1: [client ::1:39812] content_handler() - ERROR! Couldn't deallocate Wasm execution context: '57BDC7A3' | |
Simulating error 'division-by-zero'... | |
thread '<unnamed>' panicked at 'attempt to divide by zero', src/lib.rs:46:29 | |
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace | |
----------------------------------------------------------------------- | |
$ curl localhost:8080/sample-mod-wasm/index.php --no-progress-meter -H fail-me:filesystem-access | |
curl: (52) Empty reply from server | |
----------------------------------------------------------------------- | |
$ tail -n 4 /usr/local/apache2/logs/error_log | |
Simulating error 'filesystem-access'... | |
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: Custom { kind: Uncategorized, error: "failed to find a pre-opened file descriptor through which \"/usr/local/apache2/conf/httpd.conf\" could be opened" }', src/lib.rs:50:88 | |
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace | |
[Tue May 23 13:19:35.149990 2023] [core:notice] [pid 1:tid 140149973830976] AH00051: child pid 24 exit signal Illegal instruction (4), possible coredump in /usr/local/apache2 | |
----------------------------------------------------------------------- | |
Apache is still up even with the fatal failures in the Wasm code: | |
ps -eo comm,etime,user | grep root | grep httpd | |
httpd 00:13 root | |
^^^^^^^^^ Scroll back through the above output. It is self descriptive! ^^^^^^^^^^ | |
mod-wasm-apr-demo |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment