Skip to content

request path is percent-decoded in the wrong place #19

Description

@garlick

Problem: do_DELETE() percent-decodes the whole request path before matching it against the /api/v1/jobs/ prefix, so a request whose raw path is not under the API prefix is accepted as though it were.

$ curl -s --path-as-is -X DELETE 'http://localhost/api%2Fv1/jobs/f9zreCP' \
    --unix-socket $sock -w '\nHTTP %{http_code}\n'
{"id": "f9zreCP", "status": "cancel requested"}
HTTP 202          # job is actually canceled

do_GET() and do_POST() match on the raw path, so the same URL 404s on GET but succeeds on DELETE. Beyond the inconsistency, it means the routing decision depends on what the front end did or did not decode, rather than on the path as sent.

Fix: match the prefix on the raw path and unquote only the job id segment. The lenient-input goal (accepting a percent-encoded fancy F58 id) is preserved.

def _parse_job_path(path):
    prefix = f"{_PREFIX}/jobs/"
    if not path.startswith(prefix):
        return None
    jobid_str = urllib.parse.unquote(path[len(prefix) :])
    if not jobid_str or "/" in jobid_str:
        return None
    return flux.job.JobID(jobid_str)

and drop the urllib.parse.unquote() call in do_DELETE().

Worth a test asserting that a raw /api%2Fv1/jobs/<id> path is rejected.

Found while reviewing #17; not a regression, present since the endpoint was added.

Asisted-by: Claude:opus-5

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions