0
0
mirror of https://github.com/honojs/hono.git synced 2024-12-01 11:51:01 +01:00

Merge branch 'main' into next

This commit is contained in:
Yusuke Wada 2023-05-12 16:11:12 +09:00
commit 1bfecc15e2
3 changed files with 85 additions and 28 deletions

View File

@ -9,6 +9,12 @@ describe('AWS Lambda Adapter for Hono', () => {
return c.text('Hello Lambda!')
})
app.get('/binary', (c) => {
return c.body('Fake Image', 200, {
'Content-Type': 'image/png',
})
})
app.post('/post', async (c) => {
const body = (await c.req.parseBody()) as { message: string }
return c.text(body.message)
@ -35,8 +41,27 @@ describe('AWS Lambda Adapter for Hono', () => {
const response = await handler(event)
expect(response.statusCode).toBe(200)
expect(response.body).toBe('SGVsbG8gTGFtYmRhIQ==')
expect(response.body).toBe('Hello Lambda!')
expect(response.headers['content-type']).toMatch(/^text\/plain/)
expect(response.isBase64Encoded).toBe(false)
})
it('Should handle a GET request and return a 200 response with binary', async () => {
const event = {
httpMethod: 'GET',
headers: {},
path: '/binary',
body: null,
isBase64Encoded: false,
requestContext: {
domainName: 'example.com',
},
}
const response = await handler(event)
expect(response.statusCode).toBe(200)
expect(response.body).toBe('RmFrZSBJbWFnZQ==')
expect(response.headers['content-type']).toMatch(/^image\/png/)
expect(response.isBase64Encoded).toBe(true)
})
@ -53,14 +78,14 @@ describe('AWS Lambda Adapter for Hono', () => {
method: 'GET',
},
},
};
const response = await handler(event);
expect(response.statusCode).toBe(200);
expect(response.body).toBe('SGVsbG8gTGFtYmRhIQ==');
expect(response.headers['content-type']).toMatch(/^text\/plain/);
expect(response.isBase64Encoded).toBe(true);
});
}
const response = await handler(event)
expect(response.statusCode).toBe(200)
expect(response.body).toBe('Hello Lambda!')
expect(response.headers['content-type']).toMatch(/^text\/plain/)
expect(response.isBase64Encoded).toBe(false)
})
it('Should handle a GET request and return a 404 response', async () => {
const event = {
@ -96,12 +121,12 @@ describe('AWS Lambda Adapter for Hono', () => {
const response = await handler(event)
expect(response.statusCode).toBe(200)
expect(response.body).toBe('R29vZCBNb3JuaW5nIExhbWJkYSE=')
expect(response.body).toBe('Good Morning Lambda!')
})
it('Should handle a POST request and return a 200 response (LambdaFunctionUrlEvent)', async () => {
const searchParam = new URLSearchParams();
searchParam.append('message', 'Good Morning Lambda!');
const searchParam = new URLSearchParams()
searchParam.append('message', 'Good Morning Lambda!')
const event = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
@ -116,13 +141,13 @@ describe('AWS Lambda Adapter for Hono', () => {
method: 'POST',
},
},
};
const response = await handler(event);
expect(response.statusCode).toBe(200);
expect(response.body).toBe('R29vZCBNb3JuaW5nIExhbWJkYSE=');
});
}
const response = await handler(event)
expect(response.statusCode).toBe(200)
expect(response.body).toBe('Good Morning Lambda!')
})
it('Should handle a request and return a 401 response with Basic auth', async () => {
const event = {
httpMethod: 'GET',
@ -159,6 +184,6 @@ describe('AWS Lambda Adapter for Hono', () => {
const response = await handler(event)
expect(response.statusCode).toBe(200)
expect(response.body).toBe('R29vZCBOaWdodCBMYW1iZGEh')
expect(response.body).toBe('Good Night Lambda!')
})
})

View File

@ -0,0 +1,15 @@
import { isContentTypeBinary } from './handler'
describe('isContentTypeBinary', () => {
it('Should determine whether it is binary', () => {
expect(isContentTypeBinary('image/png')).toBe(true)
expect(isContentTypeBinary('font/woff2')).toBe(true)
expect(isContentTypeBinary('text/plain')).toBe(false)
expect(isContentTypeBinary('text/plain; charset=UTF-8')).toBe(false)
expect(isContentTypeBinary('text/css')).toBe(false)
expect(isContentTypeBinary('text/javascript')).toBe(false)
expect(isContentTypeBinary('application/json')).toBe(false)
expect(isContentTypeBinary('application/ld+json')).toBe(false)
expect(isContentTypeBinary('application/json; charset=UTF-8')).toBe(false)
})
})

View File

@ -40,9 +40,9 @@ interface LambdaFunctionUrlEvent {
body: string | null
isBase64Encoded: boolean
requestContext: {
domainName: string,
domainName: string
http: {
method: string,
method: string
}
}
}
@ -69,11 +69,16 @@ export const handle = (app: Hono) => {
}
const createResult = async (res: Response): Promise<APIGatewayProxyResult> => {
const contentType = res.headers.get('content-type')
const isBase64Encoded = contentType && isContentTypeBinary(contentType) ? true : false
const body = isBase64Encoded ? await fromReadableToString(res) : await res.text()
const result: APIGatewayProxyResult = {
body: await fromReadableToString(res),
body: body,
headers: {},
statusCode: res.status,
isBase64Encoded: true,
isBase64Encoded,
}
res.headers.forEach((value, key) => {
@ -83,9 +88,13 @@ const createResult = async (res: Response): Promise<APIGatewayProxyResult> => {
return result
}
const createRequest = (event: APIGatewayProxyEvent | APIGatewayProxyEventV2 | LambdaFunctionUrlEvent) => {
const createRequest = (
event: APIGatewayProxyEvent | APIGatewayProxyEventV2 | LambdaFunctionUrlEvent
) => {
const queryString = extractQueryString(event)
const urlPath = `https://${event.requestContext.domainName}${isProxyEvent(event) ? event.path : event.rawPath}`
const urlPath = `https://${event.requestContext.domainName}${
isProxyEvent(event) ? event.path : event.rawPath
}`
const url = queryString ? `${urlPath}?${queryString}` : urlPath
const headers = new Headers()
@ -96,7 +105,7 @@ const createRequest = (event: APIGatewayProxyEvent | APIGatewayProxyEventV2 | La
const method = 'httpMethod' in event ? event.httpMethod : event.requestContext.http.method
const requestInit: RequestInit = {
headers,
method
method,
}
if (event.body) {
@ -106,7 +115,9 @@ const createRequest = (event: APIGatewayProxyEvent | APIGatewayProxyEventV2 | La
return new Request(url, requestInit)
}
const extractQueryString = (event: APIGatewayProxyEvent | APIGatewayProxyEventV2 | LambdaFunctionUrlEvent) => {
const extractQueryString = (
event: APIGatewayProxyEvent | APIGatewayProxyEventV2 | LambdaFunctionUrlEvent
) => {
if (isProxyEvent(event)) {
return Object.entries(event.queryStringParameters || {})
.filter(([, value]) => value)
@ -142,3 +153,9 @@ const fromReadableToString = async (res: Response) => {
return btoa(string)
}
export const isContentTypeBinary = (contentType: string) => {
return !/^(text\/(plain|html|css|javascript|csv).*|application\/(.*json|.*xml).*|image\/svg\+xml)$/.test(
contentType
)
}