Skip to content

Raw Files over HTTP

View as Markdown

CloudRepo has no Raw repository type. The create form shows an HTTP tile that is disabled and marked Coming soon, so you cannot create a repository of that type. To store and serve any file over plain HTTP, use a Maven repository: it stores a file at any path you name and returns it from the same path. Nothing about the file has to look like a Maven artifact.

This page uses curl, so it works from any shell, script or CI job.

  • A Maven repository. If you have none, see Create Your First Repository and choose Maven.
  • A repository token with Read + write access to it, from Repository Tokens: Create One and Authenticate. The username is the email address of the account that created the token, and the password is the token.
  • curl reads that credential from ~/.netrc, so it never appears on a command line. Create the file, keep it readable by you alone (chmod 600 ~/.netrc), and put your organization’s host in it:
~/.netrc
machine your-org.mycloudrepo.io
login you@example.com
password YOUR_REPOSITORY_TOKEN

A file’s address is the repository URL plus the path you choose: https://your-org.mycloudrepo.io/repositories/your-repo/ followed by the path, with no leading slash.

Make a file to send:

Terminal
echo 'Hello from CloudRepo.' > hello.txt

Send it with --upload-file, which sends a PUT of the file exactly as it is:

Terminal
curl --netrc --fail --upload-file hello.txt \
https://your-org.mycloudrepo.io/repositories/your-repo/uploads/hello.txt

Expected: curl exits 0. CloudRepo answers 200 with no body.

Do not send a file with --data: curl sends a POST unless told otherwise, and a repository URL accepts only GET, HEAD and PUT. It also removes newlines from the file it reads.

Terminal
curl --netrc --fail --output hello-copy.txt \
https://your-org.mycloudrepo.io/repositories/your-repo/uploads/hello.txt

Expected: hello-copy.txt holds the bytes you uploaded.

CloudRepo serves every download as application/octet-stream, whatever the upload said its type was.

To check that a file exists without downloading it, ask for its headers:

Terminal
curl --netrc --fail --head \
https://your-org.mycloudrepo.io/repositories/your-repo/uploads/hello.txt

Expected: a 200 status line and a content-length header. A path nobody stored answers 404 Not Found.

The portal lists a repository’s files in its file browser. See Repository Management.

The repository also lists a directory over HTTP, as an HTML page with each name, its last modified time and its size. A browser gets it, and so does any client that sends Accept: text/html for a path ending in /:

Terminal
curl --netrc --fail --header 'Accept: text/html' \
https://your-org.mycloudrepo.io/repositories/your-repo/uploads/

The listing at a repository URL is an HTML page only. A client that asks for a directory path without that header is asking for a file that is not there, and gets 404 Not Found. The one exception is the repository root, https://your-org.mycloudrepo.io/repositories/your-repo/: it answers with the listing, with the header or without. An empty repository answers 404 Not Found.

A repository URL has no DELETE: it answers 405 Method Not Allowed. Delete files in the portal. See Deleting Files and Folders.

A new repository has Overwrite Protection on, so a second upload to a path that already holds a file is refused with 409 Conflict:

Response
Version already exists. Overwrites are disabled for this repository.

Put each version of a file at its own path (builds/1.4.0/app.tar.gz), or turn Overwrite Protection off on a repository that exists to hold replaceable files. With it off, a credential that can write can replace any file in the repository. Two kinds of file can always be replaced: a file whose own directory ends in -SNAPSHOT (builds/1.4.0-SNAPSHOT/app.tar.gz, but not builds/1.4.0-SNAPSHOT/logs/app.log), and maven-metadata.xml with its checksum and signature files (.md5, .sha1, .sha256, .sha512, .asc). See Maven: SNAPSHOT and Metadata Are Exempt.

  • Path. Use letters, digits and these characters: + _ - . ! * ' ( ) / @ ~. Any other character, such as a space or a percent sign, is refused with 400 Bad Request. The whole key, your-org/your-repo/ followed by your path, may be up to 1,024 characters.
  • Size. One file can be up to 50 GB (50,000,000,000 bytes). A larger file is refused with 413.

To let anyone read the files in a repository, turn on its Public Access card. See Enabling Public Repository Access. Reads then work without credentials at https://your-org.mycloudrepo.io/public/repositories/your-repo/ followed by the path. Writes still need a token.

What you see Why What to do
401 Unauthorized No credential, or one CloudRepo refused: a mistyped, expired or revoked token, or a username that is not the email address of the token’s account. Check ~/.netrc against the token. See When a publish is refused.
403 Forbidden on an upload The token is Read only, or it does not include this repository. Create a Read + write token that includes the repository.
404 Not Found on a download Nothing is stored at that path, or the path is a directory. Check the path. List the directory as shown above.
405 Method Not Allowed The request used DELETE or POST. Upload with --upload-file. Delete in the portal.
409 Conflict on an upload A file is already stored at that path and Overwrite Protection is on. Use a new path, or see above.
400 Bad Request The path holds a character the repository does not accept. Use only the characters listed under Limits.
413 on an upload The file is over 50 GB. Split it into several files.

curl --fail shows only a short error that carries the status code, such as curl: (22) The requested URL returned error: 409, and hides the body. Add --fail-with-body (curl 7.76.0 or later) to see the explanation CloudRepo sends with the refusal.