Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: honojs/node-server
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v1.8.2
Choose a base ref
...
head repository: honojs/node-server
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v1.9.0
Choose a head ref
  • 3 commits
  • 6 files changed
  • 2 contributors

Commits on Mar 25, 2024

  1. feat: ignore response if already sent by raw level outgoing API. (#153)

    usualoma authored Mar 25, 2024

    Verified

    This commit was signed with the committer’s verified signature.
    ljharb Jordan Harband
    Copy the full SHA
    3fc502a View commit details
  2. docs(readme): tweak

    yusukebe committed Mar 25, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    9fd3de9 View commit details
  3. v1.9.0

    yusukebe committed Mar 25, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    b254208 View commit details
Showing with 67 additions and 1 deletion.
  1. +27 −0 README.md
  2. +9 −1 package.json
  3. +3 −0 src/listener.ts
  4. +4 −0 src/utils/response.ts
  5. +1 −0 src/utils/response/constants.ts
  6. +23 −0 test/utils/response.test.ts
27 changes: 27 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -212,6 +212,33 @@ type Http2Bindings = {
}
```
## Direct response from Node.js API
You can directly respond to the client from the Node.js API.
In that case, the response from Hono should be ignored, so return `RESPONSE_ALREADY_SENT`.
> [!NOTE]
> This feature can be used when migrating existing Node.js applications to Hono, but we recommend using Hono's API for new applications.
```ts
import { serve } from '@hono/node-server'
import type { HttpBindings } from '@hono/node-server'
import { RESPONSE_ALREADY_SENT } from '@hono/node-server/utils/response'
import { Hono } from 'hono'

const app = new Hono<{ Bindings: HttpBindings }>()

app.get('/', (c) => {
const { outgoing } = c.env
outgoing.writeHead(200, { 'Content-Type': 'text/plain' })
outgoing.end('Hello World\n')

return RESPONSE_ALREADY_SENT
})

serve(app)
```

## Related projects

- Hono - <https://hono.dev>
10 changes: 9 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@hono/node-server",
"version": "1.8.2",
"version": "1.9.0",
"description": "Node.js Adapter for Hono",
"main": "dist/index.js",
"types": "dist/index.d.ts",
@@ -22,6 +22,11 @@
"types": "./dist/vercel.d.ts",
"require": "./dist/vercel.js",
"import": "./dist/vercel.mjs"
},
"./utils/*": {
"types": "./dist/utils/*.d.ts",
"require": "./dist/utils/*.js",
"import": "./dist/utils/*.mjs"
}
},
"typesVersions": {
@@ -34,6 +39,9 @@
],
"vercel": [
"./dist/vercel.d.ts"
],
"utils/*": [
"./dist/utils/*.d.ts"
]
}
},
3 changes: 3 additions & 0 deletions src/listener.ts
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ import { getAbortController, newRequest } from './request'
import { cacheKey, getInternalBody } from './response'
import type { CustomErrorHandler, FetchCallback, HttpBindings } from './types'
import { writeFromReadableStream, buildOutgoingHttpHeaders } from './utils'
import { X_ALREADY_SENT } from './utils/response/constants'
import './globals'

const regBuffer = /^no$/i
@@ -128,6 +129,8 @@ const responseViaResponseObject = async (
outgoing.writeHead(res.status, resHeaderRecord)
outgoing.end(new Uint8Array(buffer))
}
} else if (resHeaderRecord[X_ALREADY_SENT]) {
// do nothing, the response has already been sent
} else {
outgoing.writeHead(res.status, resHeaderRecord)
outgoing.end()
4 changes: 4 additions & 0 deletions src/utils/response.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { X_ALREADY_SENT } from './response/constants'
export const RESPONSE_ALREADY_SENT = new Response(null, {
headers: { [X_ALREADY_SENT]: 'true' },
})
1 change: 1 addition & 0 deletions src/utils/response/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const X_ALREADY_SENT = 'x-hono-already-sent'
23 changes: 23 additions & 0 deletions test/utils/response.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Hono } from 'hono'
import request from 'supertest'
import type { HttpBindings } from '../../src/'
import { createAdaptorServer } from '../../src/server'
import { RESPONSE_ALREADY_SENT } from '../../src/utils/response'

describe('RESPONSE_ALREADY_SENT', () => {
const app = new Hono<{ Bindings: HttpBindings }>()
app.get('/', (c) => {
const { outgoing } = c.env
outgoing.writeHead(200, { 'Content-Type': 'text/plain' })
outgoing.end('Hono!')
return RESPONSE_ALREADY_SENT
})
const server = createAdaptorServer(app)

it('Should return 200 response - GET /', async () => {
const res = await request(server).get('/')
expect(res.status).toBe(200)
expect(res.headers['content-type']).toMatch('text/plain')
expect(res.text).toBe('Hono!')
})
})