Skip to content

Commit

Permalink
fix: Origin in API calls in Firefox-65.0a1 (#623)
Browse files Browse the repository at this point in the history
Closes #622
  • Loading branch information
lidel committed Nov 16, 2018
1 parent 36b4e9d commit 000e8da
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 1,823 deletions.
41 changes: 31 additions & 10 deletions add-on/src/lib/ipfs-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ const onHeadersReceivedRedirect = new Set()
// API Details: https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/webRequest
function createRequestModifier (getState, dnslinkResolver, ipfsPathValidator, runtime) {
const browser = runtime.browser
const runtimeRoot = browser.runtime.getURL('/')
const webExtensionOrigin = runtimeRoot ? new URL(runtimeRoot).origin : 'null'

// Ignored requests are identified once and cached across all browser.webRequest hooks
const ignoredRequests = new LRU({ max: 128, maxAge: 1000 * 30 })
Expand Down Expand Up @@ -114,6 +116,35 @@ function createRequestModifier (getState, dnslinkResolver, ipfsPathValidator, ru
}

if (request.url.startsWith(state.apiURLString)) {
// '403 - Forbidden' fix for Chrome and Firefox
// --------------------------------------------
// We remove Origin header from requests made to API URL
// by js-ipfs-api running in WebExtension context to remove need
// for manual whitelisting Access-Control-Allow-Origin at go-ipfs
// More info:
// Chrome: https://github.com/ipfs-shipyard/ipfs-companion/pull/616
// Firefox: https://github.com/ipfs-shipyard/ipfs-companion/issues/622
const isWebExtensionOrigin = (origin) => {
// Chromium
if (origin == null || origin === 'null') {
return true
}
// Firefox Nightly 65 sets moz-extension://{extension-installation-id}
if (origin && origin.startsWith('moz-extension://') && new URL(origin).origin === webExtensionOrigin) {
return true
}
return false
}
for (let i = 0; i < request.requestHeaders.length; i++) {
let header = request.requestHeaders[i]
if (header.name === 'Origin' && isWebExtensionOrigin(header.value)) {
request.requestHeaders.splice(i, 1)
break
}
}

// Fix "http: invalid Read on closed Body"
// ----------------------------------
// There is a bug in go-ipfs related to keep-alive connections
// that results in partial response for ipfs.files.add
// mangled by error "http: invalid Read on closed Body"
Expand Down Expand Up @@ -150,16 +181,6 @@ function createRequestModifier (getState, dnslinkResolver, ipfsPathValidator, ru
request.requestHeaders.push(expectHeader)
}
}
// For some reason js-ipfs-api sends requests with "Origin: null" under Chrome
// which produces '403 - Forbidden' error.
// This workaround removes bogus header from API requests
for (let i = 0; i < request.requestHeaders.length; i++) {
let header = request.requestHeaders[i]
if (header.name === 'Origin' && (header.value == null || header.value === 'null')) {
request.requestHeaders.splice(i, 1)
break
}
}
}
return {
requestHeaders: request.requestHeaders
Expand Down
17 changes: 16 additions & 1 deletion test/functional/lib/ipfs-request-workarounds.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict'
const { describe, it, before, beforeEach, after } = require('mocha')
const { expect } = require('chai')
const { URL } = require('url')
const { URL } = require('url') // URL implementation with support for .origin attribute
const browser = require('sinon-chrome')
const { initState } = require('../../../add-on/src/lib/state')
const createRuntimeChecks = require('../../../add-on/src/lib/runtime-checks')
Expand All @@ -18,6 +18,7 @@ describe('modifyRequest processing', function () {
before(function () {
global.URL = URL
global.browser = browser
browser.runtime.getURL.withArgs('/').returns('moz-extension://0f334731-19e3-42f8-85e2-03dbf50026df/')
})

beforeEach(async function () {
Expand Down Expand Up @@ -45,6 +46,20 @@ describe('modifyRequest processing', function () {
})
})

describe('a request to <apiURL>/api/v0/ with Origin=moz-extension://{extension-installation-id}', function () {
it('should remove Origin header ', function () {
const bogusOriginHeader = { name: 'Origin', value: 'moz-extension://0f334731-19e3-42f8-85e2-03dbf50026df' }
const request = {
requestHeaders: [ bogusOriginHeader ],
type: 'xmlhttprequest',
url: `${state.apiURLString}api/v0/id`
}
modifyRequest.onBeforeRequest(request) // executes before onBeforeSendHeaders, may mutate state
expect(modifyRequest.onBeforeSendHeaders(request).requestHeaders).to.not.include(bogusOriginHeader)
browser.runtime.getURL.flush()
})
})

describe('a request to <apiURL>/api/v0/ with Origin=null', function () {
it('should remove Origin header ', function () {
const bogusOriginHeader = { name: 'Origin', value: 'null' }
Expand Down

0 comments on commit 000e8da

Please sign in to comment.