mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Content server OPDS: Handle form encoded search queries. Fixes #1841464 [calibre server search by URL with multiple words not working](https://bugs.launchpad.net/calibre/+bug/1841464)
This commit is contained in:
parent
8d96d125e8
commit
f8f464efc0
@ -66,7 +66,7 @@ def parse_request_uri(uri):
|
||||
return None, uri, None
|
||||
|
||||
|
||||
def parse_uri(uri, parse_query=True):
|
||||
def parse_uri(uri, parse_query=True, unquote_func=unquote):
|
||||
scheme, authority, path = parse_request_uri(uri)
|
||||
if path is None:
|
||||
raise HTTPSimpleResponse(http_client.BAD_REQUEST, "No path component")
|
||||
@ -89,7 +89,7 @@ def parse_uri(uri, parse_query=True):
|
||||
query = None
|
||||
|
||||
try:
|
||||
path = '%2F'.join(unquote(x).decode('utf-8') for x in quoted_slash.split(path))
|
||||
path = '%2F'.join(unquote_func(x).decode('utf-8') for x in quoted_slash.split(path))
|
||||
except ValueError as e:
|
||||
raise HTTPSimpleResponse(http_client.BAD_REQUEST, as_unicode(e))
|
||||
path = tuple(filter(None, (x.replace('%2F', '/') for x in path.split('/'))))
|
||||
@ -212,6 +212,7 @@ class HTTPRequest(Connection):
|
||||
self.max_header_line_size = int(1024 * self.opts.max_header_line_size)
|
||||
self.max_request_body_size = int(1024 * 1024 * self.opts.max_request_body_size)
|
||||
self.forwarded_for = None
|
||||
self.request_original_uri = None
|
||||
|
||||
def read(self, buf, endpos):
|
||||
size = endpos - buf.tell()
|
||||
@ -279,6 +280,7 @@ class HTTPRequest(Connection):
|
||||
except KeyError:
|
||||
return self.simple_response(http_client.HTTP_VERSION_NOT_SUPPORTED)
|
||||
self.response_protocol = protocol_map[min((1, 1), rp)]
|
||||
self.request_original_uri = uri
|
||||
try:
|
||||
self.scheme, self.path, self.query = parse_uri(uri)
|
||||
except HTTPSimpleResponse as e:
|
||||
|
@ -219,15 +219,18 @@ class RequestData(object): # {{{
|
||||
username = None
|
||||
|
||||
def __init__(self, method, path, query, inheaders, request_body_file, outheaders, response_protocol,
|
||||
static_cache, opts, remote_addr, remote_port, is_local_connection, translator_cache, tdir, forwarded_for):
|
||||
static_cache, opts, remote_addr, remote_port, is_local_connection, translator_cache,
|
||||
tdir, forwarded_for, request_original_uri=None):
|
||||
|
||||
(self.method, self.path, self.query, self.inheaders, self.request_body_file, self.outheaders,
|
||||
self.response_protocol, self.static_cache, self.translator_cache) = (
|
||||
method, path, query, inheaders, request_body_file, outheaders,
|
||||
response_protocol, static_cache, translator_cache
|
||||
)
|
||||
|
||||
self.remote_addr, self.remote_port, self.is_local_connection = remote_addr, remote_port, is_local_connection
|
||||
self.forwarded_for = forwarded_for
|
||||
self.request_original_uri = request_original_uri
|
||||
self.opts = opts
|
||||
self.status_code = http_client.OK
|
||||
self.outcookie = Cookie()
|
||||
@ -444,7 +447,7 @@ class HTTPConnection(HTTPRequest):
|
||||
self.method, self.path, self.query, inheaders, request_body_file,
|
||||
outheaders, self.response_protocol, self.static_cache, self.opts,
|
||||
self.remote_addr, self.remote_port, self.is_local_connection,
|
||||
self.translator_cache, self.tdir, self.forwarded_for
|
||||
self.translator_cache, self.tdir, self.forwarded_for, self.request_original_uri
|
||||
)
|
||||
self.queue_job(self.run_request_handler, data)
|
||||
|
||||
|
@ -26,9 +26,10 @@ from calibre import force_unicode
|
||||
|
||||
from calibre.srv.errors import HTTPNotFound, HTTPInternalServerError
|
||||
from calibre.srv.routes import endpoint
|
||||
from calibre.srv.http_request import parse_uri
|
||||
from calibre.srv.utils import get_library_data, http_date, Offsets
|
||||
from polyglot.builtins import iteritems, unicode_type, filter, as_bytes
|
||||
from polyglot.urllib import urlencode
|
||||
from polyglot.urllib import urlencode, unquote_plus
|
||||
from polyglot.binary import as_hex_unicode, from_hex_unicode
|
||||
|
||||
|
||||
@ -624,6 +625,11 @@ def opds_search(ctx, rd, query):
|
||||
raise HTTPNotFound('Not found')
|
||||
|
||||
rc = RequestContext(ctx, rd)
|
||||
if query:
|
||||
path = parse_uri(rd.request_original_uri, parse_query=False, unquote_func=unquote_plus)[1]
|
||||
query = path[-1]
|
||||
if isinstance(query, bytes):
|
||||
query = query.decode('utf-8')
|
||||
try:
|
||||
ids = rc.search(query)
|
||||
except Exception:
|
||||
|
@ -22,6 +22,7 @@ if is_py3:
|
||||
if binary:
|
||||
ans = ans.encode(encoding, errors)
|
||||
return ans
|
||||
|
||||
else:
|
||||
from urllib import (getproxies, quote, unquote as uq, quote_plus, url2pathname, # noqa
|
||||
urlencode) # noqa
|
||||
@ -43,3 +44,9 @@ else:
|
||||
if not binary:
|
||||
ans = ans.decode(encoding, errors)
|
||||
return ans
|
||||
|
||||
|
||||
def unquote_plus(x, encoding='utf-8', errors='replace'):
|
||||
q, repl = (b'+', b' ') if isinstance(x, bytes) else ('+', ' ')
|
||||
x = x.replace(q, repl)
|
||||
return unquote(x, encoding=encoding, errors=errors)
|
||||
|
Loading…
x
Reference in New Issue
Block a user