mirror of
https://github.com/radareorg/radare2-r2pipe.git
synced 2026-11-07 06:35:58 -10:00
Use a single WASM HTTP request import
This commit is contained in:
1 parent
993de25e63
commit
e1c3f02c72
4 files changed
+14
-13
No files matched your search
@@ -128,6 +128,9 @@ interactive terminal. Use `quit()`/`close()` or a context manager to release it.
|
||||
Only HTTP(S) GET and POST are exposed, through radare2's existing
|
||||
`r_socket_http_get()` and `r_socket_http_post()` C APIs. There are no socket
|
||||
handles, listeners, UDP, WebSockets, or shell-curl execution.
|
||||
The host ABI is one `r2.http_request(post, url, headers, data, code, length)`
|
||||
import, with `post=0` for GET and `post=1` for POST. Update the host and WASM
|
||||
module together; this replaces the earlier two-import bridge.
|
||||
|
||||
```sh
|
||||
# In a clean radare2 checkout containing the HTTP bridge:
|
||||
|
||||
@@ -37,12 +37,12 @@ class R2Pipe:
|
||||
self._http = HttpBridge(self)
|
||||
# Only the existing HTTP ABI is allowed in addition to Preview1.
|
||||
for imported in module.imports:
|
||||
if imported.module == "r2" and imported.name in ("http_get", "http_post"):
|
||||
if imported.module == "r2" and imported.name == "http_request":
|
||||
continue
|
||||
if imported.module != "wasi_snapshot_preview1":
|
||||
raise ValueError(f"Unsupported WASM import {imported.module}.{imported.name}; "
|
||||
"use a wasi-api build")
|
||||
if network and not any(item.module == "r2" and item.name == "http_get" for item in module.imports):
|
||||
if network and not any(item.module == "r2" and item.name == "http_request" for item in module.imports):
|
||||
raise ValueError("This WASM build has no HTTP bridge; use a wasi-api-http build")
|
||||
required = {"memory", "malloc", "free", "r_core_new", "r_core_free",
|
||||
"r_core_cmd_str", "r_core_file_open", "r_core_bin_load"}
|
||||
|
||||
@@ -22,7 +22,8 @@ class HttpBridge:
|
||||
def __init__(self, pipe):
|
||||
self.pipe = pipe
|
||||
|
||||
def _request(self, method, url, headers, data, code, length):
|
||||
def http_request(self, post, url, headers, data, code, length):
|
||||
method = "POST" if post else "GET"
|
||||
exports = self.pipe._exports
|
||||
pointer = 0
|
||||
try:
|
||||
@@ -66,9 +67,3 @@ class HttpBridge:
|
||||
if pointer:
|
||||
exports.free(pointer)
|
||||
return 0
|
||||
|
||||
def http_get(self, url, headers, code, length):
|
||||
return self._request("GET", url, headers, 0, code, length)
|
||||
|
||||
def http_post(self, url, headers, data, code, length):
|
||||
return self._request("POST", url, headers, data, code, length)
|
||||
@@ -65,10 +65,14 @@ class HttpServerTest(unittest.TestCase):
|
||||
status, length = alloc(' '), alloc(' ')
|
||||
result = 0
|
||||
try:
|
||||
fn = getattr(e, ('r_socket_http_' if is_real else 'http_') + method)
|
||||
fn = getattr(e, 'r_socket_http_' + method) if is_real else e.http_request
|
||||
args = [address, fields if headers else 0]
|
||||
if not is_real:
|
||||
args.insert(0, int(method == 'post'))
|
||||
if method == 'post':
|
||||
args.append(alloc('{"prompt":"hello món"}'))
|
||||
elif not is_real:
|
||||
args.append(0)
|
||||
result = fn(*args, status, length) & 0xffffffff
|
||||
if not result:
|
||||
return None
|
||||
@@ -89,9 +93,8 @@ class HttpServerTest(unittest.TestCase):
|
||||
class HttpImportsTest(HttpServerTest):
|
||||
def test_imports_opt_in_get_post_status_and_binary(self):
|
||||
wat = '''(module
|
||||
(import "r2" "http_get" (func $get (param i32 i32 i32 i32) (result i32)))
|
||||
(import "r2" "http_post" (func $post (param i32 i32 i32 i32 i32) (result i32)))
|
||||
(export "http_get" (func $get)) (export "http_post" (func $post))
|
||||
(import "r2" "http_request" (func $request (param i32 i32 i32 i32 i32 i32) (result i32)))
|
||||
(export "http_request" (func $request))
|
||||
(memory (export "memory") 1)
|
||||
(global $heap (mut i32) (i32.const 4096))
|
||||
(func (export "malloc") (param $n i32) (result i32)
|
||||
|
||||
Reference in new issue
Block a user