Skip to content

Commit cee4092

Browse files
authored
Correctly handle json bodies (#10)
* Correctly handle json bodies Signed-off-by: Matteo Collina <[email protected]> * linted, added linter to CI Signed-off-by: Matteo Collina <[email protected]> --------- Signed-off-by: Matteo Collina <[email protected]>
1 parent 438f1ee commit cee4092

File tree

7 files changed

+56
-21
lines changed

7 files changed

+56
-21
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,7 @@ jobs:
3131
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
3232
- name: Install dependencies
3333
run: pnpm install
34+
- name: Lint
35+
run: pnpm run lint
3436
- name: Run Tests
3537
run: pnpm run test

lib/generator.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Generator as ServiceGenerator } from '@platformatic/service'
22
import { readFile } from 'node:fs/promises'
3-
import { basename, resolve, join } from 'node:path'
3+
import { resolve, join } from 'node:path'
44

55
export class Generator extends ServiceGenerator {
66
constructor (opts = {}) {

lib/plugin.js

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
1-
import { readFile } from 'node:fs/promises'
2-
import { basename } from 'node:path'
3-
41
const HTTP_METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'TRACE']
52

6-
const capitalizeHeaders = header => header.replace(/(^|-)([a-z])/g, (_, dash, letter) => dash + letter.toUpperCase());
3+
const capitalizeHeaders = header => header.replace(/(^|-)([a-z])/g, (_, dash, letter) => dash + letter.toUpperCase())
74

85
export async function plugin (server, opts) {
96
// We import this dynically to provide better error reporting in case
@@ -25,6 +22,7 @@ export async function plugin (server, opts) {
2522

2623
// We accept all content-types and parse them as buffer, so that PHP can
2724
// handle them
25+
server.removeAllContentTypeParsers()
2826
server.addContentTypeParser(/^.*/, { parseAs: 'buffer' }, (request, body, done) => {
2927
done(null, body)
3028
})
@@ -100,16 +98,8 @@ export async function plugin (server, opts) {
10098
}
10199

102100
// A full URL string is needed for PHP, but Node.js splits that across a bunch of places.
103-
function urlForRequest(req) {
101+
function urlForRequest (req) {
104102
const proto = req.raw.protocol ?? 'http:'
105103
const host = req.headers.host ?? 'localhost'
106104
return new URL(req.url, `${proto}//${host}`)
107105
}
108-
109-
// Currently header values must be arrays. Need to make it support single values too.
110-
function fixHeaders (headers) {
111-
return Object.fromEntries(
112-
Object.entries(headers)
113-
.map(([key, value]) => [key, [value]])
114-
)
115-
}

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
"version": "0.7.0",
44
"description": "Integration of PHP with Wattpm",
55
"scripts": {
6+
"lint": "eslint --cache",
7+
"lint:fix": "eslint --cache --fix",
68
"test": "node --test",
79
"build": "node -e 'import {schema} from \"./lib/schema.js\"; console.log(JSON.stringify(schema, null, 2))' > schema.json && json2ts > config.d.ts < schema.json",
810
"dl-wordpress": "rm -rf workdpress && curl -O https://wordpress.org/latest.zip && unzip latest.zip ; rm latest.zip",

test/fixtures/hello/post-json.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
// Set the content type to JSON
3+
header('Content-Type: application/json');
4+
5+
// Get the raw POST data
6+
$json_input = file_get_contents('php://input');
7+
8+
// Parse the JSON data
9+
$data = json_decode($json_input, true);
10+
11+
// Check if JSON parsing was successful
12+
if (json_last_error() !== JSON_ERROR_NONE) {
13+
// Handle JSON parsing error
14+
http_response_code(400);
15+
echo json_encode(['error' => 'Invalid JSON: ' . json_last_error_msg()]);
16+
exit;
17+
}
18+
19+
// Ensure $data is an array (in case of null or other types)
20+
if (!is_array($data)) {
21+
$data = [];
22+
}
23+
24+
// Output the parsed data as JSON with pretty printing
25+
echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
26+
?>

test/generator.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ test('should generate a stackable app', async t => {
7474
}
7575

7676
{
77-
const files = await readdir(join(testDir, 'public'))
77+
const files = await readdir(join(testDir, 'public'))
7878
deepStrictEqual(files.sort(), ['index.php'])
7979
}
8080

test/plugin.test.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import { buildServer } from '@platformatic/service'
2-
import { randomUUID } from 'node:crypto'
3-
import { once } from 'node:events'
4-
import { resolve, join } from 'node:path'
2+
import { join } from 'node:path'
53
import { test } from 'node:test'
64
import { stackable } from '../lib/index.js'
75
import formAutoContet from 'form-auto-content'
@@ -44,7 +42,7 @@ test('post data', async t => {
4442
url: '/post.php',
4543
method: 'POST',
4644
...formAutoContet({
47-
'foo': 'bar'
45+
foo: 'bar'
4846
})
4947
})
5048

@@ -60,8 +58,8 @@ test('get all headers', async t => {
6058

6159
t.assert.deepStrictEqual(res.statusCode, 200)
6260
t.assert.deepStrictEqual(res.json(), {
63-
'HTTP_USER_AGENT': 'lightMyRequest',
64-
'HTTP_HOST': 'localhost:80'
61+
HTTP_USER_AGENT: 'lightMyRequest',
62+
HTTP_HOST: 'localhost:80'
6563
})
6664
})
6765

@@ -94,3 +92,20 @@ test('support rewriter', async t => {
9492
t.assert.deepStrictEqual(res.statusCode, 200)
9593
t.assert.deepStrictEqual(res.body, 'Hello World!')
9694
})
95+
96+
test('post JSON', async t => {
97+
const server = await startStackable(t)
98+
const res = await server.inject({
99+
url: '/post-json.php',
100+
method: 'POST',
101+
headers: {
102+
'Content-Type': 'application/json'
103+
},
104+
body: JSON.stringify({ foo: 'bar' })
105+
})
106+
107+
t.assert.deepStrictEqual(res.statusCode, 200)
108+
t.assert.deepStrictEqual(res.json(), {
109+
foo: 'bar'
110+
})
111+
})

0 commit comments

Comments
 (0)