Skip to content

A .NET library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, POP3, POP3S, RTMP, RTMPS, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features

License

Notifications You must be signed in to change notification settings

jacob-mellor/curl-dot-net

Β 
Β 

Repository files navigation

CurlDotNet - curl for C# and .NET

NuGet Version Downloads Build Status License Coverage

CurlDotNet - Why .NET Needs a POSIX/GNU Userland

CurlDotNet Icon

πŸ†• New to curl? Start Here!

πŸ“– Complete Beginner's Guide to curl in C# β†’

The Industry Standard curl Experience for C# and .NET Developers

CurlDotNet brings the power and simplicity of curl to the .NET ecosystem. Execute curl commands directly in C#, make HTTP requests with curl's battle-tested reliability, and leverage decades of curl development - all with pure .NET code.

πŸš€ Quick Start with curl for C# and .NET

using CurlDotNet;

// Execute curl commands directly in C#
var result = await Curl.ExecuteAsync("curl -X GET https://api.github.com/users/octocat -H 'Accept: application/json'");

// Or use the fluent API for type safety
var response = await Curl.GetAsync("https://api.github.com/users/octocat")
    .WithHeader("Accept", "application/vnd.github.v3+json")
    .ExecuteAsync();

// Simple one-liners for common operations
var json = await Curl.GetJsonAsync<GitHubUser>("https://api.github.com/users/octocat");

πŸ“Š Code Coverage

  • Line Coverage: 65.9%
  • Branch Coverage: 72%
  • Method Coverage: 59.9%
  • Tests: 657 total, 619 passing, 38 failing
  • Last Updated: 2025-11-18

πŸ“¦ Installation

# .NET CLI
dotnet add package CurlDotNet

# Package Manager Console
Install-Package CurlDotNet

# PackageReference
<PackageReference Include="CurlDotNet" Version="*" />

✨ Why CurlDotNet?

curl Compatibility in .NET

  • 100% curl behavior - Your C# code works exactly like curl commands
  • Parse any curl command - Copy from documentation and paste into your code
  • Industry standard - Used by millions of developers worldwide

Superior to HttpClient

  • More features - Proxies, authentication chains, retries, rate limiting
  • Better debugging - curl-style verbose output
  • Simpler API - One-line operations that would take 20+ lines with HttpClient

Pure .NET Implementation

  • No native dependencies - 100% managed C# code
  • Universal compatibility - Runs anywhere .NET runs: Windows, Linux, macOS, iOS, Android, IoT devices, Docker, cloud
  • Safe and secure - No P/Invoke, no unmanaged memory

🎯 Key Features

HTTP/REST Operations

// GET request
var data = await Curl.GetAsync("https://api.example.com/users");

// POST JSON
var user = await Curl.PostJsonAsync("https://api.example.com/users",
    new { name = "Alice", email = "[email protected]" });

// PUT with authentication
await Curl.PutAsync("https://api.example.com/users/123")
    .WithBearerToken(token)
    .WithJson(updatedData)
    .ExecuteAsync();

// DELETE
await Curl.DeleteAsync("https://api.example.com/users/123");

// PATCH
await Curl.PatchAsync("https://api.example.com/users/123")
    .WithJson(new { status = "active" })
    .ExecuteAsync();

Authentication Methods

// Bearer Token
await Curl.GetAsync("https://api.example.com")
    .WithBearerToken("your-token")
    .ExecuteAsync();

// Basic Auth
await Curl.GetAsync("https://api.example.com")
    .WithBasicAuth("username", "password")
    .ExecuteAsync();

// API Key
await Curl.GetAsync("https://api.example.com")
    .WithApiKey("X-API-Key", "your-api-key")
    .ExecuteAsync();

// OAuth 2.0
await Curl.GetAsync("https://api.example.com")
    .WithOAuth2("access-token", "Bearer")
    .ExecuteAsync();

// Custom headers
await Curl.GetAsync("https://api.example.com")
    .WithHeader("X-Custom-Auth", "token123")
    .ExecuteAsync();

File Operations

// Download file with progress
await Curl.DownloadFileAsync(
    "https://example.com/large-file.zip",
    "local-file.zip",
    progress: (percent) => Console.WriteLine($"Progress: {percent:F1}%")
);

// Upload file
await Curl.PostAsync("https://api.example.com/upload")
    .WithFile("file", "/path/to/file.pdf")
    .ExecuteAsync();

// Multipart form data
await Curl.PostAsync("https://api.example.com/upload")
    .WithMultipartForm(form => form
        .AddString("name", "John")
        .AddFile("document", "/path/to/doc.pdf")
        .AddFile("image", "/path/to/image.jpg"))
    .ExecuteAsync();

Proxy Support

// HTTP proxy
await Curl.GetAsync("https://api.example.com")
    .WithProxy("http://proxy.example.com:8080")
    .WithProxyAuth("username", "password")
    .ExecuteAsync();

// SOCKS5 proxy (Tor)
await Curl.GetAsync("https://check.torproject.org")
    .WithSocks5Proxy("socks5://127.0.0.1:9050")
    .ExecuteAsync();

// Residential proxy
await Curl.GetAsync("https://api.example.com")
    .WithProxy("http://gate.smartproxy.com:10000")
    .WithProxyAuth("user-country-us", "password")
    .ExecuteAsync();

// Rotating proxy
await Curl.GetAsync("https://api.example.com")
    .WithProxy("http://proxy.provider.com:8000")
    .WithProxyAuth($"user-session-{Guid.NewGuid()}", "password")
    .ExecuteAsync();

// Backconnect proxy
await Curl.GetAsync("https://api.example.com")
    .WithBackconnectProxy("proxy.provider.com", 20001)
    .ExecuteAsync();

Advanced Features

// Retry with exponential backoff
await Curl.GetAsync("https://api.example.com")
    .WithRetry(maxAttempts: 3)
    .WithExponentialBackoff()
    .ExecuteAsync();

// Rate limiting
await Curl.GetAsync("https://api.example.com")
    .WithRateLimit(requestsPerMinute: 60)
    .ExecuteAsync();

// Timeout handling
await Curl.GetAsync("https://api.example.com")
    .WithTimeout(TimeSpan.FromSeconds(30))
    .WithConnectTimeout(TimeSpan.FromSeconds(10))
    .ExecuteAsync();

// Follow redirects
await Curl.GetAsync("https://bit.ly/shortened")
    .FollowRedirects(maxRedirects: 5)
    .ExecuteAsync();

// Cookie management
var cookieJar = new CookieContainer();
await Curl.GetAsync("https://example.com")
    .WithCookieContainer(cookieJar)
    .ExecuteAsync();

πŸ“Š Performance & Reliability

  • βœ… 244 Unit Tests - 100% pass rate
  • βœ… Self-Contained Testing - No external dependencies
  • βœ… Cross-Platform CI/CD - Windows, Linux, macOS
  • βœ… Production Ready - Used in enterprise applications

πŸ—οΈ Platform Support

Platform Version Support
.NET 10, 9, 8, 7, 6, 5 βœ… Full Support
.NET Core 3.1, 3.0, 2.1 βœ… Full Support
.NET Framework 4.8 βœ… Native (Windows, Mac, Linux via Mono)
.NET Framework 4.7.2+ βœ… via .NET Standard 2.0
.NET Standard 2.0+ βœ… Maximum Compatibility
Windows 10, 11, Server 2016+ βœ… Native
Linux Ubuntu, Debian, RHEL, Alpine βœ… Native
macOS 10.14+, Apple Silicon βœ… Native
iOS 12+ βœ… via .NET Standard/MAUI
Android API 21+ βœ… via .NET Standard/MAUI
IoT Raspberry Pi, Arduino βœ… via .NET IoT
Docker All Linux images βœ… Full Support
Azure App Service, Functions, Container Instances βœ… Cloud Native
AWS Lambda, ECS, Fargate βœ… Cloud Native

πŸ“– Documentation

πŸ’‘ Use Cases

REST API Integration

// GitHub API example
var repos = await Curl.GetJsonAsync<List<Repository>>(
    "https://api.github.com/users/octocat/repos"
);

Web Scraping

// Scrape with proper headers
var html = await Curl.GetAsync("https://example.com")
    .WithUserAgent("Mozilla/5.0 (Windows NT 10.0; Win64; x64)")
    .WithHeader("Accept-Language", "en-US")
    .ExecuteAsync();

Microservices Communication

// Service-to-service with retry
var response = await Curl.PostAsync("http://service-b/api/process")
    .WithJson(requestData)
    .WithRetry(3)
    .WithTimeout(TimeSpan.FromSeconds(5))
    .ExecuteAsync();

CI/CD Automation

// Deploy webhook
await Curl.PostAsync("https://deploy.example.com/webhook")
    .WithJson(new {
        version = "1.2.3",
        environment = "production"
    })
    .WithBearerToken(deployToken)
    .ExecuteAsync();

πŸ”§ Advanced Usage

Custom Middleware

// Add custom middleware for logging, caching, etc.
var result = await Curl.GetAsync("https://api.example.com")
    .UseMiddleware(async (context, next) => {
        Console.WriteLine($"Request: {context.Request.Url}");
        var response = await next();
        Console.WriteLine($"Response: {response.StatusCode}");
        return response;
    })
    .ExecuteAsync();

Code Generation

// Convert curl to other languages
var pythonCode = Curl.ToPythonRequests("curl -X GET https://api.example.com");
var jsCode = Curl.ToJavaScriptFetch("curl -X POST https://api.example.com -d '{}'");
var httpClientCode = Curl.ToHttpClient("curl https://api.example.com");

Debugging

// Enable verbose output like curl -v
var result = await Curl.GetAsync("https://api.example.com")
    .Verbose(true)
    .ExecuteAsync();

// Access detailed timing information
Console.WriteLine($"DNS Lookup: {result.Timings.DnsLookup}ms");
Console.WriteLine($"Connect: {result.Timings.Connect}ms");
Console.WriteLine($"TLS Handshake: {result.Timings.TlsHandshake}ms");
Console.WriteLine($"First Byte: {result.Timings.FirstByte}ms");
Console.WriteLine($"Total: {result.Timings.Total}ms");

Code Generation

CurlDotNet can transpile curl commands into code for other languages. This is perfect for building developer tools or converting documentation examples.

// Convert curl to PowerShell
var powershellCode = Curl.ToPowershellCode("curl -X POST https://api.example.com -d 'data'");

// Convert curl to Python Requests
var pythonCode = Curl.ToPythonCode("curl -X POST https://api.example.com -d 'data'");

// Convert curl to JavaScript Fetch
var jsCode = Curl.ToFetchCode("curl -X POST https://api.example.com -d 'data'");

// Convert curl to C# HttpClient
var csharpCode = Curl.ToHttpClientCode("curl -X POST https://api.example.com -d 'data'");

❓ Troubleshooting

SSL/TLS Issues

If you encounter SSL errors (e.g., self-signed certificates), you can disable verification for development:

// Global setting (affects all requests)
Curl.DefaultInsecure = true;

// Per-request setting
await Curl.Execute("curl -k https://self-signed.local");

Timeouts

If requests are timing out, increase the timeout settings:

// Set global timeout to 60 seconds
Curl.DefaultMaxTimeSeconds = 60;

// Or per request
await Curl.Execute("curl --max-time 60 https://slow-api.example.com");

Proxy Authentication

If your proxy requires authentication:

await Curl.Execute("curl -x http://user:[email protected]:8080 https://api.example.com");

🀝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

# Clone the repository
git clone https://github.com/jacob-mellor/curl-dot-net.git

# Build the project
dotnet build

# Run tests
dotnet test

# Run with coverage
dotnet test /p:CollectCoverage=true

πŸ“Š Examples

Comprehensive examples are available in the examples directory:

πŸ“„ License

CurlDotNet is MIT licensed. See LICENSE for details.

🌟 Why Developers Choose CurlDotNet

"Finally, I can just paste curl commands from API docs!" - Senior Developer

"The proxy support is fantastic for our web scraping needs." - Data Engineer

"Migrating from HttpClient saved us hundreds of lines of code." - Tech Lead

"The retry logic and rate limiting just work." - DevOps Engineer

🚦 Getting Started

  1. Install the package: dotnet add package CurlDotNet
  2. Add using: using CurlDotNet;
  3. Make your first request: await Curl.GetAsync("https://api.example.com");

That's it! You're now using the power of curl in C# and .NET.

πŸ†˜ Support

πŸ“Ž Additional Resources

πŸ“– Our Story

Read about how CurlDotNet is bringing curl superpowers to every corner of the .NET 10 & C# stack: πŸ“° Featured Article: CurlDotNet - Bringing curl Superpowers to Every Corner of the .NET 10 & C# Stack

🌐 Part of UserLand.NET

CurlDotNet is part of the UserLand.NET initiative - bringing Unix/Linux tools to .NET through pure C# implementations.


Keywords: curl C#, curl .NET, C# HTTP client, .NET curl, REST API C#, HTTP requests .NET, web scraping C#, proxy C#, curl for Windows, curl alternative, HttpClient alternative

Author: Jacob Mellor | Sponsored by IronSoftware.com

About

A .NET library for transferring data with URL syntax, supporting DICT, FILE, FTP, FTPS, GOPHER, GOPHERS, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, POP3, POP3S, RTMP, RTMPS, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, TELNET, TFTP, WS and WSS. libcurl offers a myriad of powerful features

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Languages

  • C# 98.3%
  • Shell 1.3%
  • Other 0.4%