Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions omega-locales/en_US/LC_MESSAGES/omega-web.po
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,30 @@ msgstr ""
"The rule list will be updated from this URL. If it is left blank, the "
"following text will be parsed instead."

msgid "options_group_ruleListHeaders"
msgstr "Custom Headers"

msgid "options_ruleListHeaderName"
msgstr "Header Name"

msgid "options_ruleListHeaderValue"
msgstr "Header Value"

msgid "options_ruleListHeaderNamePlaceholder"
msgstr "e.g. Authorization"

msgid "options_ruleListHeaderValuePlaceholder"
msgstr "e.g. Bearer my-token"

msgid "options_ruleListHeadersHelp"
msgstr "You can specify custom HTTP headers to include when downloading the rule list. This is useful if, for example, the source requires authentication."

msgid "options_deleteHeader"
msgstr "Delete header"

msgid "options_addHeader"
msgstr "Add header"

msgid "options_group_ruleListText"
msgstr "Rule List Text"

Expand Down
15 changes: 9 additions & 6 deletions omega-target-chromium-extension/src/module/fetch_url.coffee
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

xhrWrapper currently doesn't handle other 4xx errors (most notably 401 and 403), and instead treat those as success. Obviously this isn't ideal, but this belongs in a separate PR.

Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@ Promise = OmegaTarget.Promise
Url = require('url')
ContentTypeRejectedError = OmegaTarget.ContentTypeRejectedError

xhrWrapper = (args...) ->
fetch(args...).then((response) ->
xhrWrapper = (url, headers) ->
options = {}
if headers
options.headers = headers
fetch(url, options).then((response) ->
response.text().then((body) ->
return [response, body]
)
Expand All @@ -18,7 +21,7 @@ xhrWrapper = (args...) ->
throw new OmegaTarget.HttpServerError(err)
throw new OmegaTarget.HttpError(err)

fetchUrl = (dest_url, opt_bypass_cache, opt_type_hints) ->
fetchUrl = (dest_url, headers, opt_bypass_cache, opt_type_hints) ->
getResBody = ([response, body]) ->
return body unless opt_type_hints
contentType = response.headers['content-type']?.toLowerCase()
Expand All @@ -36,11 +39,11 @@ fetchUrl = (dest_url, opt_bypass_cache, opt_type_hints) ->
parsed.query['_'] = Date.now()
dest_url_nocache = Url.format(parsed)
# Try first with the dumb parameter to bypass cache.
xhrWrapper(dest_url_nocache).then(getResBody).catch ->
xhrWrapper(dest_url_nocache, headers).then(getResBody).catch ->
# If failed, try again with the original URL.
xhrWrapper(dest_url).then(getResBody)
xhrWrapper(dest_url, headers).then(getResBody)
else
xhrWrapper(dest_url).then(getResBody)
xhrWrapper(dest_url, headers).then(getResBody)

defaultHintHandler = (response, body, {contentType, hint}) ->
if '!' + contentType == hint
Expand Down
10 changes: 8 additions & 2 deletions omega-target/src/options.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,12 @@ class Options
url = OmegaPac.Profiles.updateUrl(profile)
if url
type_hints = OmegaPac.Profiles.updateContentTypeHints(profile)
fetchResult = @fetchUrl(url, opt_bypass_cache, type_hints)
headers = {}
if profile.headers
for header in profile.headers
# Being defensive here: filter out headers with empty names
headers[header.name] = header.value if header.name
fetchResult = @fetchUrl(url, headers, opt_bypass_cache, type_hints)
results[key] = fetchResult.then((data) =>
# Errors and unsuccessful response codes shoud have been already
# rejected by fetchUrl and will not end up here.
Expand All @@ -805,11 +810,12 @@ class Options
# Make an HTTP GET request to fetch the content of the url.
# In base class, this method is not implemented and will always reject.
# @param {string} url The name of the profiles,
# @param {?{}} headers Optional headers dictionary with name-value pairs
# @param {?bool} opt_bypass_cache Do not read from the cache if true
# @param {?string} opt_type_hints MIME type hints for downloaded content.
# @returns {Promise<String>} The text content fetched from the url
###
fetchUrl: (url, opt_bypass_cache, opt_type_hints) ->
fetchUrl: (url, headers, opt_bypass_cache, opt_type_hints) ->
Promise.reject new Error('not implemented')

_replaceRefChanges: (fromName, toName, changes) ->
Expand Down
8 changes: 8 additions & 0 deletions omega-web/src/omega/controllers/switch_profile.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -458,3 +458,11 @@ angular.module('omega').controller 'SwitchProfileCtrl', ($scope, $rootScope,
omegaTarget.state('web.switchGuide', 'shown')
return if $scope.profile.rules.length == 0
$script 'js/switch_profile_guide.js'

# == Custom Headers ==
$scope.addHeader = ->
$scope.attached.headers ?= []
$scope.attached.headers.push({name: '', value: ''})

$scope.removeHeader = (index) ->
$scope.attached.headers.splice(index, 1)
26 changes: 25 additions & 1 deletion omega-web/src/partials/profile_switch.jade
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,31 @@ div(ng-controller='SwitchProfileCtrl')
label {{'options_group_ruleListUrl' | tr}}
.width-limit.inline-form-control(input-group-clear type='url' model='attached.sourceUrl'
style='vertical-align: middle')
p.help-block {{'options_ruleListUrlHelp' | tr}}
p.help-block {{'options_ruleListUrlHelp' | tr}}
.form-group
label {{'options_group_ruleListHeaders' | tr}}
.width-limit
.table-responsive(ng-if='attached.headers && attached.headers.length > 0')
table.table.table-bordered.table-condensed
thead
tr
th {{'options_ruleListHeaderName' | tr}}
th {{'options_ruleListHeaderValue' | tr}}
th {{'options_conditionActions' | tr}}
tbody
tr(ng-repeat='header in attached.headers track by $index')
td
input.form-control(type='text' ng-model='header.name' placeholder="{{'options_ruleListHeaderNamePlaceholder' | tr}}" required)
td
input.form-control(type='text' ng-model='header.value' placeholder="{{'options_ruleListHeaderValuePlaceholder' | tr}}")
td
button.btn.btn-danger.btn-sm(type='button' title="{{'options_deleteHeader' | tr}}" ng-click='removeHeader($index)')
span.glyphicon.glyphicon-trash
button.btn.btn-default.btn-sm(type='button' ng-click='addHeader()')
span.glyphicon.glyphicon-plus
= ' '
| {{'options_addHeader' | tr}}
p.help-block {{'options_ruleListHeadersHelp' | tr}}
p
button.btn.btn-default(ng-disabled='!attached.sourceUrl' ng-click='updateProfile(attached.name)'
ladda='updatingProfile[attached.name]' data-spinner-color="#000000"
Expand Down