Fix server crashing with malformed requests
It also adds tests to ensure there are no regressions. Closes #381
This commit is contained in:
parent
858fc3a324
commit
83e6c74936
|
@ -3,6 +3,7 @@
|
||||||
"password": "password",
|
"password": "password",
|
||||||
"name": "The Dude",
|
"name": "The Dude",
|
||||||
"emailToken": "000000",
|
"emailToken": "000000",
|
||||||
|
"serverUrl": "http://localhost:3000",
|
||||||
"v3_email": "user2@example.com",
|
"v3_email": "user2@example.com",
|
||||||
"v3_url": "http://localhost:8081"
|
"v3_url": "http://localhost:8081"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
describe("Server", () => {
|
||||||
|
const { serverUrl } = Cypress.env();
|
||||||
|
|
||||||
|
it("can properly respond to valid and invalid requests", () => {
|
||||||
|
cy.request({ url: `${serverUrl}/`, method: "GET", failOnStatusCode: false }).then(
|
||||||
|
(response) => expect(response.status).to.eq(405) // method not allowed
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.request({ url: `${serverUrl}/`, method: "PUT", failOnStatusCode: false }).then(
|
||||||
|
(response) => expect(response.status).to.eq(405) // method not allowed
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.request({ url: `${serverUrl}/`, method: "OPTIONS" });
|
||||||
|
|
||||||
|
cy.request({ url: `${serverUrl}/`, method: "POST", failOnStatusCode: false }).then(
|
||||||
|
(response) => expect(response.status).to.eq(400) // bad request (no json)
|
||||||
|
);
|
||||||
|
|
||||||
|
cy.request({
|
||||||
|
url: `${serverUrl}/`,
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({ email: "user@example.com" }),
|
||||||
|
}).then((response) => {
|
||||||
|
expect(response.status).to.eq(200);
|
||||||
|
expect(JSON.stringify(response.body)).to.eq(
|
||||||
|
JSON.stringify({
|
||||||
|
result: null,
|
||||||
|
error: {
|
||||||
|
code: "invalid_request",
|
||||||
|
message: "",
|
||||||
|
},
|
||||||
|
kind: "response",
|
||||||
|
version: "3.1.0",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
cy.request({
|
||||||
|
url: `${serverUrl}/`,
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({
|
||||||
|
method: "getAuthInfo",
|
||||||
|
params: [],
|
||||||
|
device: {},
|
||||||
|
auth: {},
|
||||||
|
kind: "request",
|
||||||
|
version: "3.1.0",
|
||||||
|
}),
|
||||||
|
}).then((response) => {
|
||||||
|
expect(response.status).to.eq(200);
|
||||||
|
expect(JSON.stringify(response.body)).to.eq(
|
||||||
|
JSON.stringify({
|
||||||
|
result: null,
|
||||||
|
error: { code: "invalid_session", message: "" },
|
||||||
|
kind: "response",
|
||||||
|
version: "3.1.0",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -60,24 +60,29 @@ export class HTTPReceiver implements Receiver {
|
||||||
httpRes.end();
|
httpRes.end();
|
||||||
break;
|
break;
|
||||||
case "POST":
|
case "POST":
|
||||||
const body = await readBody(httpReq, this.config.maxRequestSize);
|
try {
|
||||||
const req = new Request().fromRaw(unmarshal(body));
|
const body = await readBody(httpReq, this.config.maxRequestSize);
|
||||||
const ipAddress = httpReq.headers["x-forwarded-for"] || httpReq.socket?.remoteAddress;
|
const req = new Request().fromRaw(unmarshal(body));
|
||||||
req.ipAddress = Array.isArray(ipAddress) ? ipAddress[0] : ipAddress;
|
const ipAddress = httpReq.headers["x-forwarded-for"] || httpReq.socket?.remoteAddress;
|
||||||
const location = req.ipAddress && (await getLocation(req.ipAddress));
|
req.ipAddress = Array.isArray(ipAddress) ? ipAddress[0] : ipAddress;
|
||||||
req.location = location
|
const location = req.ipAddress && (await getLocation(req.ipAddress));
|
||||||
? {
|
req.location = location
|
||||||
country: location.country?.names["en"],
|
? {
|
||||||
city: location.city?.names["en"],
|
country: location.country?.names["en"],
|
||||||
}
|
city: location.city?.names["en"],
|
||||||
: undefined;
|
}
|
||||||
|
: undefined;
|
||||||
|
|
||||||
const clientVersion = (req.device && req.device.appVersion) || undefined;
|
const clientVersion = (req.device && req.device.appVersion) || undefined;
|
||||||
const res = await handler(req);
|
const res = await handler(req);
|
||||||
const resBody = marshal(res.toRaw(clientVersion));
|
const resBody = marshal(res.toRaw(clientVersion));
|
||||||
httpRes.setHeader("Content-Type", "application/json; charset=utf-8");
|
httpRes.setHeader("Content-Type", "application/json; charset=utf-8");
|
||||||
httpRes.setHeader("Content-Length", Buffer.byteLength(resBody));
|
httpRes.setHeader("Content-Length", Buffer.byteLength(resBody));
|
||||||
httpRes.write(resBody);
|
httpRes.write(resBody);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
httpRes.statusCode = 400;
|
||||||
|
}
|
||||||
httpRes.end();
|
httpRes.end();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in New Issue