How do I escape a '/' in the URI for a GET request?

1k Views Asked by At

I'm trying to use Groovy to script a GET request to our GitLab server to retrieve a file. The API URI format is:

https://githost/api/v4/projects/<namespace>%2F<repo>/files/<path>?ref=<branch>

Note that there is an encoded '/' between namespace and repo. The final URI needs to look like the following to work properly:

https://githost/api/v4/projects/mynamespace%2Fmyrepo/files/myfile.json?ref=master

I have the following code:

File f = HttpBuilder.configure {
    request.uri.scheme = scheme
    request.uri.host = host
    request.uri.path = "/api/v4/projects/${apiNamespace}%2F${apiRepoName}/repository/files/${path}/myfile.json"
    request.uri.query.put("ref", "master")
    request.contentType = 'application/json'
    request.accept = 'application/json'
    request.headers['PRIVATE-TOKEN'] = apiToken
    ignoreSslIssues execution
}.get {
    Download.toFile(delegate as HttpConfig, new File("${dest}/myfile.json"))
}

However, the %2F is re-encoded as %252F. I've tried multiple ways to try and create the URI so that it doesn't encode the %2F in between the namespace and repo, but I can't get anything to work. It either re-encodes the '%' or decodes it to the literal "/".

How do I do this using Groovy + http-builder-ng to set the URI in a way that will preserve the encoded "/"? I've searched but can't find any examples that have worked.

Thanks!

2

There are 2 best solutions below

0
Jason Heithoff On

Possible Workaround

The Gitlab API allows you to query via project id or project name. Look up the project id first, then query the project.

  1. Lookup the project id first. See https://docs.gitlab.com/ee/api/projects.html#list-all-projects

    def projects = // GET /projects

    def project = projects.find { it['path_with_namespace'] == 'diaspora/diaspora-client' }

  2. Fetch Project by :id, See https://docs.gitlab.com/ee/api/projects.html#get-single-project

    GET /projects/${project.id}

0
cjstehno On

As of the 1.0.0 release you can handle requests with encoded characters in the URI. An example would be:

def result = HttpBuilder.configure {
    request.raw = "http://localhost:8080/projects/myteam%2Fmyrepo/myfile.json"
}.get()

Notice, the use of raw rather than uri in the example. Using this approach requires you to do any other encoding/decoding of the Uri yourself.