Skip to content

Commit

Permalink
Fix: Infer content type with charset in dev and prod (#3841)
Browse files Browse the repository at this point in the history
* fix: add text/plain;charset;utf-8 header in dev

* test: ensure content type for body shorthand

* chore: changeset

* feat: infer content type by pathname

* feat: add charset to prod build handler

* test: update for charset in prod build test
  • Loading branch information
bholmesdev committed Jul 7, 2022
1 parent b2f53c3 commit 820a26d
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/ten-radios-rush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'astro': patch
---

Fix: add default content type to endpoints with { body } shorthand
4 changes: 3 additions & 1 deletion packages/astro/src/core/app/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,9 @@ export class App {
const headers = new Headers();
const mimeType = mime.getType(url.pathname);
if (mimeType) {
headers.set('Content-Type', mimeType);
headers.set('Content-Type', `${mimeType};charset=utf-8`);
} else {
headers.set('Content-Type', 'text/plain;charset=utf-8');
}
const bytes = this.#encoder.encode(body);
headers.set('Content-Length', bytes.byteLength.toString());
Expand Down
8 changes: 7 additions & 1 deletion packages/astro/src/vite-plugin-astro-server/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type http from 'http';
import type * as vite from 'vite';
import mime from 'mime';
import type { AstroConfig, ManifestData } from '../@types/astro';
import type { SSROptions } from '../core/render/dev/index';

Expand Down Expand Up @@ -315,7 +316,12 @@ async function handleRequest(
if (result.type === 'response') {
await writeWebResponse(res, result.response);
} else {
res.writeHead(200);
let contentType = 'text/plain';
const computedMimeType = route.pathname ? mime.getType(route.pathname) : null;
if (computedMimeType) {
contentType = computedMimeType;
}
res.writeHead(200, { 'Content-Type': `${contentType};charset=utf-8` });
res.end(result.body);
}
} else {
Expand Down
9 changes: 8 additions & 1 deletion packages/astro/test/ssr-api-route.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('API routes in SSR', () => {
const request = new Request('http://example.com/food.json');
const response = await app.render(request);
expect(response.status).to.equal(200);
expect(response.headers.get('Content-Type')).to.equal('application/json');
expect(response.headers.get('Content-Type')).to.equal('application/json;charset=utf-8');
expect(response.headers.get('Content-Length')).to.not.be.empty;
const body = await response.json();
expect(body.length).to.equal(3);
Expand All @@ -56,6 +56,13 @@ describe('API routes in SSR', () => {
expect(text).to.equal(`ok`);
});

it('Infer content type with charset for { body } shorthand', async () => {
const response = await fixture.fetch('/food.json', {
method: 'GET',
});
expect(response.headers.get('Content-Type')).to.equal('application/json;charset=utf-8');
});

it('Can set multiple headers of the same type', async () => {
const response = await fixture.fetch('/login', {
method: 'POST',
Expand Down

0 comments on commit 820a26d

Please sign in to comment.