{"id":44645642,"url":"https://github.com/nixpig/corkscrew","last_synced_at":"2026-02-14T19:33:44.572Z","repository":{"id":208190303,"uuid":"714565336","full_name":"nixpig/corkscrew","owner":"nixpig","description":"🌀 Batch execution of HTTP requests from a simple YAML schema.","archived":false,"fork":false,"pushed_at":"2024-02-07T16:13:21.000Z","size":183,"stargazers_count":0,"open_issues_count":7,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-10T06:49:40.604Z","etag":null,"topics":["curl","featured","http","https","request","rust","wget","yaml"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nixpig.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2023-11-05T09:32:08.000Z","updated_at":"2025-07-06T05:08:20.000Z","dependencies_parsed_at":"2023-12-01T08:41:41.818Z","dependency_job_id":"0d514963-83d4-4d9e-ab92-d48f551ad412","html_url":"https://github.com/nixpig/corkscrew","commit_stats":null,"previous_names":["nixpig/corkscrew"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/nixpig/corkscrew","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nixpig%2Fcorkscrew","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nixpig%2Fcorkscrew/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nixpig%2Fcorkscrew/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nixpig%2Fcorkscrew/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nixpig","download_url":"https://codeload.github.com/nixpig/corkscrew/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nixpig%2Fcorkscrew/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29453472,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-14T15:52:44.973Z","status":"ssl_error","status_checked_at":"2026-02-14T15:52:11.208Z","response_time":53,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["curl","featured","http","https","request","rust","wget","yaml"],"created_at":"2026-02-14T19:33:44.022Z","updated_at":"2026-02-14T19:33:44.566Z","avatar_url":"https://github.com/nixpig.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Workflow Status](https://github.com/nixpig/corkscrew/actions/workflows/general.yml/badge.svg?branch=main)](https://github.com/nixpig/corkscrew/actions/workflows/general.yml?query=branch%3Amain)\n[![Coverage Status](https://coveralls.io/repos/github/nixpig/corkscrew/badge.svg?branch=main)](https://coveralls.io/github/nixpig/corkscrew?branch=main)\n\n# 🌀 corkscrew\n\nA simple tool for executing HTTP requests configured in YAML. Written in Rust, btw.\n\n\u003e 🦀 This is my first ever project in Rust. No doubt there's going to me many things that can be improved upon. Happy to receive constructive suggestions in [issues](https://github.com/nixpig/corkscrew/issues).\n\n## ⚠️ WORK IN PROGRESS\n\n**It's probably not a good idea to actually use this for anything at this point. Maybe soon 🤷**\n\n## Features\n\n```shell\n$ corkscrew --help\n\nConfigure HTTP requests in YAML and execute from the command line.\n\nUsage: corkscrew [OPTIONS] [REQUEST_NAMES]...\n\nArguments:\n  [REQUEST_NAMES]...\n\nOptions:\n  -f, --file \u003cfile_path\u003e  Path to file containing requests [default: requests.yml]\n  -p, --parallel \u003cnum\u003e    Specify number of parallel requests\n  -h, --help              Print help\n  -V, --version           Print version\n```\n\n## Installation\n\n### Build from source\n\n1. Install the Rust toolchain ([instructions](https://rustup.rs/))\n1. `git clone https://github.com/nixpig/corkscrew.git`\n1. `cd corkscrew`\n1. `cargo build --release`\n1. `mv target/release/corkscrew ~/.local/bin/`\n\n```shell\n\n```\n\n## Examples\n\n### Minimal example (single request)\n\n```yaml\n# requests.yml\n\n- name: get_posts\n  host: example.com\n  resource: /api/posts\n```\n\n```shell\n$ corkscrew\n  # =\u003e get request to http://example.com/api/posts\n\n+---+---------------------------------+--------+\n| # | URL                             | Status |\n+---+---------------------------------+--------+\n| 0 | http://example.com/posts        | 200    |\n+---+---------------------------------+--------+\n```\n\n### Multiple requests\n\n```yaml\n# requests.yml\n\n- name: multiple_requests\n  host: example.com\n  requests:\n    - name: get_users\n      resource: /api/users\n    - name: get_posts\n      resource: /api/posts\n    - name: get_comments\n      resource: /api/comments\n```\n\n```shell\n$ corkscrew\n  # =\u003e get request to http://example.com/api/users\n  # =\u003e get request to http://example.com/api/posts\n  # =\u003e get request to http://example.com/api/comments\n```\n\n### Specify requests\n\n```yaml\n# requests.yml\n\n- name: multiple_requests\n  host: example.com\n  requests:\n    - name: get_users\n      resource: /api/users\n    - name: get_posts\n      resource: /api/posts\n    - name: get_comments\n      resource: /api/comments\n```\n\n```shell\n$ corkscrew get_posts get_comments\n  # =\u003e get request to http://example.com/api/posts\n  # =\u003e get request to http://example.com/api/comments\n```\n\n### Send POST request with JSON body\n\n```yaml\n# requests.yml\n\n- name: post_json_body\n  host: example.com\n  resource: /api/likes\n  method: post\n  body:\n    postId: 2\n    userId: 3\n```\n\n```shell\n$ corkscrew\n  # =\u003e post request to http://example.com/api/likes\n  # Content-Type: application/json\n  # { \"postId\": 2, \"userId\": 3 }\n```\n\n### Send POST request with form data\n\n```yml\n# requests.yml\n\n- name: post_form_data\n  host: example.com\n  resource: /api/comments\n  method: post\n  form:\n    userId: 3\n    comment: I really liked this!\n```\n\n```shell\n$ corkscrew\n  # =\u003e post request to http://example.com/api/comments\n  # Content-Type: application/x-www-form-urlencoded\n  # userId=3\u0026comment=I%20really%20liked%20this%21\n```\n\n### Send request with query parameters\n\n```yaml\n# requests.yml\n\n- name: query_params\n  host: example.com\n  resource: /api/comments\n  params:\n    userId: 3\n    limit: 10\n```\n\n```shell\n$ corkscrew\n  # =\u003e get request to http://example.com/api/comments?userId=3\u0026limit=10\n```\n\n### Send request with auth token\n\n```yaml\n# requests.yml\n\n- name: bearer_auth\n  host: example.com\n  resource: /api/users\n  auth: !bearer\n    token: abcd$1234\n```\n\n```shell\n$ corkscrew\n  # =\u003e get request to http://example.com/api/users\n  # Authorization: Bearer \u003ctoken\u003e\n```\n\n### Send request with HTTP basic auth\n\n```yaml\n- name: basic_auth\n  host: example.com\n  resource: /api/login\n  auth: !basic\n    username: corks\n    password: p4ssw0rd\n```\n\n```shell\n$ corkscrew\n  # =\u003e get request to http://example.com/api/users\n  # Authorization: Basic \u003ccredentials\u003e\n```\n\n### Nesting requests\n\nRequests can also be nested, where descendents can 'inherit' and/or 'override' properties from their ancestors.\n\n```yaml\n- name: example_root\n  host: example.com\n  resource: /api\n  scheme: https\n  requests:\n    - name: example_get_post\n      resource: /api/post\n    - name: example_get_comments\n      resource: /api/comments\n      params:\n        postId: 1\n```\n\n```shell\n$ corkscrew\n  # =\u003e get request to https://example.com/api\n  # =\u003e get request to https://example.com/api/post\n  # =\u003e get request to https://example.com/api/comments\n```\n\n## API\n\n\u003e This is a work in progress and open to change.\n\n```yaml\n- name: String # name of the host (can be any string, it's not used to build the actual request)\n  host: String # the host to which to make a request, e.g. example.com\n  scheme: String\u003chttp|https\u003e # the scheme to use, e.g. https (default: http)\n  port: Number # the port to use\n  timeout: Number # number of seconds before timing out (default: 30)\n  resource: String # that resource to request, e.g. /api/user\n  method: String\u003cget|post|put|patch|delete\u003e # the http method to use, e.g. post (default: get)\n  params:\n    # \u003cparameter_name\u003e: \u003cparameter_value\u003e\n    name: value\n\n  # the type of authentication to use, valid values are !basic or !bearer\n  auth: Enum\u003c!basic|!bearer\u003e # valid enum values are !basic or !bearer\n    token: String # in the case of !bearer authentication, provide the token to use\n    username: String # in the case of !basic authentication, provide the username to use\n    password: String # in the case of !basic authentication, provide the password to use\n\n  # Optional form data content (implicitly sets Content-Type: application/x-www-form-urlencoded)\n  form:\n    name1: value1\n    name2: value2\n    name3: value3\n\n  # Optional body content (implicityly sets Content-Type: application/json)\n  body:\n    name: value # \u003cproperty_name\u003e: \u003cproperty_value\u003e\n    # also supports nested JSON structures\n    l1_name1: l1_value1\n    l1_name2:\n      l2_name1: l2_value1\n      l2_name2:\n        l3_name1: l3_value1\n        l3_name2: l3_value2\n\n  # Optional headers\n  headers:\n    # \u003cheader_name\u003e: \u003cheader_value\u003e\n    name: value\n\n  # Optional nested requests\n  requests:\n    - \u003cRequest\u003e\n```\n\n## Motivation\n\nI wanted a way to define project-specific REST API requests to quickly and easily execute from the command-line.\n\n## Alternatives\n\nThere are a bunch of other solutions for making REST API requests.\n\nI've tried most of these in the past, but they didn't quite fit into my workflow as I needed. They may well work for you, in which case, don't worry!\n\n| Name    | Type | Challenges                                                                                              |\n| ------- | ---- | ------------------------------------------------------------------------------------------------------- |\n| cURL    | CLI  | Depending on the approach, either searching through shell history or maintaining lots of `.http` files. |\n| Postman | GUI  | GUI apps don't fit well into my workflow. JSON is a pain to maintain.                                   |\n\nYes, I've probably also tried _insert favourite util here_, raw-dogging `ncat` requests, and everything in between.\n\n## Contribute\n\nThis is a personal project for me to learn Rust and is not currently open for contributions.\n\nThis may change in the future.\n\nFeel free to leave constructive comments, feedback or suggestions in the [issues](https://github.com/nixpig/corkscrew/issues).\n\n## TODO\n\n- [ ] Use Hyper instead of Reqwest.\n- [ ] Handle errors and non-happy path scenarios.\n- [ ] Use a request client pool to reuse clients instead of creating new ones for every request.\n- [ ] Add option to parallelise request execution and specify number of threads, e.g. `--parallel 4`.\n- [ ] Add option to output various data from request response.\n- [ ] Show some 'in progress' message/counter.\n- [ ] Add option to specify nested groups of requests by `request_group` / `request_group:request_group` / `request_group:request`.\n- [ ] Get rid of all the data cloning, unwrapping, etc...\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnixpig%2Fcorkscrew","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnixpig%2Fcorkscrew","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnixpig%2Fcorkscrew/lists"}