From d2768b3aa7a306dab1310c35e2ae6423a078e946 Mon Sep 17 00:00:00 2001 From: Juri Leino Date: Fri, 27 Oct 2023 12:44:53 +0200 Subject: [PATCH 1/2] fix(package): installation falls back to XMLRPC fixes #170 Try REST connection, fall back to XMLRPC and inform user that this happened. --- commands/package/install.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/commands/package/install.js b/commands/package/install.js index 645d69e..2bb0091 100644 --- a/commands/package/install.js +++ b/commands/package/install.js @@ -108,8 +108,13 @@ export async function handler (argv) { if (rest) { upload = boundUpload } else { - const test = await restClient.get('db') - upload = test.statusCode === 200 ? boundUpload : db.app.upload + try { + await restClient.get('db') + upload = boundUpload + } catch (e) { + console.log('Falling back to XMLRPC API') + upload = db.app.upload + } } } From 6a98d507b2d245a214bc44dc42996264765481cb Mon Sep 17 00:00:00 2001 From: Juri Leino Date: Wed, 15 Nov 2023 12:26:24 +0100 Subject: [PATCH 2/2] test: add facility to test with REST disabled --- .github/workflows/test-no-rest.yml | 41 +++ package.json | 1 + spec/fixtures/web-no-rest.xml | 409 +++++++++++++++++++++++++++++ spec/norest/package/install.js | 60 +++++ spec/tests/list.js | 22 +- 5 files changed, 523 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/test-no-rest.yml create mode 100644 spec/fixtures/web-no-rest.xml create mode 100644 spec/norest/package/install.js diff --git a/.github/workflows/test-no-rest.yml b/.github/workflows/test-no-rest.yml new file mode 100644 index 0000000..c6a0c4c --- /dev/null +++ b/.github/workflows/test-no-rest.yml @@ -0,0 +1,41 @@ +name: Test - No REST + +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + # pull image + - run: docker pull existdb/existdb:release + # create docker container + # --volume $(pwd)/empty:/exist/autodeploy:ro + - name: create eXist-db Container + run: docker create --name exist --publish 8080:8080 --publish 8443:8443 existdb/existdb:release + # - name: Start eXist-db Container + # run: docker start exist + # - name: Wait for eXist-db Startup + # run: timeout 90 sh -c 'until nc -z $0 $1; do sleep 3; done' localhost 8080 + # get web.xml (use prepared web.xml instead) + # - run: docker cp exist:exist/etc/webapp/WEB-INF/web.xml ./web.xml + # modify web.xml + # - run: cat web.xml | \ + # tr '\n' '\r' | \ + # sed -E 's/(hidden<\/param-name>\r[[:space:]]+)false(<\/param-value>)/\1true\2/' | \ + # tr '\r' '\n' > modified-web.xml + - name: Copy modified web.xml + run: docker cp ./spec/fixtures/web-no-rest.xml exist:exist/etc/webapp/WEB-INF/web.xml + - name: Restart eXist-db Container + # run: docker stop exist && docker wait; docker start exist + run: docker start exist + - name: Wait for eXist-db Startup + run: timeout 90 sh -c 'until nc -z $0 $1; do sleep 3; done' localhost 8080 + - name: Use Node.js 20 + uses: actions/setup-node@v3 + with: + node-version: 20 + - run: npm ci --no-optional + - run: npm link + - run: npm run test:norest + diff --git a/package.json b/package.json index 24506fd..786aba1 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ }, "scripts": { "test": "standard && tape \"spec/tests/**/*.js\"", + "test:norest": "tape \"spec/norest/**/*.js\"", "lint": "standard --fix" }, "keywords": [ diff --git a/spec/fixtures/web-no-rest.xml b/spec/fixtures/web-no-rest.xml new file mode 100644 index 0000000..699f51d --- /dev/null +++ b/spec/fixtures/web-no-rest.xml @@ -0,0 +1,409 @@ + + + + eXist Open Source Native XML Database + eXist XML Database + + + + + org.exist.xmlrpc.RpcServlet + org.exist.xmlrpc.RpcServlet + + enabledForExtensions + true + + + + useDefaultUser + true + + + + charset + UTF-8 + + + + + EXistServlet + org.exist.http.servlets.EXistServlet + + + configuration + conf.xml + + + + basedir + WEB-INF/ + + + start + true + + + + hidden + true + + + + xquery-submission + enabled + + + + xupdate-submission + enabled + + 2 + + + + JMXServlet + org.exist.management.client.JMXServlet + + + + milton + org.exist.webdav.MiltonWebDAVServlet + + resource.factory.class + org.exist.webdav.ExistResourceFactory + + + + + + + + + XQueryServlet + org.exist.http.servlets.XQueryServlet + + uri + xmldb:exist:///db + + + form-encoding + UTF-8 + + + container-encoding + UTF-8 + + + encoding + UTF-8 + + + hide-error-messages + false + + + + + XQueryURLRewrite + org.exist.http.urlrewrite.XQueryURLRewrite + + + config + WEB-INF/controller-config.xml + + + + + + + send-challenge + true + + + + + XSLTServlet + org.exist.http.servlets.XSLTServlet + + + + RestXqServlet + org.exist.extensions.exquery.restxq.impl.RestXqServlet + + + + jnlp + org.exist.webstart.JnlpServlet + + + + + + XQueryURLRewrite + /* + + + + + + + + + + css + text/css + + + xml + application/xml + + + xsl + application/xml+xslt + + + xconf + application/xml + + + xmap + application/xml + + + ent + text/plain + + + grm + text/plain + + + + FORM + JAASLoginService + + /login/login + /login/error + + + + + diff --git a/spec/norest/package/install.js b/spec/norest/package/install.js new file mode 100644 index 0000000..9b094c4 --- /dev/null +++ b/spec/norest/package/install.js @@ -0,0 +1,60 @@ +import { test } from 'tape' +import { run, asAdmin } from '../../test.js' + +const testLibName = 'http://exist-db.org/apps/test-lib' + +async function removeTestlib (t) { + const { stderr } = await run('xst', ['run', `repo:undeploy("${testLibName}"),repo:remove("${testLibName}")`], asAdmin) + if (stderr) { + console.error(stderr) + t.fail(stderr) + } +} + +async function cleanup (t) { + await removeTestlib(t) +} + +test('package install without REST', async function (t) { + t.test('falls back to XMLRPC, succeeds', async function (st) { + const { stderr, stdout } = await run('xst', ['package', 'install', 'spec/fixtures/test-lib.xar'], asAdmin) + if (stderr) { + st.fail(stderr) + st.end() + return + } + + const lines = stdout.split('\n') + st.equal(lines[0], 'Falling back to XMLRPC API') + st.equal(lines[1], 'Install test-lib.xar on https://localhost:8443') + st.equal(lines[2], '✔︎ uploaded') + st.equal(lines[3], '✔︎ installed') + st.end() + }) + + t.test('succeeds when enforcing upload over XMLRPC', async function (st) { + const { stderr, stdout } = await run('xst', ['package', 'install', '--rpc', 'spec/fixtures/test-lib.xar'], asAdmin) + if (stderr) { + st.fail(stderr) + st.end() + return + } + + const lines = stdout.split('\n') + st.equal(lines[0], 'Install test-lib.xar on https://localhost:8443') + st.equal(lines[1], '✔︎ uploaded') + st.equal(lines[2], '✔︎ updated') + st.end() + }) + + t.test('fails with enforced upload over REST', async function (st) { + const { stderr, stdout } = await run('xst', ['package', 'install', '--rest', 'spec/fixtures/test-lib.xar'], asAdmin) + + st.equal(stdout, 'Install test-lib.xar on https://localhost:8443\n') + + st.equal(stderr, 'Response code 403 (Forbidden)\n') + st.end() + }) + + t.teardown(cleanup) +}) diff --git a/spec/tests/list.js b/spec/tests/list.js index 58a7896..bbbc90d 100644 --- a/spec/tests/list.js +++ b/spec/tests/list.js @@ -7,7 +7,7 @@ const testSourceFolder = 'spec' async function prepare (t) { try { - const phase1 = await run('xst', ['up', '-D', '-e', 'tests', testSourceFolder, testCollection], asAdmin) + const phase1 = await run('xst', ['up', '-D', '-e', 'tests', '-e', 'norest', testSourceFolder, testCollection], asAdmin) if (phase1.stderr) { throw Error(phase1.stderr) } const ensureTestsOlder = await run('xst', ['up', '-e', 'package,utility', testSourceFolder + '/tests', testCollection + '/tests'], asAdmin) if (ensureTestsOlder.stderr) { throw Error(ensureTestsOlder.stderr) } @@ -181,7 +181,7 @@ test('with fixtures uploaded', async (t) => { if (stderr) { return st.fail(stderr) } const expectedlines = 'a.txt\na1.txt\na11.json\na20.txt\na22.xml\nb\nfixtures\nindex.html\ntest.js\ntest.xq\ntests\n' - st.equal(expectedlines, stdout, stdout) + st.equal(stdout, expectedlines, stdout) st.end() }) @@ -190,7 +190,7 @@ test('with fixtures uploaded', async (t) => { if (stderr) { return st.fail(stderr) } const expectedlines = 'tests\ntest.xq\ntest.js\nindex.html\nfixtures\nb\na22.xml\na20.txt\na11.json\na1.txt\na.txt\n' - st.equal(expectedlines, stdout, stdout) + st.equal(stdout, expectedlines, stdout) st.end() }) @@ -199,7 +199,7 @@ test('with fixtures uploaded', async (t) => { if (stderr) { return st.fail(stderr) } const expectedlines = 'b\nfixtures\ntests\nindex.html\ntest.js\na11.json\na.txt\na1.txt\na20.txt\na22.xml\ntest.xq\n' - st.equal(expectedlines, stdout, stdout) + st.equal(stdout, expectedlines, stdout) st.end() }) @@ -208,7 +208,7 @@ test('with fixtures uploaded', async (t) => { if (stderr) { return st.fail(stderr) } const expectedlines = 'a22.xml\nindex.html\ntest.js\na11.json\na.txt\na1.txt\na20.txt\nb\ntest.xq\nfixtures\ntests\n' - st.equal(expectedlines, stdout, stdout) + st.equal(stdout, expectedlines, stdout) st.end() }) @@ -217,7 +217,7 @@ test('with fixtures uploaded', async (t) => { if (stderr) { return t.fail(stderr) } const expectedlines = 'tests\nfixtures\ntest.xq\nb\na20.txt\na1.txt\na.txt\na11.json\ntest.js\nindex.html\na22.xml\n' - st.equal(expectedlines, stdout, stdout) + st.equal(stdout, expectedlines, stdout) st.end() }) @@ -227,7 +227,7 @@ test('with fixtures uploaded', async (t) => { const expectedlines = 'test.xq\nindex.html\na22.xml\na20.txt\na11.json\na1.txt\na.txt\nb\ntests\ntest.js\nfixtures\n' - st.equal(expectedlines, stdout, stdout) + st.equal(stdout, expectedlines, stdout) st.end() }) @@ -236,7 +236,7 @@ test('with fixtures uploaded', async (t) => { if (stderr) { return st.fail(stderr) } const expectedlines = 'fixtures\ntests\ntest.xq\nb\na.txt\na1.txt\na20.txt\na11.json\ntest.js\na22.xml\nindex.html\n' - st.equal(expectedlines, stdout, stdout) + st.equal(stdout, expectedlines, stdout) st.end() }) @@ -260,6 +260,7 @@ test('with fixtures uploaded', async (t) => { /db/list-test/fixtures/test-lib.xar /db/list-test/fixtures/test.xml /db/list-test/fixtures/test.xq +/db/list-test/fixtures/web-no-rest.xml /db/list-test/index.html /db/list-test/test.js /db/list-test/test.xq @@ -273,7 +274,7 @@ test('with fixtures uploaded', async (t) => { /db/list-test/tests/rm.js /db/list-test/tests/upload.js ` - st.equal(expectedlines, stdout, stdout) + st.equal(stdout, expectedlines, stdout) st.end() }) @@ -291,6 +292,7 @@ test('with fixtures uploaded', async (t) => { /db/list-test/fixtures/test-lib.xar /db/list-test/fixtures/broken-test-app.xar /db/list-test/fixtures/test.xml +/db/list-test/fixtures/web-no-rest.xml /db/list-test/tests /db/list-test/tests/cli.js /db/list-test/tests/info.js @@ -310,7 +312,7 @@ test('with fixtures uploaded', async (t) => { /db/list-test/a22.xml /db/list-test/index.html ` - st.equal(expectedlines, stdout, stdout) + st.equal(stdout, expectedlines, stdout) st.end() })