Merge branch 'master' into live

This commit is contained in:
Kevin Morris 2022-02-10 01:21:26 -08:00
commit e9472d5db6
No known key found for this signature in database
GPG key ID: F7E46DED420788F3
3 changed files with 61 additions and 15 deletions

View file

@ -274,7 +274,12 @@ class RPC:
] ]
# Union all subqueries together. # Union all subqueries together.
query = subqueries[0].union_all(*subqueries[1:]) max_results = config.getint("options", "max_rpc_results")
query = subqueries[0].union_all(*subqueries[1:]).limit(
max_results + 1).all()
if len(query) > max_results:
raise RPCError("Too many package results.")
# Store our extra information in a class-wise dictionary, # Store our extra information in a class-wise dictionary,
# which contains package id -> extra info dict mappings. # which contains package id -> extra info dict mappings.
@ -306,7 +311,11 @@ class RPC:
search.search_by(by, arg) search.search_by(by, arg)
max_results = config.getint("options", "max_rpc_results") max_results = config.getint("options", "max_rpc_results")
results = self._entities(search.results()).limit(max_results) results = self._entities(search.results()).limit(max_results + 1).all()
if len(results) > max_results:
raise RPCError("Too many package results.")
return self._assemble_json_data(results, self._get_json_data) return self._assemble_json_data(results, self._get_json_data)
def _handle_msearch_type(self, args: List[str] = [], **kwargs)\ def _handle_msearch_type(self, args: List[str] = [], **kwargs)\

View file

@ -28,21 +28,27 @@ Package information can be obtained by issuing HTTP GET requests of the form
+/rpc?v=5&type=info&arg[]=_pkg1_&arg[]=_pkg2_&...+ where _pkg1_, _pkg2_, ... +/rpc?v=5&type=info&arg[]=_pkg1_&arg[]=_pkg2_&...+ where _pkg1_, _pkg2_, ...
are the names of packages to retrieve package details for. are the names of packages to retrieve package details for.
Request Types Request Methods
------------- ---------------
The GET method here parses arguments in an odd way due to `v=5` historically Historically, the `type=multiinfo` `v=5` GET request has supported a
supporting this ordering. Later versions will remove support for this kind particular ordering of arguments. The POST request argument ordering
of parsing, and the POST method is our first step toward solving it. cannot be guaranteed, and so its behavior is different. Differences are
described below:
* `GET` `GET`::
- Search arguments are constructed using the last found argument(s). `type=multiinfo` arguments are parsed by iterating the query string
If the last related argument is `arg[]`, we collect arguments from from last to first key, looking for an `arg` or `arg[]`. Once one is
end to start until we hit a non-`arg[]` argument. If the last related found, behavior diverges depending on which is found first: the `arg`
argument is `arg`, it used as the one and only argument. parameter is used as the sole argument or the `arg[]` parameters are
* `POST` built into a list until a non-argument key is encountered.
- Search arguments are constructed using `[arg] + args` where `POST (experimental)`::
`args == arg[]`. All provided instances of `arg` and `arg[]` given to `type=multiinfo`
are supported in unison:
curl -d 'v=5' -d 'type=info' -d 'arg=one' -d 'arg[]=two' -d 'arg[]=three' ...
All other valid query types are supported without change.
Examples Examples
-------- --------

View file

@ -795,3 +795,34 @@ def test_rpc_post(client: TestClient, packages: List[Package]):
resp = request.post("/rpc", data=data) resp = request.post("/rpc", data=data)
assert resp.status_code == int(HTTPStatus.OK) assert resp.status_code == int(HTTPStatus.OK)
assert resp.json().get("resultcount") == 2 assert resp.json().get("resultcount") == 2
def test_rpc_too_many_search_results(client: TestClient,
packages: List[Package]):
config_getint = config.getint
def mock_config(section: str, key: str):
if key == "max_rpc_results":
return 1
return config_getint(section, key)
params = {"v": 5, "type": "search", "arg": "chungus"}
with mock.patch("aurweb.config.getint", side_effect=mock_config):
with client as request:
resp = request.get("/rpc", params=params)
assert resp.json().get("error") == "Too many package results."
def test_rpc_too_many_info_results(client: TestClient, packages: List[Package]):
config_getint = config.getint
def mock_config(section: str, key: str):
if key == "max_rpc_results":
return 1
return config_getint(section, key)
params = {"v": 5, "type": "info", "arg[]": [p.Name for p in packages]}
with mock.patch("aurweb.config.getint", side_effect=mock_config):
with client as request:
resp = request.get("/rpc", params=params)
assert resp.json().get("error") == "Too many package results."