Allow Apache-friendly fine-tuning
This commit is contained in:
parent
ade2979857
commit
5c1673b29f
6 changed files with 162 additions and 26 deletions
|
|
@ -4,10 +4,57 @@ This FreshRSS extension allows you to get rid of insecure content warnings or di
|
|||
|
||||
To use it, upload this entire directory to the FreshRSS `./extensions` directory on your server and enable it on the extension panel in FreshRSS.
|
||||
|
||||
## Configuration settings
|
||||
|
||||
* `proxy_url` (default: `https://images.example.com/?url=`): the URL that is prependended to the original image URL
|
||||
|
||||
* `scheme_http` (default: `1`): whether to proxy HTTP resources
|
||||
|
||||
* `scheme_https` (default: `0`): whether to proxy HTTPS resources
|
||||
|
||||
* `scheme_default` (default: `http`): which scheme to use for resources that do not include one (if set to `-`, those will not be proxied)
|
||||
|
||||
* `scheme_include` (default: `0`): whether to include the scheme - `http*://` - in the proxied URL
|
||||
|
||||
* `url_encode` (default: `1`): whether to URL-encode (RFC 3986) the proxied URL
|
||||
|
||||
## Proxy Settings
|
||||
|
||||
By default this extension will use the [images.weserv.nl](https://images.weserv.nl) image caching and resizing proxy, but instead you can supply your own proxy URL in the settings. An example URL would look like ``https://images.example.com/?url=``.
|
||||
|
||||
By ticking the `scheme_https` checkbox, you can also force the use of the proxy, even for images coming through an encrypted channel. This makes the server that hosts your FreshRSS instance the only point of entry for images, preventing your client from connecting directly to the RSS sources to recover them (which could be a privacy concern in extreme cases).
|
||||
|
||||
The source code for the images.weserv.nl proxy can be found at [github.com/andrieslouw/imagesweserv](https://github.com/andrieslouw/imagesweserv), but of course other methods are available. For example, in Apache you could [use `mod_rewrite` to set up a simple proxy](https://httpd.apache.org/docs/2.2/rewrite/proxy.html) and similar methods are available in nginx and lighttpd. Alternatively you could use a simple PHP script, [along these lines](https://github.com/Alexxz/Simple-php-proxy-script). Keep in mind that too simple a proxy could introduce security risks, which is why the default proxy processes the images.
|
||||
|
||||
By ticking the dedicated checkbox, you can also force the use of the proxy, even for images coming through an encrypted channel. This makes the server that hosts your FreshRSS instance the only point of entry for images, preventing your client from connecting directly to the RSS sources to recover them (which could be a privacy concern in extreme cases).
|
||||
### Apache configuration
|
||||
|
||||
In order to use Apache `mod_rewrite`, you will need to set the following settings:
|
||||
|
||||
* `proxy_url` = ``https://www.example.org/proxy/``
|
||||
|
||||
* `scheme_include` = **1**
|
||||
|
||||
* `url_encode` = **0**
|
||||
|
||||
Along the following Apache configuration for the `www.example.org` virtual host:
|
||||
|
||||
```
|
||||
# WARNING: Multiple '/' are trimmed to a single one!
|
||||
RewriteCond %{REQUEST_URI} ^/proxy/https:/+(.*)$
|
||||
RewriteRule ^ https://%1 [QSA,P,L]
|
||||
RewriteCond %{REQUEST_URI} ^/proxy/http:/+(.*)$
|
||||
RewriteRule ^ http://%1 [QSA,P,L]
|
||||
<Location "/proxy/">
|
||||
# CRITICAL: Do NOT leave your proxy opened to everyone!!!
|
||||
# Local network
|
||||
Require ip 192.168.0.0/16 172.16.0.0/12 10.0.0.0/8
|
||||
# Users
|
||||
AuthType Basic
|
||||
AuthName "Proxy - Authorized Users ONLY"
|
||||
AuthBasicProvider file
|
||||
AuthUserFile /etc/apache2/htpasswd/users
|
||||
Require valid-user
|
||||
# Local network OR authenticated users
|
||||
Satisfy any
|
||||
</Location>
|
||||
```
|
||||
|
|
|
|||
|
|
@ -5,9 +5,40 @@
|
|||
<div class="group-controls">
|
||||
<input type="url" name="image_proxy_url" id="image_proxy_url" value="<?php echo FreshRSS_Context::$user_conf->image_proxy_url; ?>">
|
||||
</div>
|
||||
<label class="group-name" for="image_proxy_force"><?php echo _t('ext.imageproxy.force'); ?></label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="group-name" for="image_proxy_scheme_http"><?php echo _t('ext.imageproxy.scheme_http'); ?></label>
|
||||
<div class="group-controls">
|
||||
<input type="checkbox" name="image_proxy_force" id="image_proxy_force" value="1" <?php echo (FreshRSS_Context::$user_conf->image_proxy_force ? 'checked' : ''); ?>>
|
||||
<input type="checkbox" name="image_proxy_scheme_http" id="image_proxy_scheme_http" value="1" <?php echo (FreshRSS_Context::$user_conf->image_proxy_scheme_http ? 'checked' : ''); ?>>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="group-name" for="image_proxy_scheme_https"><?php echo _t('ext.imageproxy.scheme_https'); ?></label>
|
||||
<div class="group-controls">
|
||||
<input type="checkbox" name="image_proxy_scheme_https" id="image_proxy_scheme_https" value="1" <?php echo (FreshRSS_Context::$user_conf->image_proxy_scheme_https ? 'checked' : ''); ?>>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="group-name" for="image_proxy_scheme_default"><?php echo _t('ext.imageproxy.scheme_default'); ?></label>
|
||||
<div class="group-controls">
|
||||
<select name="image_proxy_scheme_default" id="image_proxy_scheme_default">
|
||||
<option value="<?php echo htmlentities(FreshRSS_Context::$user_conf->image_proxy_scheme_default); ?>" selected="selected"><?php echo htmlentities(FreshRSS_Context::$user_conf->image_proxy_scheme_default); ?></option>
|
||||
<option value="-">-</option>
|
||||
<option value="http">http</option>
|
||||
<option value="https">https</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="group-name" for="image_proxy_scheme_include"><?php echo _t('ext.imageproxy.scheme_include'); ?></label>
|
||||
<div class="group-controls">
|
||||
<input type="checkbox" name="image_proxy_scheme_include" id="image_proxy_scheme_include" value="1" <?php echo (FreshRSS_Context::$user_conf->image_proxy_scheme_include ? 'checked' : ''); ?>>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="group-name" for="image_proxy_url_encode"><?php echo _t('ext.imageproxy.url_encode'); ?></label>
|
||||
<div class="group-controls">
|
||||
<input type="checkbox" name="image_proxy_url_encode" id="image_proxy_url_encode" value="1" <?php echo (FreshRSS_Context::$user_conf->image_proxy_url_encode ? 'checked' : ''); ?>>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,45 +1,95 @@
|
|||
<?php
|
||||
|
||||
class ImageProxyExtension extends Minz_Extension {
|
||||
// Defaults
|
||||
private const PROXY_URL = 'https://images.weserv.nl/?url=';
|
||||
private const SCHEME_HTTP = '1';
|
||||
private const SCHEME_HTTPS = '';
|
||||
private const SCHEME_DEFAULT = 'http';
|
||||
private const SCHEME_INCLUDE = '';
|
||||
private const URL_ENCODE = '1';
|
||||
|
||||
public function init() {
|
||||
$this->registerHook('entry_before_display',
|
||||
array('ImageProxyExtension', 'setImageProxyHook'));
|
||||
|
||||
if (FreshRSS_Context::$user_conf->image_proxy_url != '') {
|
||||
self::$proxy_url = FreshRSS_Context::$user_conf->image_proxy_url;
|
||||
// Defaults
|
||||
$save = false;
|
||||
if (is_null(FreshRSS_Context::$user_conf->image_proxy_url)) {
|
||||
FreshRSS_Context::$user_conf->image_proxy_url = self::PROXY_URL;
|
||||
$save = true;
|
||||
}
|
||||
if (is_null(FreshRSS_Context::$user_conf->image_proxy_scheme_http)) {
|
||||
FreshRSS_Context::$user_conf->image_proxy_scheme_http = self::SCHEME_HTTP;
|
||||
$save = true;
|
||||
}
|
||||
if (is_null(FreshRSS_Context::$user_conf->image_proxy_scheme_https)) {
|
||||
FreshRSS_Context::$user_conf->image_proxy_scheme_https = self::SCHEME_HTTPS;
|
||||
// Legacy
|
||||
if (!is_null(FreshRSS_Context::$user_conf->image_proxy_force)) {
|
||||
FreshRSS_Context::$user_conf->image_proxy_scheme_https = FreshRSS_Context::$user_conf->image_proxy_force;
|
||||
FreshRSS_Context::$user_conf->image_proxy_force = null; // Minz -> unset
|
||||
}
|
||||
$save = true;
|
||||
}
|
||||
if (is_null(FreshRSS_Context::$user_conf->image_proxy_scheme_default)) {
|
||||
FreshRSS_Context::$user_conf->image_proxy_scheme_default = self::SCHEME_DEFAULT;
|
||||
$save = true;
|
||||
}
|
||||
if (is_null(FreshRSS_Context::$user_conf->image_proxy_scheme_include)) {
|
||||
FreshRSS_Context::$user_conf->image_proxy_scheme_include = self::SCHEME_INCLUDE;
|
||||
$save = true;
|
||||
}
|
||||
if (is_null(FreshRSS_Context::$user_conf->image_proxy_url_encode)) {
|
||||
FreshRSS_Context::$user_conf->image_proxy_url_encode = self::URL_ENCODE;
|
||||
$save = true;
|
||||
}
|
||||
if ($save) {
|
||||
FreshRSS_Context::$user_conf->save();
|
||||
}
|
||||
}
|
||||
|
||||
public static $proxy_url = 'https://images.weserv.nl/?url=';
|
||||
|
||||
public function handleConfigureAction() {
|
||||
$this->registerTranslates();
|
||||
|
||||
if (Minz_Request::isPost()) {
|
||||
FreshRSS_Context::$user_conf->image_proxy_url = Minz_Request::param('image_proxy_url', '');
|
||||
FreshRSS_Context::$user_conf->image_proxy_force = Minz_Request::param('image_proxy_force', '');
|
||||
FreshRSS_Context::$user_conf->image_proxy_url = Minz_Request::param('image_proxy_url', self::PROXY_URL);
|
||||
FreshRSS_Context::$user_conf->image_proxy_scheme_http = Minz_Request::param('image_proxy_scheme_http', '');
|
||||
FreshRSS_Context::$user_conf->image_proxy_scheme_https = Minz_Request::param('image_proxy_scheme_https', '');
|
||||
FreshRSS_Context::$user_conf->image_proxy_scheme_default = Minz_Request::param('image_proxy_scheme_default', self::SCHEME_DEFAULT);
|
||||
FreshRSS_Context::$user_conf->image_proxy_scheme_include = Minz_Request::param('image_proxy_scheme_include', '');
|
||||
FreshRSS_Context::$user_conf->image_proxy_url_encode = Minz_Request::param('image_proxy_url_encode', '');
|
||||
FreshRSS_Context::$user_conf->save();
|
||||
}
|
||||
}
|
||||
|
||||
public static function getProxyImageUri($url) {
|
||||
$parsed_url = parse_url($url);
|
||||
if (isset($parsed_url['scheme']) && $parsed_url['scheme'] === 'http') {
|
||||
$url = self::$proxy_url . rawurlencode(substr($url, strlen('http://')));
|
||||
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] : null;
|
||||
if ($scheme === 'http') {
|
||||
if (!FreshRSS_Context::$user_conf->image_proxy_scheme_http) return $url;
|
||||
if (!FreshRSS_Context::$user_conf->image_proxy_scheme_include) {
|
||||
$url = substr($url, 7); // http://
|
||||
}
|
||||
}
|
||||
// force proxy even with https, if set by the user
|
||||
else if (isset($parsed_url['scheme']) &&
|
||||
$parsed_url['scheme'] === 'https' &&
|
||||
FreshRSS_Context::$user_conf->image_proxy_force) {
|
||||
$url = self::$proxy_url . rawurlencode(substr($url, strlen('https://')));
|
||||
else if ($scheme === 'https') {
|
||||
if (!FreshRSS_Context::$user_conf->image_proxy_scheme_https) return $url;
|
||||
if (!FreshRSS_Context::$user_conf->image_proxy_scheme_include) {
|
||||
$url = substr($url, 8); // https://
|
||||
}
|
||||
}
|
||||
// oddly enough there are protocol-less IMG SRC attributes that don't actually work with HTTPS
|
||||
// so I guess we should just run 'em all through the proxy
|
||||
else if (empty($parsed_url['scheme'])) {
|
||||
$url = self::$proxy_url . rawurlencode($url);
|
||||
else if (empty($scheme)) {
|
||||
if (substr(FreshRSS_Context::$user_conf->image_proxy_scheme_default,0, 4) !== 'http') return $url;
|
||||
if (FreshRSS_Context::$user_conf->image_proxy_scheme_include) {
|
||||
$url = FreshRSS_Context::$user_conf->image_proxy_scheme_default . '://' . $url;
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
else { // unknown/unsupported (non-http) scheme
|
||||
return $url;
|
||||
}
|
||||
if (FreshRSS_Context::$user_conf->image_proxy_url_encode) {
|
||||
$url = rawurlencode($url);
|
||||
}
|
||||
return FreshRSS_Context::$user_conf->image_proxy_url . $url;
|
||||
}
|
||||
|
||||
public static function getSrcSetUris($matches) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@
|
|||
return array(
|
||||
'imageproxy' => array(
|
||||
'proxy_url' => 'Proxy URL',
|
||||
'force' => 'Force proxying, even for https',
|
||||
'scheme_http' => 'Proxy HTTP',
|
||||
'scheme_https' => 'Proxy HTTPS',
|
||||
'scheme_default' => 'Proxy unspecified',
|
||||
'scheme_include' => 'Include http*:// in URL',
|
||||
'url_encode' => 'Encode the URL',
|
||||
'true' => 'On',
|
||||
'false' => 'Off',
|
||||
),
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@
|
|||
return array(
|
||||
'imageproxy' => array(
|
||||
'proxy_url' => 'URL du proxy',
|
||||
'force' => 'Toujours utiliser le proxy, même en https',
|
||||
'scheme_http' => 'Proxy HTTP',
|
||||
'scheme_https' => 'Proxy HTTPS',
|
||||
'scheme_default' => 'Proxy indéterminées',
|
||||
'scheme_include' => 'Inclure http*:// dans l\'URL',
|
||||
'url_encode' => 'Encoder l\'URL',
|
||||
'true' => 'Oui',
|
||||
'false' => 'Non',
|
||||
),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"name": "Image Proxy",
|
||||
"author": "Frans de Jonge",
|
||||
"description": "No insecure content warnings or disappearing images.",
|
||||
"version": 0.4,
|
||||
"version": 0.5,
|
||||
"entrypoint": "ImageProxy",
|
||||
"type": "user"
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue