Skip to content

Commit 4dddcae

Browse files
committed
Support streams
1 parent 121d1c6 commit 4dddcae

File tree

21 files changed

+1405
-409
lines changed

21 files changed

+1405
-409
lines changed

.github/workflows/CI.yml

Lines changed: 106 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,6 @@ jobs:
4545
brew install autoconf automake libtool re2c bison libiconv \
4646
argon2 libzip postgresql@16
4747
48-
# TODO: Do we need to care about x86_64 macOS?
49-
# NOTE: Unable to force link bison on macOS 13, which php-src requires.
50-
- host: macos-13
51-
target: x86_64-apple-darwin
52-
# build: pnpm build --target x86_64-apple-darwin
53-
build: pnpm build
54-
setup: |
55-
brew install autoconf automake libtool re2c bison libiconv \
56-
argon2 libzip postgresql@16
57-
5848
#
5949
# Linux
6050
#
@@ -302,11 +292,6 @@ jobs:
302292
fail-fast: false
303293
matrix:
304294
settings:
305-
- host: macos-13
306-
target: x86_64-apple-darwin
307-
architecture: x64
308-
setup: |
309-
brew install openssl@3 argon2 postgresql@16
310295
- host: macos-15
311296
target: aarch64-apple-darwin
312297
architecture: arm64
@@ -352,8 +337,85 @@ jobs:
352337
- name: List packages
353338
run: ls -R ./npm
354339
shell: bash
340+
- name: Show environment info
341+
run: |
342+
echo "=== macOS Info ==="
343+
uname -a
344+
sw_vers
345+
echo ""
346+
echo "=== Node.js ==="
347+
node -v
348+
echo ""
349+
echo "=== OpenSSL (brew) ==="
350+
brew info openssl@3 | head -5
351+
echo ""
352+
echo "=== OpenSSL (node built-in) ==="
353+
node -e "console.log(process.versions)"
354+
echo ""
355+
echo "=== libphp dependencies ==="
356+
otool -L npm/darwin-arm64/libphp.dylib | head -20
357+
echo ""
358+
echo "=== binding.node dependencies ==="
359+
otool -L npm/darwin-arm64/binding.node | head -20
355360
- name: Test bindings
356-
run: pnpm test
361+
run: |
362+
# Run tests with LLDB to catch segfaults on macOS
363+
LLDB_OUTPUT=$(mktemp)
364+
LLDB_SCRIPT=$(mktemp)
365+
366+
# Create LLDB command script with stop-hook to automatically get backtraces
367+
cat > "$LLDB_SCRIPT" << 'LLDBSCRIPT'
368+
settings set auto-confirm true
369+
settings set target.process.stop-on-exec false
370+
371+
# Add a stop hook that runs "bt all" whenever the process stops
372+
target stop-hook add -o "bt all"
373+
374+
# Run the process
375+
run
376+
377+
# After process exits or crashes, get final backtrace and quit
378+
bt all
379+
quit
380+
LLDBSCRIPT
381+
382+
echo "=== Running tests under LLDB ==="
383+
384+
# Run LLDB with the script
385+
lldb \
386+
-s "$LLDB_SCRIPT" \
387+
-- node node_modules/ava/entrypoints/cli.mjs __test__/handler.spec.mjs __test__/headers.spec.mjs __test__/request.spec.mjs __test__/response.spec.mjs __test__/rewriter.spec.mjs __test__/streaming.spec.mjs 2>&1 | tee "$LLDB_OUTPUT"
388+
389+
LLDB_EXIT=$?
390+
echo ""
391+
echo "=== LLDB exit code: $LLDB_EXIT ==="
392+
393+
rm -f "$LLDB_SCRIPT"
394+
395+
# Check for crash indicators in LLDB output
396+
if grep -qE "(SIGSEGV|SIGABRT|SIGBUS|EXC_BAD_ACCESS|EXC_CRASH|zend_mm_heap corrupted|stop reason = EXC|stop reason = signal)" "$LLDB_OUTPUT"; then
397+
echo ""
398+
echo "========================================"
399+
echo "=== CRASH DETECTED ==="
400+
echo "========================================"
401+
echo ""
402+
echo "=== Backtrace output should be above ==="
403+
rm -f "$LLDB_OUTPUT"
404+
exit 1
405+
fi
406+
407+
# Check the output for test results
408+
if grep -q "tests passed" "$LLDB_OUTPUT" && ! grep -q "tests failed" "$LLDB_OUTPUT"; then
409+
echo "=== Tests passed ==="
410+
rm -f "$LLDB_OUTPUT"
411+
exit 0
412+
fi
413+
414+
# If we get here, something went wrong
415+
echo "=== Test run did not complete successfully ==="
416+
cat "$LLDB_OUTPUT"
417+
rm -f "$LLDB_OUTPUT"
418+
exit 1
357419
358420
test-linux-binding:
359421
name: Test bindings on ${{ matrix.target }} - node@${{ matrix.node }}
@@ -431,9 +493,34 @@ jobs:
431493
libcurl4-openssl-dev autoconf libxml2-dev libsqlite3-dev \
432494
bison re2c libonig-dev libargon2-dev libzip-dev zlib1g-dev \
433495
openssh-client libclang-dev libreadline-dev libpng-dev \
434-
libjpeg-dev libsodium-dev libpq5
435-
436-
npm run test
496+
libjpeg-dev libsodium-dev libpq5 gdb
497+
498+
# Enable core dumps
499+
ulimit -c unlimited
500+
echo '/tmp/core.%e.%p' > /proc/sys/kernel/core_pattern || true
501+
502+
# Run tests with GDB to catch segfaults
503+
# Use the ava entrypoint directly instead of the bin script
504+
gdb -batch \
505+
-ex "set pagination off" \
506+
-ex "set confirm off" \
507+
-ex "handle SIGSEGV stop print" \
508+
-ex "run" \
509+
-ex "thread apply all bt full" \
510+
--args node node_modules/ava/entrypoints/cli.mjs __test__/handler.spec.mjs __test__/headers.spec.mjs __test__/request.spec.mjs __test__/response.spec.mjs __test__/rewriter.spec.mjs __test__/streaming.spec.mjs
511+
512+
EXIT_CODE=$?
513+
if [ $EXIT_CODE -ne 0 ]; then
514+
echo "=== Test failed with exit code $EXIT_CODE ==="
515+
# Try to find and analyze core dumps
516+
if ls /tmp/core.* 2>/dev/null; then
517+
for core in /tmp/core.*; do
518+
echo "=== Analyzing core dump: $core ==="
519+
gdb -batch -ex "bt full" -ex "thread apply all bt" node "$core" || true
520+
done
521+
fi
522+
exit $EXIT_CODE
523+
fi
437524
438525
publish:
439526
name: Publish a release

Cargo.toml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,19 @@ path = "src/main.rs"
2222
[dependencies]
2323
bytes = "1.10.1"
2424
hostname = "0.4.1"
25-
ext-php-rs = { version = "0.14.0", features = ["embed"] }
26-
http-handler = { git = "https://github.com/platformatic/http-handler.git", branch = "core-async-trait" }
25+
# TODO: Switch back to crates.io once 0.15.3+ is released with ext_php_rs_sapi_per_thread_shutdown
26+
ext-php-rs = { git = "https://github.com/extphprs/ext-php-rs.git", features = ["embed"] }
27+
http-body-util = "0.1"
28+
http-handler = { git = "https://github.com/platformatic/http-handler.git" }
2729
# http-handler = { path = "../http-handler" }
2830
http-rewriter = { git = "https://github.com/platformatic/http-rewriter.git" }
2931
# http-rewriter = { path = "../http-rewriter" }
3032
libc = "0.2.171"
3133
# Default enable napi4 feature, see https://nodejs.org/api/n-api.html#node-api-version-matrix
32-
napi = { version = "3", default-features = false, features = ["napi4"], optional = true }
34+
napi = { version = "3", default-features = false, features = ["napi4", "tokio_rt", "async"], optional = true }
3335
napi-derive = { version = "3", optional = true }
3436
once_cell = "1.21.0"
35-
tokio = { version = "1.45", features = ["rt", "macros", "rt-multi-thread"] }
37+
tokio = { version = "1.45", features = ["rt", "macros", "rt-multi-thread", "sync"] }
3638
regex = "1.0"
3739

3840
[dev-dependencies]

__test__/request.spec.mjs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ test('minimum construction requirements', (t) => {
1010

1111
t.is(req.method, 'GET')
1212
t.is(req.url, 'http://example.com/test.php')
13-
t.assert(req.body instanceof Buffer)
14-
t.is(req.body.length, 0)
1513
t.assert(req.headers instanceof Headers)
1614
t.is(req.headers.size, 0)
1715
})

__test__/response.spec.mjs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ test('Minimal response construction', (t) => {
99

1010
t.is(res.status, 200)
1111
t.assert(res.headers instanceof Headers)
12-
t.assert(res.body instanceof Buffer)
13-
t.deepEqual(res.body.toString(), '')
1412
t.assert(res.log instanceof Buffer)
1513
t.deepEqual(res.log.toString(), '')
1614
t.is(res.exception, null)
@@ -37,8 +35,6 @@ test('Full Response construction', (t) => {
3735
t.assert(res.headers instanceof Headers)
3836
t.deepEqual(res.headers.get('Content-Type'), 'application/json')
3937
t.deepEqual(res.headers.getAll('Accept'), ['application/json', 'text/plain'])
40-
t.assert(res.body instanceof Buffer)
41-
t.deepEqual(res.body.toString(), json)
4238
t.assert(res.log instanceof Buffer)
4339
t.deepEqual(res.log.toString(), 'Hello, from error_log!')
4440
t.deepEqual(res.exception, 'Hello, from PHP!')

0 commit comments

Comments
 (0)