Merge pull request #15895 from overleaf/jpa-latexqc-fetch-backend

[latexqc] migrate backend from axios to fetch

GitOrigin-RevId: 6dc1a9ca0aa96da01229fec96d3c4b34750f4aa2
This commit is contained in:
Jakob Ackermann 2023-11-28 09:12:06 +01:00 committed by Copybot
parent 011609b345
commit 7a87bf4288
4 changed files with 75 additions and 0 deletions

View file

@ -80,6 +80,35 @@ async function fetchNothing(url, opts = {}) {
return response return response
} }
/**
* Make a request and extract the redirect from the response.
*
* @param {string | URL} url - request URL
* @param {object} opts - fetch options
* @return {Promise<string>}
* @throws {RequestFailedError} if the response has a non redirect status code or missing Location header
*/
async function fetchRedirect(url, opts = {}) {
const { fetchOpts } = parseOpts(opts)
fetchOpts.redirect = 'manual'
const response = await performRequest(url, fetchOpts)
if (response.status < 300 || response.status >= 400) {
const body = await maybeGetResponseBody(response)
throw new RequestFailedError(url, opts, response, body)
}
const location = response.headers.get('Location')
if (!location) {
const body = await maybeGetResponseBody(response)
throw new RequestFailedError(url, opts, response, body).withCause(
new OError('missing Location response header on 3xx response', {
headers: Object.fromEntries(response.headers.entries()),
})
)
}
await discardResponseBody(response)
return location
}
/** /**
* Make a request and return a string. * Make a request and return a string.
* *
@ -222,6 +251,7 @@ module.exports = {
fetchStream, fetchStream,
fetchStreamWithResponse, fetchStreamWithResponse,
fetchNothing, fetchNothing,
fetchRedirect,
fetchString, fetchString,
fetchStringWithResponse, fetchStringWithResponse,
RequestFailedError, RequestFailedError,

View file

@ -7,6 +7,7 @@ const {
fetchJson, fetchJson,
fetchStream, fetchStream,
fetchNothing, fetchNothing,
fetchRedirect,
fetchString, fetchString,
RequestFailedError, RequestFailedError,
} = require('../..') } = require('../..')
@ -205,6 +206,36 @@ describe('fetch-utils', function () {
await expectRequestAborted(this.server.lastReq) await expectRequestAborted(this.server.lastReq)
}) })
}) })
describe('fetchRedirect', function () {
it('returns the immediate redirect', async function () {
const body = await fetchRedirect(this.url('/redirect/1'))
expect(body).to.equal(this.url('/redirect/2'))
})
it('rejects status 200', async function () {
await expect(fetchRedirect(this.url('/hello'))).to.be.rejectedWith(
RequestFailedError
)
await expectRequestAborted(this.server.lastReq)
})
it('rejects empty redirect', async function () {
await expect(fetchRedirect(this.url('/redirect/empty-location')))
.to.be.rejectedWith(RequestFailedError)
.and.eventually.have.property('cause')
.and.to.have.property('message')
.to.equal('missing Location response header on 3xx response')
await expectRequestAborted(this.server.lastReq)
})
it('handles errors', async function () {
await expect(fetchRedirect(this.url('/500'))).to.be.rejectedWith(
RequestFailedError
)
await expectRequestAborted(this.server.lastReq)
})
})
}) })
async function streamToString(stream) { async function streamToString(stream) {

View file

@ -73,6 +73,18 @@ class TestServer {
// Never returns // Never returns
this.app.post('/hang', (req, res) => {}) this.app.post('/hang', (req, res) => {})
// Redirect
this.app.get('/redirect/1', (req, res) => {
res.redirect('/redirect/2')
})
this.app.get('/redirect/2', (req, res) => {
res.send('body after redirect')
})
this.app.get('/redirect/empty-location', (req, res) => {
res.sendStatus(302)
})
} }
start(port) { start(port) {

2
package-lock.json generated
View file

@ -41413,6 +41413,7 @@
"version": "0.0.1", "version": "0.0.1",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@overleaf/fetch-utils": "*",
"aws-sdk": "^2.1174.0", "aws-sdk": "^2.1174.0",
"axios": "^0.21.2", "axios": "^0.21.2",
"body-parser": "^1.19.2", "body-parser": "^1.19.2",
@ -67341,6 +67342,7 @@
"@babel/preset-env": "^7.23.2", "@babel/preset-env": "^7.23.2",
"@babel/preset-react": "^7.22.15", "@babel/preset-react": "^7.22.15",
"@babel/register": "^7.22.15", "@babel/register": "^7.22.15",
"@overleaf/fetch-utils": "*",
"aws-sdk": "^2.1174.0", "aws-sdk": "^2.1174.0",
"axios": "^0.21.2", "axios": "^0.21.2",
"babel-loader": "^9.1.3", "babel-loader": "^9.1.3",