Redirect POST search -> enc GET request

This should fix the annoyance with browsers like Firefox not caching
POST request responses. By redirecting a POST search to be a GET request
instead (with an encrypted query string), the page can be cached and
successfully navigated back to after visiting a result.
main
Ben Busby 2023-10-16 16:28:36 -06:00
parent 7bda165ca3
commit 2950aa869b
No known key found for this signature in database
GPG Key ID: B9B7231E01D924A1
2 changed files with 21 additions and 1 deletions

View File

@ -21,7 +21,7 @@ from app.utils.misc import empty_gif, placeholder_img, get_proxy_host_url, \
fetch_favicon fetch_favicon
from app.filter import Filter from app.filter import Filter
from app.utils.misc import read_config_bool, get_client_ip, get_request_url, \ from app.utils.misc import read_config_bool, get_client_ip, get_request_url, \
check_for_update check_for_update, encrypt_string
from app.utils.widgets import * from app.utils.widgets import *
from app.utils.results import bold_search_terms,\ from app.utils.results import bold_search_terms,\
add_currency_card, check_currency, get_tabs_content add_currency_card, check_currency, get_tabs_content
@ -34,6 +34,7 @@ from requests import exceptions
from requests.models import PreparedRequest from requests.models import PreparedRequest
from cryptography.fernet import Fernet, InvalidToken from cryptography.fernet import Fernet, InvalidToken
from cryptography.exceptions import InvalidSignature from cryptography.exceptions import InvalidSignature
from werkzeug.datastructures import MultiDict
# Load DDG bang json files only on init # Load DDG bang json files only on init
bang_json = json.load(open(app.config['BANG_FILE'])) or {} bang_json = json.load(open(app.config['BANG_FILE'])) or {}
@ -184,6 +185,7 @@ def before_request_func():
def after_request_func(resp): def after_request_func(resp):
resp.headers['X-Content-Type-Options'] = 'nosniff' resp.headers['X-Content-Type-Options'] = 'nosniff'
resp.headers['X-Frame-Options'] = 'DENY' resp.headers['X-Frame-Options'] = 'DENY'
resp.headers['Cache-Control'] = 'max-age=86400'
if os.getenv('WHOOGLE_CSP', False): if os.getenv('WHOOGLE_CSP', False):
resp.headers['Content-Security-Policy'] = app.config['CSP'] resp.headers['Content-Security-Policy'] = app.config['CSP']
@ -301,6 +303,13 @@ def autocomplete():
@session_required @session_required
@auth_required @auth_required
def search(): def search():
if request.method == 'POST':
# Redirect as a GET request with an encrypted query
post_data = MultiDict(request.form)
post_data['q'] = encrypt_string(g.session_key, post_data['q'])
get_req_str = urlparse.urlencode(post_data)
return redirect(url_for('.search') + '?' + get_req_str)
search_util = Search(request, g.user_config, g.session_key) search_util = Search(request, g.user_config, g.session_key)
query = search_util.new_search_query() query = search_util.new_search_query()

View File

@ -1,5 +1,6 @@
import base64 import base64
from bs4 import BeautifulSoup as bsoup from bs4 import BeautifulSoup as bsoup
from cryptography.fernet import Fernet
from flask import Request from flask import Request
import hashlib import hashlib
import io import io
@ -126,3 +127,13 @@ def list_to_dict(lst: list) -> dict:
return {} return {}
return {lst[i].replace(' ', ''): lst[i+1].replace(' ', '') return {lst[i].replace(' ', ''): lst[i+1].replace(' ', '')
for i in range(0, len(lst), 2)} for i in range(0, len(lst), 2)}
def encrypt_string(key: bytes, string: str) -> str:
cipher_suite = Fernet(key)
return cipher_suite.encrypt(string.encode()).decode()
def decrypt_string(key: bytes, string: str) -> str:
cipher_suite = Fernet(g.session_key)
return cipher_suite.decrypt(string.encode()).decode()