Skip to content

fix(middleware): change how mime type option is handled #670

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ export default function wdm(compiler, options = {}) {
if (mimeTypes) {
const { types } = mime;

mime.types = { ...mimeTypes, ...types };
// mimeTypes from user provided options should take priority
// over existing, known types
mime.types = { ...types, ...mimeTypes };
}

const context = {
Expand Down
22 changes: 13 additions & 9 deletions src/middleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,9 @@ export default function wrapper(context) {
return;
}

try {
content = context.outputFileSystem.readFileSync(filename);
} catch (_ignoreError) {
await goNext();
return;
}

// Buffer
content = handleRangeHeaders(content, req, res);
// Content-Type and headers need to be set before checking if
// the file is in the outputFileSystem, as these things should be
// applied to all files that are being served
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

correct me if this approach is incorrect, but it seems that headers and content types need to be applied before rejecting a file that is not in the outputFileSystem. This is because files/routes served by webpack-dev-server like localhost:8080/main, or files that are in the user's directory and are being served, are not in the middleware filesystem but should still have the headers and content types applied to them. That is what the previous behavior was. But let me know if this was an intentional breaking change.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, looks like regression


if (!res.get('Content-Type')) {
// content-type name(like application/javascript; charset=utf-8) or false
Expand All @@ -74,6 +68,16 @@ export default function wrapper(context) {
}
}

try {
content = context.outputFileSystem.readFileSync(filename);
} catch (_ignoreError) {
await goNext();
return;
}

// Buffer
content = handleRangeHeaders(content, req, res);

// send Buffer
res.send(content);
}
Expand Down
97 changes: 93 additions & 4 deletions test/middleware.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1990,7 +1990,7 @@ describe('middleware', () => {

afterAll(close);

it('should return the "200" code for the "GET" request to "file.html"', (done) => {
it('should return the "200" code for the "GET" request to "file.phtml"', (done) => {
request(app)
.get('/file.phtml')
.expect('Content-Type', 'application/octet-stream')
Expand Down Expand Up @@ -2031,13 +2031,91 @@ describe('middleware', () => {

afterAll(close);

it('should return the "200" code for the "GET" request "file.html"', (done) => {
it('should return the "200" code for the "GET" request "file.phtml"', (done) => {
request(app)
.get('/file.phtml')
.expect('Content-Type', 'text/html; charset=utf-8')
.expect(200, 'welcome', done);
});
});

describe('should override value for "Content-Type" header for known MIME type', () => {
beforeAll((done) => {
const outputPath = path.resolve(__dirname, './outputs/basic');
const compiler = getCompiler({
...webpackConfig,
output: {
filename: 'bundle.js',
path: outputPath,
},
});

instance = middleware(compiler, {
mimeTypes: {
jpg: 'application/octet-stream',
},
});

app = express();
app.use(instance);

listen = listenShorthand(done);

instance.context.outputFileSystem.mkdirSync(outputPath, {
recursive: true,
});
instance.context.outputFileSystem.writeFileSync(
path.resolve(outputPath, 'file.jpg'),
'welcome'
);
});

afterAll(close);

it('should return the "200" code for the "GET" request "file.jpg"', (done) => {
request(app)
.get('/file.jpg')
.expect('Content-Type', /application\/octet-stream/)
.expect(200, done);
});
});

describe('should set "Content-Type" header for route not from outputFileSystem', () => {
beforeAll((done) => {
const outputPath = path.resolve(__dirname, './outputs/basic');
const compiler = getCompiler({
...webpackConfig,
output: {
filename: 'bundle.js',
path: outputPath,
},
});

instance = middleware(compiler, {
mimeTypes: {
jpg: 'application/octet-stream',
},
});

app = express();
app.use(instance);

app.get('/file.jpg', (req, res) => {
res.send('welcome');
});

listen = listenShorthand(done);
});

afterAll(close);

it('should return the "200" code for the "GET" request "file.jpg"', (done) => {
request(app)
.get('/file.jpg')
.expect('Content-Type', /application\/octet-stream/)
.expect(200, done);
});
});
});

describe('watchOptions option', () => {
Expand Down Expand Up @@ -2640,7 +2718,7 @@ describe('middleware', () => {
});

describe('headers option', () => {
beforeAll((done) => {
beforeEach((done) => {
const compiler = getCompiler(webpackConfig);

instance = middleware(compiler, {
Expand All @@ -2653,7 +2731,7 @@ describe('middleware', () => {
listen = listenShorthand(done);
});

afterAll(close);
afterEach(close);

it('should return the "200" code for the "GET" request to the bundle file and return headers', (done) => {
request(app)
Expand All @@ -2662,6 +2740,17 @@ describe('middleware', () => {
.expect('X-nonsense-2', 'no')
.expect(200, done);
});

it('should return the "200" code for the "GET" request to path not in outputFileSystem and return headers', (done) => {
app.get('/file.jpg', (req, res) => {
res.send('welcome');
});
request(app)
.get('/file.jpg')
.expect('X-nonsense-1', 'yes')
.expect('X-nonsense-2', 'no')
.expect(200, done);
});
});

describe('publicPath option', () => {
Expand Down