Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
76 commits
Select commit Hold shift + click to select a range
66baca6
Total Overhaul (but with all the same fixtures!) (#248)
dimitropoulos Apr 26, 2022
c7eae4c
fix: case where if `postData.params` is missing some targets crash (#…
erunion May 13, 2022
998e403
fix: compatibility issues on node 14 with `Object.hasOwn()` (#252)
erunion May 13, 2022
f64080d
fix: typo in the httpie `style` option not being correctly applied (#…
erunion May 13, 2022
cd4bb4c
fix: axios targets not sending `x-www-form-urlencoded` properly (#255)
erunion May 19, 2022
62d158d
feat: addition of a PHP target for Guzzle (#253)
erunion May 19, 2022
0e0728a
Add Github Build Workflow (#250) (#251)
filfreire May 20, 2022
411844f
feat: native upload support in python `requests` snippets (#259)
erunion May 23, 2022
3119335
fix: `multipart/form-data` header issues with node/js fetch targets (…
erunion May 23, 2022
5e8f161
fix: headers not being properly applied to R httr snippets (#263)
erunion May 23, 2022
8ca9771
Fix build workflow dispatch rules (#265)
filfreire May 24, 2022
97731b1
Chore: Remove travis links (#266)
filfreire May 26, 2022
91a872b
fix: issue where query strings in R wouldn't be properly concatenated…
erunion Jul 13, 2022
d4bebe4
add header namesspace to prevent header errors (#247)
Jul 13, 2022
da711e9
fix: stop implicitly coercing warning in Swift snippet generator (#195)
irajtaghlidi Jul 14, 2022
3c9e6a6
fix: clj-http handling of literal null JSON bodies (#283)
dimitropoulos Jul 15, 2022
7da8c97
fix: prevent crash in Swift/Objc with checking length of input body p…
irajtaghlidi Jul 15, 2022
12aa17e
fix: cUrl target should encode x-www-form-urlencoded post data params…
jgiovaresco Jul 15, 2022
2c8b558
feat: Add support for insecureSkipVerify (#285)
dimitropoulos Jul 18, 2022
735e69a
feat: implementing cleaner handling of JSON in cURL snippets (#256)
erunion Jul 18, 2022
8ea7e13
chore: minor cleanup (#286)
erunion Jul 18, 2022
19f1b2f
feat: use curl's --compressed option for requests that accept it (#287)
dimitropoulos Jul 18, 2022
2f7525d
feat: make Python snippets simpler, clearer & more consistent (#288)
dimitropoulos Jul 18, 2022
4ac5253
feat: change the default response code for Python Requests (#181)
jgiovaresco Jul 19, 2022
a92b4fc
feat: PHP JSON body encoding (#291)
dimitropoulos Jul 19, 2022
5ec84e0
Async/Await (top level) support in JavaScript snippets (#292)
dimitropoulos Jul 19, 2022
1dda869
Exclude package.json from build to fix output paths (#294)
pimterry Jul 26, 2022
911ab77
Fix crash when building nsurlsession snippets for empty params (#295)
pimterry Jul 26, 2022
cd2a0cc
removes `require 'openssl'` from ruby target (no longer needed) (#296)
dimitropoulos Jul 27, 2022
bf019b3
Escape quotes in headers correctly in all languages (#289)
pimterry Jul 28, 2022
7c00d05
updates README (#299)
dimitropoulos Aug 30, 2022
cee79a5
ioutil -> io (deprecated) (#305)
Nov 2, 2022
6b8909e
audit fix
jackkav Jul 5, 2023
2026197
add missing type on README
filfreire Jul 7, 2023
a0c0933
types?
filfreire Jul 7, 2023
fc067af
Switching to Apache License Version 2.0
subnetmarco Sep 29, 2023
7c3d401
Support Node v20 (#333)
itsikcircle Dec 18, 2023
7efd8e0
Add SAST scanning using semgrep (#336)
saisatishkarra Jan 23, 2024
2e8c285
chore(feat/slsa)[SEC-1085]: add publish pipeline [INS-3792] (#347)
filfreire May 16, 2024
2aaed34
fix(CI): add pat for triggering releases [no-ticket] (#349)
filfreire May 16, 2024
36d0de1
fix(CI): Persist PAT to trigger downstream workflow on tag push (#350)
saisatishkarra May 16, 2024
cfb34a7
fix(ci): permissions to publish npm provenance (#351)
saisatishkarra May 16, 2024
c4a6906
feat: add npm version to release pipeline [INS-3853] (#352)
filfreire May 17, 2024
91be017
fix: rm extra commit on release.yml [INS-3853] (#353)
filfreire May 17, 2024
aa711ef
fix: release push [INS-3853] (#354)
filfreire May 17, 2024
b81e707
3.0.2
filfreire May 17, 2024
a3ddd6c
fix: tag weirdness (#355)
filfreire May 17, 2024
140d4b7
fix: release tags
filfreire May 17, 2024
7717966
fix: push also to origin
filfreire May 17, 2024
63650f3
3.0.4
filfreire May 17, 2024
143bb6d
Create SECURITY.md [SEC-1138]
filfreire Jul 2, 2024
e901d61
Add rust target with reqwest (#328)
Benjscho Jul 12, 2024
bb81dca
chore(deps-dev): bump ws from 7.5.7 to 7.5.10 (#358)
dependabot[bot] Jul 12, 2024
b6b2021
chore(deps-dev): bump braces from 3.0.2 to 3.0.3 (#357)
dependabot[bot] Jul 12, 2024
893da8b
chore(deps-dev): bump @babel/traverse from 7.22.6 to 7.24.5 (#348)
dependabot[bot] Jul 12, 2024
b9e1d7b
Generate Crystal language code (#343)
yanecc Jul 12, 2024
e99422a
Fix setting default value of request.PostData of HarEntry (#323)
nsrCodes Jul 12, 2024
29947cc
Support any method for PowerShell (#320)
verhovsky Jul 12, 2024
147eb98
chore: add nvmrc and set it to 20 (#262)
bbbco Jul 12, 2024
8739d73
Add generator for Ruby's Faraday client (#362)
filfreire Jul 12, 2024
fbd23b5
3.0.5
filfreire Jul 12, 2024
6a758d6
Prep for Release: source maps, types, prettier (#301)
dimitropoulos Jul 12, 2024
723581e
3.0.6
filfreire Jul 12, 2024
08aec7b
feat: replace ajv usage [INS-145] (#371)
vaibhavrajsingh2001 Sep 30, 2024
889ef62
3.0.7
filfreire Oct 1, 2024
d107479
correct the casing of Method enums in RestSharp snippets (#366)
michaelgwelch Oct 1, 2024
8a1bc90
3.0.8
filfreire Oct 1, 2024
66b587b
fix(form-data): fix ssr error due to window object access (#373)
vaibhavrajsingh2001 Oct 16, 2024
5b4474d
3.0.9
filfreire Oct 16, 2024
73c327c
fix: Pin all external github actions to their corresponding commit S…
balugeorge Mar 24, 2025
55cbe8b
fix: critical and high vulnerabilities [KHCP-18541] (#385)
ValeryG Nov 21, 2025
5f8234e
chore: bump deps to fix vulns (#390)
ryan-willis Mar 25, 2026
197f9a1
fix: use insomnia-automation app for release (#391)
ryan-willis Mar 25, 2026
795d98e
fix: identify automation app (#392)
ryan-willis Mar 25, 2026
d16b0a0
Merge remote-tracking branch 'upstream/master' into feat/update-fork
erunion Jun 9, 2026
f0b4e4a
fix: reverting an unnecessary change
erunion Jun 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# HTTP Snippet [![version][npm-version]][npm-url] [![License][npm-license]][license-url]
# HTTPSnippet

> HTTP Request snippet generator for _many_ languages & tools including: `cURL`, `HTTPie`, `Javascript`, `Node`, `C`, `Java`, `PHP`, `Objective-C`, `Swift`, `Python`, `Ruby`, `C#`, `Go`, `OCaml` and [more](https://github.com/Kong/httpsnippet/wiki/Targets)!
> HTTP Request snippet generator for _many_ languages & tools including: `cURL`, `HTTPie`, `Javascript`, `Node`, `C`, `Java`, `PHP`, `Objective-C`, `Swift`, `Python`, `Ruby`, `Rust`, `C#`, `Go`, `OCaml` and [more](https://github.com/Kong/httpsnippet/wiki/Targets)!

Relies on the popular [HAR](http://www.softwareishard.com/blog/har-12-spec/#request) format to import data and describe HTTP calls.

Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"keywords": [
"api",
"clojure",
"crystal",
"csharp",
"curl",
"go",
Expand All @@ -23,6 +24,7 @@
"python",
"requests",
"ruby",
"rust",
"shell",
"snippet",
"swift",
Expand Down
35 changes: 35 additions & 0 deletions src/helpers/__snapshots__/utils.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,20 @@ exports[`availableTargets > returns all available targets 1`] = `
"key": "clojure",
"title": "Clojure",
},
{
"clients": [
{
"description": "Crystal HTTP client",
"extname": ".cr",
"key": "native",
"link": "https://crystal-lang.org/api/master/HTTP/Client.html",
"title": "http::client",
},
],
"default": "native",
"key": "crystal",
"title": "Crystal",
},
{
"cli": "dotnet",
"clients": [
Expand Down Expand Up @@ -338,11 +352,32 @@ exports[`availableTargets > returns all available targets 1`] = `
"link": "http://ruby-doc.org/stdlib-2.2.1/libdoc/net/http/rdoc/Net/HTTP.html",
"title": "net::http",
},
{
"description": "Faraday HTTP client",
"extname": ".rb",
"key": "faraday",
"link": "https://github.com/lostisland/faraday",
"title": "faraday",
},
],
"default": "native",
"key": "ruby",
"title": "Ruby",
},
{
"clients": [
{
"description": "reqwest HTTP library",
"extname": ".rs",
"key": "reqwest",
"link": "https://docs.rs/reqwest/latest/reqwest/",
"title": "reqwest",
},
],
"default": "reqwest",
"key": "rust",
"title": "Rust",
},
{
"cli": "%s",
"clients": [
Expand Down
12 changes: 12 additions & 0 deletions src/helpers/code-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,18 @@ export class CodeBuilder {
this.code.push(newLine);
};

/**
* Add the line to the end of the last line. Creates a new line
* if no lines exist yet.
*/
pushToLast = (line: string): void => {
if (!this.code) {
this.push(line);
}
const updatedLine = `${this.code[this.code.length - 1]}${line}`;
this.code[this.code.length - 1] = updatedLine;
};

/**
* Add an empty line at the end of current lines
*/
Expand Down
19 changes: 19 additions & 0 deletions src/targets/crystal/native/client.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { Request } from '../../../index.js';

import httpInsecure from '../../../fixtures/requests/http-insecure.cjs';
import { runCustomFixtures } from '../../../fixtures/runCustomFixtures';

runCustomFixtures({
targetId: 'crystal',
clientId: 'native',
tests: [
{
it: 'should support the insecureSkipVerify option',
input: httpInsecure.log.entries[0].request as Request,
options: {
insecureSkipVerify: true,
},
expected: 'insecure-skip-verify.cr',
},
],
});
70 changes: 70 additions & 0 deletions src/targets/crystal/native/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* @description
* HTTP code snippet generator for native Crystal
*
* @author
* @18183883296
*
* for any questions or issues regarding the generated code snippet, please open an issue mentioning the author.
*/
import type { Client } from '../../index.js';

import { CodeBuilder } from '../../../helpers/code-builder';
import { escapeForDoubleQuotes } from '../../../helpers/escape';

export interface CrystalNativeOptions {
insecureSkipVerify?: boolean;
}

export const native: Client<CrystalNativeOptions> = {
info: {
key: 'native',
title: 'http::client',
link: 'https://crystal-lang.org/api/master/HTTP/Client.html',
description: 'Crystal HTTP client',
extname: '.cr',
},
convert: ({ method: rawMethod, fullUrl, postData, allHeaders }, options = {}) => {
const { insecureSkipVerify = false } = options;

const { push, blank, join } = new CodeBuilder();

push('require "http/client"');

blank();

push(`url = "${fullUrl}"`);

const headers = Object.keys(allHeaders);
if (headers.length) {
push('headers = HTTP::Headers{');
headers.forEach(key => {
push(` "${key}" => "${escapeForDoubleQuotes(allHeaders[key])}"`);
});
push('}');
}

if (postData.text) {
push(`reqBody = ${JSON.stringify(postData.text)}`);
}

blank();

const method = rawMethod.toUpperCase();
const methods = ['GET', 'POST', 'HEAD', 'DELETE', 'PATCH', 'PUT', 'OPTIONS'];

const headersContext = headers.length ? ', headers: headers' : '';
const bodyContext = postData.text ? ', body: reqBody' : '';
const sslContext = insecureSkipVerify ? ', tls: OpenSSL::SSL::Context::Client.insecure' : '';

if (methods.includes(method)) {
push(`response = HTTP::Client.${method.toLowerCase()} url${headersContext}${bodyContext}${sslContext}`);
} else {
push(`response = HTTP::Client.exec "${method}", url${headersContext}${bodyContext}${sslContext}`);
}

push('puts response.body');

return join();
},
};
10 changes: 10 additions & 0 deletions src/targets/crystal/native/fixtures/application-form-encoded.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require "http/client"

url = "https://httpbin.org/anything"
headers = HTTP::Headers{
"content-type" => "application/x-www-form-urlencoded"
}
reqBody = "foo=bar&hello=world"

response = HTTP::Client.post url, headers: headers, body: reqBody
puts response.body
10 changes: 10 additions & 0 deletions src/targets/crystal/native/fixtures/application-json.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require "http/client"

url = "https://httpbin.org/anything"
headers = HTTP::Headers{
"content-type" => "application/json"
}
reqBody = "{\"number\":1,\"string\":\"f\\\"oo\",\"arr\":[1,2,3],\"nested\":{\"a\":\"b\"},\"arr_mix\":[1,\"a\",{\"arr_mix_nested\":[]}],\"boolean\":false}"

response = HTTP::Client.post url, headers: headers, body: reqBody
puts response.body
9 changes: 9 additions & 0 deletions src/targets/crystal/native/fixtures/cookies.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
require "http/client"

url = "https://httpbin.org/cookies"
headers = HTTP::Headers{
"cookie" => "foo=bar; bar=baz"
}

response = HTTP::Client.get url, headers: headers
puts response.body
6 changes: 6 additions & 0 deletions src/targets/crystal/native/fixtures/custom-method.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require "http/client"

url = "https://httpbin.org/anything"

response = HTTP::Client.exec "PROPFIND", url
puts response.body
12 changes: 12 additions & 0 deletions src/targets/crystal/native/fixtures/full.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require "http/client"

url = "https://httpbin.org/anything?foo=bar&foo=baz&baz=abc&key=value"
headers = HTTP::Headers{
"cookie" => "foo=bar; bar=baz"
"accept" => "application/json"
"content-type" => "application/x-www-form-urlencoded"
}
reqBody = "foo=bar"

response = HTTP::Client.post url, headers: headers, body: reqBody
puts response.body
12 changes: 12 additions & 0 deletions src/targets/crystal/native/fixtures/headers.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
require "http/client"

url = "https://httpbin.org/headers"
headers = HTTP::Headers{
"accept" => "application/json"
"x-foo" => "Bar"
"x-bar" => "Foo"
"quoted-value" => "\"quoted\" 'string'"
}

response = HTTP::Client.get url, headers: headers
puts response.body
6 changes: 6 additions & 0 deletions src/targets/crystal/native/fixtures/http-insecure.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require "http/client"

url = "http://httpbin.org/anything"

response = HTTP::Client.get url
puts response.body
6 changes: 6 additions & 0 deletions src/targets/crystal/native/fixtures/insecure-skip-verify.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require "http/client"

url = "http://httpbin.org/anything"

response = HTTP::Client.get url, tls: OpenSSL::SSL::Context::Client.insecure
puts response.body
10 changes: 10 additions & 0 deletions src/targets/crystal/native/fixtures/jsonObj-multiline.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require "http/client"

url = "https://httpbin.org/anything"
headers = HTTP::Headers{
"content-type" => "application/json"
}
reqBody = "{\n \"foo\": \"bar\"\n}"

response = HTTP::Client.post url, headers: headers, body: reqBody
puts response.body
10 changes: 10 additions & 0 deletions src/targets/crystal/native/fixtures/jsonObj-null-value.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require "http/client"

url = "https://httpbin.org/anything"
headers = HTTP::Headers{
"content-type" => "application/json"
}
reqBody = "{\"foo\":null}"

response = HTTP::Client.post url, headers: headers, body: reqBody
puts response.body
10 changes: 10 additions & 0 deletions src/targets/crystal/native/fixtures/multipart-data.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require "http/client"

url = "https://httpbin.org/anything"
headers = HTTP::Headers{
"content-type" => "multipart/form-data; boundary=---011000010111000001101001"
}
reqBody = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"foo\"; filename=\"src/fixtures/files/hello.txt\"\r\nContent-Type: text/plain\r\n\r\nHello World\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"bar\"\r\n\r\nBonjour le monde\r\n-----011000010111000001101001--"

response = HTTP::Client.post url, headers: headers, body: reqBody
puts response.body
10 changes: 10 additions & 0 deletions src/targets/crystal/native/fixtures/multipart-file.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require "http/client"

url = "https://httpbin.org/anything"
headers = HTTP::Headers{
"content-type" => "multipart/form-data; boundary=---011000010111000001101001"
}
reqBody = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"foo\"; filename=\"src/fixtures/files/hello.txt\"\r\nContent-Type: text/plain\r\n\r\n\r\n-----011000010111000001101001--"

response = HTTP::Client.post url, headers: headers, body: reqBody
puts response.body
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
require "http/client"

url = "https://httpbin.org/anything"
headers = HTTP::Headers{
"Content-Type" => "multipart/form-data"
}

response = HTTP::Client.post url, headers: headers
puts response.body
10 changes: 10 additions & 0 deletions src/targets/crystal/native/fixtures/multipart-form-data.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require "http/client"

url = "https://httpbin.org/anything"
headers = HTTP::Headers{
"Content-Type" => "multipart/form-data; boundary=---011000010111000001101001"
}
reqBody = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"foo\"\r\n\r\nbar\r\n-----011000010111000001101001--"

response = HTTP::Client.post url, headers: headers, body: reqBody
puts response.body
6 changes: 6 additions & 0 deletions src/targets/crystal/native/fixtures/nested.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require "http/client"

url = "https://httpbin.org/anything?foo%5Bbar%5D=baz%2Czap&fiz=buz&key=value"

response = HTTP::Client.get url
puts response.body
9 changes: 9 additions & 0 deletions src/targets/crystal/native/fixtures/postdata-malformed.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
require "http/client"

url = "https://httpbin.org/anything"
headers = HTTP::Headers{
"content-type" => "application/json"
}

response = HTTP::Client.post url, headers: headers
puts response.body
6 changes: 6 additions & 0 deletions src/targets/crystal/native/fixtures/query-encoded.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require "http/client"

url = "https://httpbin.org/anything?startTime=2019-06-13T19%3A08%3A25.455Z&endTime=2015-09-15T14%3A00%3A12-04%3A00"

response = HTTP::Client.get url
puts response.body
6 changes: 6 additions & 0 deletions src/targets/crystal/native/fixtures/query.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require "http/client"

url = "https://httpbin.org/anything?foo=bar&foo=baz&baz=abc&key=value"

response = HTTP::Client.get url
puts response.body
6 changes: 6 additions & 0 deletions src/targets/crystal/native/fixtures/short.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require "http/client"

url = "https://httpbin.org/anything"

response = HTTP::Client.get url
puts response.body
Loading