@lzpong/httpm 1.2.0 → 1.2.1

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.
Files changed (3) hide show
  1. package/README.md +17 -0
  2. package/httpm.js +7 -8
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -224,6 +224,7 @@ app.ws('/chat/:room', (ws, req) => {
224
224
  ```javascript
225
225
  app.wss.broadcast('/chat', 'Hello everyone'); // 按路径分组广播
226
226
  app.wss.broadcast('/chat', 'Hello', ws); // 排除指定连接(传 ws 对象)
227
+ app.wss.broadcastAll('Hello everyone'); // 全局广播
227
228
  app.wss.getConnections(); // 获取所有连接
228
229
  ```
229
230
 
@@ -237,6 +238,13 @@ app.wss.getConnections(); // 获取所有连接
237
238
  | `close` | 连接关闭,回调参数 `(code, reason)` |
238
239
  | `error` | 连接错误 |
239
240
 
241
+ ### WebSocket 方法
242
+
243
+ | 方法 | 说明 |
244
+ |------|------|
245
+ | `ws.send(data)` | 发送消息(自动区分文本/JSON/二进制) |
246
+ | `ws.close(code, reason)` | 关闭连接,可选状态码和原因 |
247
+
240
248
  ### data 事件使用
241
249
 
242
250
  ```javascript
@@ -382,6 +390,15 @@ const app = httpm({
382
390
  });
383
391
  ```
384
392
 
393
+ ## 关闭服务
394
+
395
+ ```javascript
396
+ // 关闭 HTTP/HTTPS 服务器并断开所有 WebSocket 连接
397
+ app.close(() => {
398
+ console.log('Server closed');
399
+ });
400
+ ```
401
+
385
402
  ## 导出接口
386
403
 
387
404
  ```javascript
package/httpm.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * httpm - 基于 Node.js 原生模块的单文件、零依赖 HTTP 服务库
3
3
  *
4
4
  * @name httpm
5
- * @version 1.2.0
5
+ * @version 1.2.1
6
6
  * @description 兼容 Express API,内置路由、中间件、静态文件服务、
7
7
  * WebSocket、SSE、流式上传、日志系统等功能
8
8
  * @license MIT
@@ -2191,6 +2191,8 @@ class Application extends Router {
2191
2191
  * 错误处理:查找错误处理中间件(4 个参数)
2192
2192
  */
2193
2193
  _handleError(err, req, res, stack, startIdx) {
2194
+ // 无错误时直接返回(错误处理中间件调用 next() 无参数表示错误已处理)
2195
+ if (!err) return;
2194
2196
  // 从当前栈中查找错误处理中间件
2195
2197
  for (let i = startIdx; i < stack.length; i++) {
2196
2198
  const handler = stack[i].handler;
@@ -2384,23 +2386,20 @@ class Application extends Router {
2384
2386
  */
2385
2387
  _renderDirectoryHTML(requestPath, items) {
2386
2388
  // requestPath 已去掉前导 /,空字符串表示根目录
2387
- // path.dirname('subdir') 返回 '.',应映射为根目录 ''
2388
- let parentPath = requestPath ? path.dirname(requestPath) : '/';
2389
- if (parentPath === '.') parentPath = '';
2390
2389
  // 根目录时显示 '/',否则显示请求路径
2391
2390
  const displayPath = requestPath || '/';
2392
2391
  let html = `<!DOCTYPE html><html><head><meta charset="utf-8"><title>Directory: ${escapeHtml(displayPath)}</title>`;
2393
2392
  html += `<style>body{font-family:-apple-system,sans-serif;margin:20px;background:#f5f5f5}h1{font-size:18px;color:#333}table{width:100%;border-collapse:collapse;background:#fff;box-shadow:0 1px 3px rgba(0,0,0,.1)}th{text-align:left;padding:10px 12px;background:#f8f8f8;border-bottom:2px solid #ddd;font-size:13px;color:#666}td{padding:8px 12px;border-bottom:1px solid #eee;font-size:13px}a{color:#0066cc;text-decoration:none}a:hover{text-decoration:underline}.dir{font-weight:bold}.size{color:#999}</style>`;
2394
2393
  html += `</head><body><h1>Directory: ${escapeHtml(displayPath)}</h1><table><tr><th>Name</th><th>Size</th><th>Modified</th></tr>`;
2395
2394
 
2396
- // 父目录链接(根目录时不显示)
2395
+ // 父目录链接:使用相对路径 .. 返回上一级(根目录时不显示)
2397
2396
  if (requestPath && requestPath !== '/') {
2398
- html += `<tr><td><a href="${escapeHtml(parentPath)}" class="dir">../</a></td><td class="size">-</td><td>-</td></tr>`;
2397
+ html += `<tr><td><a href=".." class="dir">../</a></td><td class="size">-</td><td>-</td></tr>`;
2399
2398
  }
2400
2399
 
2401
2400
  for (const item of items) {
2402
- // 使用 '/' 拼接路径,防止 Windows 上 path.join 产生反斜杠导致 href 失效
2403
- const href = requestPath ? requestPath + '/' + item.name : item.name;
2401
+ // 仅使用文件名作为相对 href,页面 URL 本身已包含目录路径
2402
+ const href = item.name;
2404
2403
  const name = item.isDirectory ? item.name + '/' : item.name;
2405
2404
  const size = item.isDirectory ? '-' : fmtSize(item.size);
2406
2405
  const cls = item.isDirectory ? 'dir' : '';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lzpong/httpm",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "基于 Node.js 原生模块的单文件、零依赖 HTTP 服务库,兼容 Express API",
5
5
  "main": "httpm.js",
6
6
  "files": [