javascript-solid-server 0.0.90 → 0.0.92
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/jss.js +10 -0
- package/package.json +1 -1
- package/src/handlers/resource.js +13 -1
- package/src/server.js +10 -1
- package/test/ldp.test.js +41 -0
package/bin/jss.js
CHANGED
|
@@ -188,6 +188,16 @@ program
|
|
|
188
188
|
process.on('SIGINT', shutdown);
|
|
189
189
|
process.on('SIGTERM', shutdown);
|
|
190
190
|
|
|
191
|
+
// Gracefully handle ECONNRESET — normal network noise from clients
|
|
192
|
+
// closing connections early (browser navigation, health checks, etc.)
|
|
193
|
+
process.on('uncaughtException', (err) => {
|
|
194
|
+
if (err.code === 'ECONNRESET' || err.code === 'EPIPE' || err.code === 'ECONNABORTED') {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
console.error('Uncaught exception:', err);
|
|
198
|
+
process.exit(1);
|
|
199
|
+
});
|
|
200
|
+
|
|
191
201
|
} catch (err) {
|
|
192
202
|
console.error(`Error: ${err.message}`);
|
|
193
203
|
process.exit(1);
|
package/package.json
CHANGED
package/src/handlers/resource.js
CHANGED
|
@@ -553,7 +553,19 @@ export async function handlePut(request, reply) {
|
|
|
553
553
|
if (isContainer(urlPath)) {
|
|
554
554
|
const stats = await storage.stat(storagePath);
|
|
555
555
|
if (stats?.isDirectory) {
|
|
556
|
-
//
|
|
556
|
+
// If container has index.html and PUT sends HTML, rewrite URL to target the
|
|
557
|
+
// index document and delegate to the standard PUT pipeline. This mirrors GET
|
|
558
|
+
// behavior (line 138) which serves index.html for container URLs, and reuses
|
|
559
|
+
// If-Match/If-None-Match, quota checks, and notification handling.
|
|
560
|
+
const indexPath = storagePath.endsWith('/') ? `${storagePath}index.html` : `${storagePath}/index.html`;
|
|
561
|
+
const contentType = request.headers['content-type'] || '';
|
|
562
|
+
if (contentType.includes('text/html') && await storage.exists(indexPath)) {
|
|
563
|
+
const indexUrl = urlPath.endsWith('/') ? `${urlPath}index.html` : `${urlPath}/index.html`;
|
|
564
|
+
// Fastify request.url is a getter, so proxy it with the rewritten path
|
|
565
|
+
const proxied = Object.create(request, { url: { value: indexUrl } });
|
|
566
|
+
return handlePut(proxied, reply);
|
|
567
|
+
}
|
|
568
|
+
// Container exists but no index routing applies - reject
|
|
557
569
|
return reply.code(409).send({ error: 'Cannot PUT to existing container' });
|
|
558
570
|
}
|
|
559
571
|
|
package/src/server.js
CHANGED
|
@@ -95,7 +95,16 @@ export function createServer(options = {}) {
|
|
|
95
95
|
disableRequestLogging: true,
|
|
96
96
|
trustProxy: true,
|
|
97
97
|
// Handle raw body for non-JSON content
|
|
98
|
-
bodyLimit: 10 * 1024 * 1024 // 10MB
|
|
98
|
+
bodyLimit: 10 * 1024 * 1024, // 10MB
|
|
99
|
+
// Gracefully handle client TCP errors (ECONNRESET, EPIPE, etc.)
|
|
100
|
+
clientErrorHandler: (err, socket) => {
|
|
101
|
+
if (err.code === 'ECONNRESET' || err.code === 'EPIPE' || err.code === 'ECONNABORTED') {
|
|
102
|
+
socket.destroy();
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// Default Fastify behavior for other client errors
|
|
106
|
+
socket.destroy(err);
|
|
107
|
+
}
|
|
99
108
|
};
|
|
100
109
|
|
|
101
110
|
// Add HTTPS support if SSL config provided
|
package/test/ldp.test.js
CHANGED
|
@@ -163,6 +163,47 @@ describe('LDP CRUD Operations', () => {
|
|
|
163
163
|
const verify = await request('/ldptest/public/new-container/');
|
|
164
164
|
assertHeaderContains(verify, 'Link', 'Container');
|
|
165
165
|
});
|
|
166
|
+
|
|
167
|
+
it('should PUT HTML to container with index.html routing to index document', async () => {
|
|
168
|
+
// Create container with an index.html inside
|
|
169
|
+
await request('/ldptest/public/board/', { method: 'PUT', auth: 'ldptest' });
|
|
170
|
+
await request('/ldptest/public/board/index.html', {
|
|
171
|
+
method: 'PUT',
|
|
172
|
+
headers: { 'Content-Type': 'text/html' },
|
|
173
|
+
body: '<html><body>original</body></html>',
|
|
174
|
+
auth: 'ldptest'
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// PUT to container URL with text/html should route to index.html
|
|
178
|
+
const res = await request('/ldptest/public/board/', {
|
|
179
|
+
method: 'PUT',
|
|
180
|
+
headers: { 'Content-Type': 'text/html' },
|
|
181
|
+
body: '<html><body>updated</body></html>',
|
|
182
|
+
auth: 'ldptest'
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
assertStatus(res, 204);
|
|
186
|
+
|
|
187
|
+
// Verify index.html was updated
|
|
188
|
+
const verify = await request('/ldptest/public/board/index.html');
|
|
189
|
+
const content = await verify.text();
|
|
190
|
+
assert.ok(content.includes('updated'), 'index.html should contain updated content');
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('should still 409 on PUT to container without index.html', async () => {
|
|
194
|
+
// Create an empty container
|
|
195
|
+
await request('/ldptest/public/empty-dir/', { method: 'PUT', auth: 'ldptest' });
|
|
196
|
+
|
|
197
|
+
// PUT text/html to container without index.html should still 409
|
|
198
|
+
const res = await request('/ldptest/public/empty-dir/', {
|
|
199
|
+
method: 'PUT',
|
|
200
|
+
headers: { 'Content-Type': 'text/html' },
|
|
201
|
+
body: '<html><body>test</body></html>',
|
|
202
|
+
auth: 'ldptest'
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
assertStatus(res, 409);
|
|
206
|
+
});
|
|
166
207
|
});
|
|
167
208
|
|
|
168
209
|
describe('POST', () => {
|