question: It does't work with express-mysql-session
I was trying to...
use this library with express-mysql-session, but it doesn't work.
The problem:
The error occurs when...
- Run the code below.
- Access to
localhost:3000(Got a session-id) - Access to
localhost:3000/secret
then I expect to get an Unauthorized Error(401) but get a net::ERR_CONTENT_LENGTH_MISMATCH
import "reflect-metadata";
import express from "express";
import session from "express-session";
import MySQLStoreClassFactory from "express-mysql-session";
import {
Authorized,
Controller,
Get,
Session,
useExpressServer,
} from "routing-controllers";
const PORT = 3000;
const SECRET = "secret";
const DB_HOST = "localhost";
const DB_PORT = 3306;
const DB_USER = "root";
const DB_PASS = "password";
const DB_NAME = "express_session";
const app = express();
const MySQLSessionStore = MySQLStoreClassFactory(session as any);
const sessionStore = new MySQLSessionStore({
host: DB_HOST,
port: DB_PORT,
user: DB_USER,
password: DB_PASS,
database: DB_NAME,
});
@Controller()
class IndexController {
@Get("/")
index(@Session() sess: any) {
sess.views = (sess.views || 0) + 1;
return "Hello World";
}
@Authorized()
@Get("/secret")
secret() {
return "Secret Page";
}
}
app.use(
session({
secret: SECRET,
store: sessionStore,
resave: false,
saveUninitialized: false,
})
);
useExpressServer(app, {
controllers: [IndexController],
authorizationChecker: () => false,
});
app.listen(PORT, () => {
console.log(`Server is listening on port ${PORT}`);
});
I think this is because...
https://github.com/typestack/routing-controllers/blob/24556885e58e1022531881eecb963c363e9933a9/src/driver/express/ExpressDriver.ts#L384-L391
Here, the next callback is called after the res.send method was called. (ref #589)
the res.send method calls res.end internally and when using express-session library, res.end method is proxied.
In this proxy, the first ${chunk.length - 1} bytes of the data chunk will be written immediately but the remaining one byte will be written after saving/touching session data to the data store asynchronously.
ref https://github.com/expressjs/session/blob/a8641429502fcc076c4b2dcbd6b2320891c1650c/index.js#L334-L343
if (shouldSave(req)) {
req.session.save(function onsave(err) {
if (err) {
defer(next, err);
}
writeend();
});
return writetop();
} else if (...) {
On the other hand, when the next callback is called with an error, the error will be passed to this method.
In this method, if the headers of the response have already been sent, the socket of the response will be destroyed. ref https://github.com/pillarjs/finalhandler/blob/15e78cab32ecbd4993d1575a065963b238336df9/index.js#L126-L130
So, when the socket is destroyed before the last byte of the data chunk is written, the CONTENT_LENGTH_MISMATCH error happens. (actually, content length was mismatched by 1 byte)
As mentioned in #589, the next callback seems strange.
But this issue is about a very ordinary use case, so I feel there is some best practice I don't know.
So, I want to know how to set up this amazing library with express-mysql-session if you have any idea.