diff --git a/app/web/api/v1/strategies.rb b/app/web/api/v1/strategies.rb
index 12582b08..992211b7 100644
--- a/app/web/api/v1/strategies.rb
+++ b/app/web/api/v1/strategies.rb
@@ -33,8 +33,8 @@ def index(_request)
def display_name_for(name)
case name.to_s
- when 'ssrf_filter' then 'Standard (recommended)'
- when 'browserless' then 'JavaScript pages'
+ when 'faraday' then 'Standard rendering'
+ when 'browserless' then 'JavaScript pages (recommended)'
else name.to_s.split('_').map(&:capitalize).join(' ')
end
end
diff --git a/app/web/boot/setup.rb b/app/web/boot/setup.rb
index 2c22f364..fd69faa8 100644
--- a/app/web/boot/setup.rb
+++ b/app/web/boot/setup.rb
@@ -26,9 +26,7 @@ def validate_environment!
# @return [void]
def configure_request_service!
- Html2rss::RequestService.register_strategy(:ssrf_filter, SsrfFilterStrategy)
- Html2rss::RequestService.default_strategy_name = :ssrf_filter
- Html2rss::RequestService.unregister_strategy(:faraday)
+ nil
end
end
end
diff --git a/app/web/domain/auto_source.rb b/app/web/domain/auto_source.rb
index 4b1d09c7..becd389e 100644
--- a/app/web/domain/auto_source.rb
+++ b/app/web/domain/auto_source.rb
@@ -21,7 +21,7 @@ def enabled?
# @param token_data [Hash{Symbol=>Object}] authenticated account data.
# @param strategy [String]
# @return [Html2rss::Web::Api::V1::FeedMetadata::Metadata, nil]
- def create_stable_feed(name, url, token_data, strategy = 'ssrf_filter')
+ def create_stable_feed(name, url, token_data, strategy = 'faraday')
return nil unless token_data && FeedAccess.url_allowed_for_username?(token_data[:username], url)
feed_token = Auth.generate_feed_token(token_data[:username], url, strategy: strategy)
diff --git a/app/web/feeds/source_resolver.rb b/app/web/feeds/source_resolver.rb
index 0bb33a6e..75e1abf4 100644
--- a/app/web/feeds/source_resolver.rb
+++ b/app/web/feeds/source_resolver.rb
@@ -69,7 +69,7 @@ def static_cache_identity(feed_name, params)
def static_generator_input(config, params)
generator_input = config.dup
generator_input[:params] = merged_static_params(config, params)
- generator_input[:strategy] ||= Html2rss::RequestService.default_strategy_name
+ generator_input[:strategy] ||= :faraday
generator_input
end
diff --git a/app/web/security/ssrf_filter_strategy.rb b/app/web/security/ssrf_filter_strategy.rb
deleted file mode 100644
index 2ad3f76f..00000000
--- a/app/web/security/ssrf_filter_strategy.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-# frozen_string_literal: true
-
-require 'ssrf_filter'
-require 'html2rss'
-module Html2rss
- module Web
- ##
- # Strategy to fetch a URL using the SSRF filter.
- class SsrfFilterStrategy < Html2rss::RequestService::Strategy
- # Executes a URL fetch through `ssrf_filter` and adapts response shape.
- #
- # @return [Html2rss::RequestService::Response]
- def execute
- headers = LocalConfig.global.fetch(:headers, {}).merge(
- ctx.headers.transform_keys(&:to_sym)
- )
- response = SsrfFilter.get(ctx.url, headers:)
-
- Html2rss::RequestService::Response.new(body: response.body,
- url: ctx.url,
- headers: response.to_hash.transform_values(&:first))
- end
- end
- end
-end
diff --git a/spec/html2rss/web/api/v1/feed_metadata_spec.rb b/spec/html2rss/web/api/v1/feed_metadata_spec.rb
index dc8780b4..fb9e55fa 100644
--- a/spec/html2rss/web/api/v1/feed_metadata_spec.rb
+++ b/spec/html2rss/web/api/v1/feed_metadata_spec.rb
@@ -11,7 +11,7 @@
name: 'Example Feed',
url: 'https://example.com/articles',
username: 'alice',
- strategy: 'ssrf_filter',
+ strategy: 'faraday',
feed_token: 'generated-token',
identity_token: 'account-token'
}
@@ -23,7 +23,7 @@
name: 'Example Feed',
url: 'https://example.com/articles',
username: 'alice',
- strategy: 'ssrf_filter',
+ strategy: 'faraday',
feed_token: 'generated-token',
public_url: '/api/v1/feeds/generated-token',
json_public_url: '/api/v1/feeds/generated-token.json'
diff --git a/spec/html2rss/web/api/v1_spec.rb b/spec/html2rss/web/api/v1_spec.rb
index f7137b9f..17d52278 100644
--- a/spec/html2rss/web/api/v1_spec.rb
+++ b/spec/html2rss/web/api/v1_spec.rb
@@ -49,14 +49,14 @@ def ghost_feed_token
.create_with_validation(
username: 'ghost',
url: feed_url,
- strategy: 'ssrf_filter',
+ strategy: 'faraday',
secret_key: ENV.fetch('HTML2RSS_SECRET_KEY')
)
.encode
end
def valid_feed_token
- Html2rss::Web::Auth.generate_feed_token('admin', feed_url, strategy: 'ssrf_filter')
+ Html2rss::Web::Auth.generate_feed_token('admin', feed_url, strategy: 'faraday')
end
def json_feed_response_for(token)
@@ -285,7 +285,7 @@ def json_feed_headers_tuple
end
it 'renders feed for a valid token', :aggregate_failures do
- token = Html2rss::Web::Auth.generate_feed_token('admin', feed_url, strategy: 'ssrf_filter')
+ token = Html2rss::Web::Auth.generate_feed_token('admin', feed_url, strategy: 'faraday')
allow(Html2rss::Web::Feeds::Service).to receive(:call).and_return(feed_result)
allow(Html2rss::Web::Feeds::RssRenderer).to receive(:call).and_return('')
@@ -305,7 +305,7 @@ def json_feed_headers_tuple
end
it 'prefers xml when Accept quality outranks json', :aggregate_failures do
- token = Html2rss::Web::Auth.generate_feed_token('admin', feed_url, strategy: 'ssrf_filter')
+ token = Html2rss::Web::Auth.generate_feed_token('admin', feed_url, strategy: 'faraday')
allow(Html2rss::Web::Feeds::Service).to receive(:call).and_return(feed_result)
allow(Html2rss::Web::Feeds::RssRenderer).to receive(:call).and_return('')
@@ -317,7 +317,7 @@ def json_feed_headers_tuple
end
it 'ignores query param strategy overrides', :aggregate_failures, openapi: false do
- token = Html2rss::Web::Auth.generate_feed_token('admin', feed_url, strategy: 'ssrf_filter')
+ token = Html2rss::Web::Auth.generate_feed_token('admin', feed_url, strategy: 'faraday')
allow(Html2rss::Web::Feeds::Service).to receive(:call).and_return(feed_result)
allow(Html2rss::Web::Feeds::RssRenderer).to receive(:call).and_return('')
@@ -346,7 +346,7 @@ def json_feed_headers_tuple
it 'returns forbidden when auto source is disabled', :aggregate_failures do
unique_url = "#{feed_url}/disabled"
- token = Html2rss::Web::Auth.generate_feed_token('admin', unique_url, strategy: 'ssrf_filter')
+ token = Html2rss::Web::Auth.generate_feed_token('admin', unique_url, strategy: 'faraday')
ClimateControl.modify(AUTO_SOURCE_ENABLED: 'false') do
get "/api/v1/feeds/#{token}", {}, { 'HTTP_ACCEPT' => 'application/xml' }
@@ -359,7 +359,7 @@ def json_feed_headers_tuple
it 'returns JSON Feed-shaped forbidden errors when requested through Accept', :aggregate_failures do
unique_url = "#{feed_url}/disabled-json"
- token = Html2rss::Web::Auth.generate_feed_token('admin', unique_url, strategy: 'ssrf_filter')
+ token = Html2rss::Web::Auth.generate_feed_token('admin', unique_url, strategy: 'faraday')
ClimateControl.modify(AUTO_SOURCE_ENABLED: 'false') do
get "/api/v1/feeds/#{token}", {}, { 'HTTP_ACCEPT' => 'application/feed+json' }
@@ -372,7 +372,7 @@ def json_feed_headers_tuple
it 'returns non-cacheable xml feed errors when service generation fails', :aggregate_failures do
unique_url = "#{feed_url}/service-error-xml"
- token = Html2rss::Web::Auth.generate_feed_token('admin', unique_url, strategy: 'ssrf_filter')
+ token = Html2rss::Web::Auth.generate_feed_token('admin', unique_url, strategy: 'faraday')
allow(Html2rss::Web::Feeds::Service).to receive(:call).and_return(service_error_result)
@@ -386,7 +386,7 @@ def json_feed_headers_tuple
it 'returns non-cacheable json feed errors when service generation fails', :aggregate_failures do
unique_url = "#{feed_url}/service-error-json"
- token = Html2rss::Web::Auth.generate_feed_token('admin', unique_url, strategy: 'ssrf_filter')
+ token = Html2rss::Web::Auth.generate_feed_token('admin', unique_url, strategy: 'faraday')
status, content_type, cache_control, title = json_feed_service_error_tuple(token)
@@ -404,7 +404,7 @@ def json_feed_headers_tuple
let(:request_params) do
{
url: feed_url,
- strategy: 'ssrf_filter'
+ strategy: 'faraday'
}
end
diff --git a/spec/html2rss/web/app_integration_spec.rb b/spec/html2rss/web/app_integration_spec.rb
index e84b8b20..8cb2a230 100644
--- a/spec/html2rss/web/app_integration_spec.rb
+++ b/spec/html2rss/web/app_integration_spec.rb
@@ -59,7 +59,7 @@
Html2rss::Web::FeedToken,
url: feed_url,
username: account[:username],
- strategy: 'ssrf_filter'
+ strategy: 'faraday'
)
allow(Html2rss::Web::FeedToken).to receive_messages(
decode: token_payload,
@@ -187,7 +187,7 @@ def stub_escaped_feed_token(raw_token:, encoded_token:)
Html2rss::Web::FeedToken,
url: feed_url,
username: account[:username],
- strategy: 'ssrf_filter'
+ strategy: 'faraday'
)
allow(Html2rss::Web::FeedToken).to receive(:decode).with(raw_token).and_return(escaped_token_payload)
@@ -203,7 +203,7 @@ def stub_escaped_feed_token(raw_token:, encoded_token:)
let(:request_payload) do
{
url: feed_url,
- strategy: 'ssrf_filter'
+ strategy: 'faraday'
}
end
@@ -212,7 +212,7 @@ def stub_escaped_feed_token(raw_token:, encoded_token:)
id: 'feed-123',
name: 'Example Feed',
url: feed_url,
- strategy: 'ssrf_filter',
+ strategy: 'faraday',
feed_token: feed_token,
public_url: "/api/v1/feeds/#{feed_token}",
json_public_url: "/api/v1/feeds/#{feed_token}.json",
diff --git a/spec/html2rss/web/boot/setup_spec.rb b/spec/html2rss/web/boot/setup_spec.rb
index 32fbde0f..8682dbce 100644
--- a/spec/html2rss/web/boot/setup_spec.rb
+++ b/spec/html2rss/web/boot/setup_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-require_relative '../../../../app/web/boot/setup'
+require_relative '../../../../app'
RSpec.describe Html2rss::Web::Boot::Setup do
describe '.call!' do
@@ -10,21 +10,14 @@
allow(Html2rss::Web::EnvironmentValidator).to receive(:validate_environment!)
allow(Html2rss::Web::EnvironmentValidator).to receive(:validate_production_security!)
allow(Html2rss::Web::Flags).to receive(:validate!)
- allow(Html2rss::RequestService).to receive(:register_strategy)
- allow(Html2rss::RequestService).to receive(:default_strategy_name=)
- allow(Html2rss::RequestService).to receive(:unregister_strategy)
end
- it 'validates environment state and configures the request service', :aggregate_failures do
+ it 'validates environment state', :aggregate_failures do
described_class.call!
expect(Html2rss::Web::EnvironmentValidator).to have_received(:validate_environment!).once
expect(Html2rss::Web::EnvironmentValidator).to have_received(:validate_production_security!).once
expect(Html2rss::Web::Flags).to have_received(:validate!).once
- expect(Html2rss::RequestService).to have_received(:register_strategy)
- .with(:ssrf_filter, Html2rss::Web::SsrfFilterStrategy).once
- expect(Html2rss::RequestService).to have_received(:default_strategy_name=).with(:ssrf_filter).once
- expect(Html2rss::RequestService).to have_received(:unregister_strategy).with(:faraday).once
end
end
end
diff --git a/spec/html2rss/web/feeds/cache_spec.rb b/spec/html2rss/web/feeds/cache_spec.rb
index eb2bacf5..0bcb2b36 100644
--- a/spec/html2rss/web/feeds/cache_spec.rb
+++ b/spec/html2rss/web/feeds/cache_spec.rb
@@ -13,7 +13,7 @@
feed: Object.new,
site_title: 'Example',
url: 'https://example.com',
- strategy: 'ssrf_filter'
+ strategy: 'faraday'
),
message: nil,
ttl_seconds: 60,
diff --git a/spec/html2rss/web/feeds/json_renderer_spec.rb b/spec/html2rss/web/feeds/json_renderer_spec.rb
index a3a59e3a..d14fef9c 100644
--- a/spec/html2rss/web/feeds/json_renderer_spec.rb
+++ b/spec/html2rss/web/feeds/json_renderer_spec.rb
@@ -11,7 +11,7 @@
feed: Object.new,
site_title: 'https://example.com/articles',
url: 'https://example.com/articles',
- strategy: 'ssrf_filter'
+ strategy: 'faraday'
)
end
let(:empty_result) do
@@ -37,7 +37,7 @@
def expected_builder_args
{
url: 'https://example.com/articles',
- strategy: 'ssrf_filter',
+ strategy: 'faraday',
site_title: 'https://example.com/articles'
}
end
diff --git a/spec/html2rss/web/feeds/responder_spec.rb b/spec/html2rss/web/feeds/responder_spec.rb
index 2dd1d2e9..d2e51307 100644
--- a/spec/html2rss/web/feeds/responder_spec.rb
+++ b/spec/html2rss/web/feeds/responder_spec.rb
@@ -21,7 +21,7 @@ def resolved_source
Html2rss::Web::Feeds::Contracts::ResolvedSource.new(
source_kind: :token,
cache_identity: 'token:abc',
- generator_input: { strategy: :ssrf_filter, channel: { url: 'https://example.com' } },
+ generator_input: { strategy: :faraday, channel: { url: 'https://example.com' } },
ttl_seconds: 600
)
end
@@ -74,7 +74,7 @@ def resolved_source
expect(Html2rss::Web::Observability).to have_received(:emit).with(
event_name: 'feed.render',
outcome: 'success',
- details: include(strategy: :ssrf_filter, url: 'https://example.com'),
+ details: include(strategy: :faraday, url: 'https://example.com'),
level: :info
)
end
diff --git a/spec/html2rss/web/feeds/rss_renderer_spec.rb b/spec/html2rss/web/feeds/rss_renderer_spec.rb
index a4e7f2f9..ca07c26a 100644
--- a/spec/html2rss/web/feeds/rss_renderer_spec.rb
+++ b/spec/html2rss/web/feeds/rss_renderer_spec.rb
@@ -11,7 +11,7 @@
feed: Object.new,
site_title: 'https://example.com/articles',
url: 'https://example.com/articles',
- strategy: 'ssrf_filter'
+ strategy: 'faraday'
)
end
let(:empty_result) do
@@ -37,7 +37,7 @@
def expected_builder_args
{
url: 'https://example.com/articles',
- strategy: 'ssrf_filter',
+ strategy: 'faraday',
site_title: 'https://example.com/articles'
}
end
diff --git a/spec/html2rss/web/feeds/service_spec.rb b/spec/html2rss/web/feeds/service_spec.rb
index 834f3cc6..4f085ca4 100644
--- a/spec/html2rss/web/feeds/service_spec.rb
+++ b/spec/html2rss/web/feeds/service_spec.rb
@@ -11,7 +11,7 @@
source_kind: :static,
cache_identity: 'example-feed:abc123',
generator_input: {
- strategy: :ssrf_filter,
+ strategy: :faraday,
channel: { url: 'https://example.com/articles' },
auto_source: {}
},
@@ -109,7 +109,7 @@ def expected_payload
feed: feed,
site_title: 'Example Feed',
url: 'https://example.com/articles',
- strategy: 'ssrf_filter'
+ strategy: 'faraday'
)
end
end
diff --git a/spec/html2rss/web/feeds/source_resolver_spec.rb b/spec/html2rss/web/feeds/source_resolver_spec.rb
index 42e431a2..838ad5b0 100644
--- a/spec/html2rss/web/feeds/source_resolver_spec.rb
+++ b/spec/html2rss/web/feeds/source_resolver_spec.rb
@@ -29,7 +29,6 @@ def resolved_tuple(resolved)
before do
allow(Html2rss::Web::LocalConfig).to receive(:find).with('legacy').and_return(config)
- allow(Html2rss::RequestService).to receive(:default_strategy_name).and_return(:ssrf_filter)
end
it 'normalizes the static source into shared generator input', :aggregate_failures do
@@ -40,7 +39,7 @@ def resolved_tuple(resolved)
:static,
start_with('static:legacy:'),
900,
- include(params: { 'existing' => '1', 'page' => '3' }, strategy: :ssrf_filter)
+ include(params: { 'existing' => '1', 'page' => '3' }, strategy: :faraday)
]
)
end
@@ -53,6 +52,14 @@ def resolved_tuple(resolved)
params: { 'existing' => '1' }
)
end
+
+ it 'preserves an explicit static strategy when configured' do
+ config[:strategy] = :browserless
+
+ resolved = described_class.call(feed_request)
+
+ expect(resolved.generator_input[:strategy]).to eq(:browserless)
+ end
end
context 'with a token request' do
@@ -70,7 +77,7 @@ def resolved_tuple(resolved)
Html2rss::Web::FeedToken,
username: 'admin',
url: 'https://example.com/private',
- strategy: 'ssrf_filter'
+ strategy: 'faraday'
)
end
@@ -82,7 +89,7 @@ def resolved_tuple(resolved)
allow(Html2rss::Web::UrlValidator).to receive(:url_allowed?)
.with({ username: 'admin' }, 'https://example.com/private').and_return(true)
allow(Html2rss::Web::AutoSource).to receive(:enabled?).and_return(true)
- allow(Html2rss::RequestService).to receive(:strategy_names).and_return([:ssrf_filter])
+ allow(Html2rss::RequestService).to receive(:strategy_names).and_return([:faraday])
allow(Html2rss::Web::LocalConfig).to receive(:global)
.and_return({ headers: { 'User-Agent' => 'html2rss-web' } })
end
@@ -92,7 +99,7 @@ def resolved_tuple(resolved)
expect(resolved_tuple(resolved)).to match(
[:token, start_with('token:'), 300,
- include(strategy: :ssrf_filter, channel: { url: 'https://example.com/private' }, auto_source: {})]
+ include(strategy: :faraday, channel: { url: 'https://example.com/private' }, auto_source: {})]
)
end
end
diff --git a/spec/smoke/docker_spec.rb b/spec/smoke/docker_spec.rb
index a4ba31cd..115d2b76 100644
--- a/spec/smoke/docker_spec.rb
+++ b/spec/smoke/docker_spec.rb
@@ -71,7 +71,7 @@ def expect_json_feed_response(path)
it 'creates a feed when provided with valid credentials', :aggregate_failures do
payload = {
url: feed_url,
- strategy: 'ssrf_filter'
+ strategy: 'faraday'
}
response, body = post_json('/api/v1/feeds', body: payload)
@@ -84,7 +84,7 @@ def expect_json_feed_response(path)
payload = {
url: feed_url,
- strategy: 'ssrf_filter'
+ strategy: 'faraday'
}
response, body = post_json('/api/v1/feeds',
@@ -101,7 +101,7 @@ def expect_json_feed_response(path)
payload = {
url: feed_url,
- strategy: 'ssrf_filter'
+ strategy: 'faraday'
}
response, body = post_json('/api/v1/feeds',