Skip to content

Instantly share code, notes, and snippets.

@danielt1263
Last active January 12, 2025 17:30
Show Gist options
  • Save danielt1263/103828b8f38742b73493f3e4c22d9c64 to your computer and use it in GitHub Desktop.
Save danielt1263/103828b8f38742b73493f3e4c22d9c64 to your computer and use it in GitHub Desktop.
//
// URLRequest+curlCommand Tests.swift
//
// Created by Daniel Tartaglia on 21 Nov 2024.
// Copyright © 2025 Daniel Tartaglia. MIT License.
//
struct curl_command_tests {
struct first_line_tests {
@Test func firstLineContainsGETIfMissingMethod() {
let request = URLRequest(url: URL(string: "https://nil.dev")!)
let result = request.curlCommand()
#expect(result.components(separatedBy: .newlines).first == "curl -X GET \\")
}
@Test func firstLineContainsMethod() {
var request = URLRequest(url: URL(string: "https://nil.dev")!)
request.httpMethod = "PUT"
let result = request.curlCommand()
#expect(result.components(separatedBy: .newlines).first == "curl -X PUT \\")
}
@Test func firstLineContainsBody() {
var request = URLRequest(url: URL(string: "https://nil.dev")!)
request.httpBody = "FooBar".data(using: .utf8)
let result = request.curlCommand()
#expect(result.components(separatedBy: .newlines).first == #"curl -X GET -d "FooBar" \"#)
}
@Test func quotesInBodyAreEscaped() {
var request = URLRequest(url: URL(string: "https://nil.dev")!)
request.httpBody = "Foo \"Bar\"".data(using: .utf8)
let result = request.curlCommand()
#expect(result.components(separatedBy: .newlines).first == #"curl -X GET -d "Foo \"Bar\"" \"#)
}
}
struct second_line_tests {
@Test func secondLineContainsHeader() {
var request = URLRequest(url: URL(string: "https://nil.dev")!)
request.addValue("Bearer foobar", forHTTPHeaderField: "Authorization")
let result = request.curlCommand()
#expect(result.components(separatedBy: .newlines).dropFirst()
.first == #" -H "Authorization: Bearer foobar" \"#)
}
@Test func quotesInHeaderAreEscaped() {
var request = URLRequest(url: URL(string: "https://nil.dev")!)
request.addValue("Bearer \"foo bar\"", forHTTPHeaderField: "Authorization")
let result = request.curlCommand()
#expect(result.components(separatedBy: .newlines).dropFirst()
.first == #" -H "Authorization: Bearer \"foo bar\"" \"#)
}
@Test func noHeadersMeansSecondLineContainsURL() {
let request = URLRequest(url: URL(string: "https://nil.dev")!)
let result = request.curlCommand()
#expect(result.components(separatedBy: .newlines).dropFirst().first == #""https://nil.dev" -i -v"#)
}
}
@Test func lastLineShowsUnknownWhenURLIsMissing() {
var request = URLRequest(url: URL(string: "https://nil.dev")!)
request.url = nil
let result = request.curlCommand()
#expect(result.components(separatedBy: .newlines).last == #""<unknown url>" -i -v"#)
}
}
//
// URLRequest+curlCommand.swift
//
// Created by Daniel Tartaglia on 21 Nov 2024.
// Copyright © 2025 Daniel Tartaglia. MIT License.
//
extension URLRequest {
/// Produce a string that can be copy & pasted into the terminal in order to check the network response.
///
/// - Returns: A String representing the curl command of the request.
func curlCommand() -> String {
template(
method: httpMethod ?? "GET",
body: httpBody.flatMap { String(data: $0, encoding: .utf8)?.escapedQuotes() } ?? "",
headerFields: allHTTPHeaderFields?.map { ($0.key, $0.value.escapedQuotes()) } ?? [],
url: url?.absoluteString ?? "<unknown url>"
)
}
}
private func template(method: String, body: String, headerFields: [(key: String, value: String)], url: String) -> String
{
#"curl -X \#(method)\#(body.isEmpty ? "" : #" -d "\#(body)""#) \\#n"#
+ headerFields.map { #" -H "\#($0.key): \#($0.value)" "# }.joined(separator: "\\\n")
+ (headerFields.isEmpty ? "" : "\\\n")
+ #""\#(url)" -i -v"#
}
private extension String {
func escapedQuotes() -> String {
replacingOccurrences(of: #"""#, with: #"\""#, options: [], range: nil)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment