+### Example .http file:
+
+```http
+@baseUrl = https://api.example.com
+@token = your-jwt-token
-## Docker
+###
-There's a docker image(weihanli/dotnet-httpie) that you could use directly without installing the tool, use sample:
+# @name getUsers
+GET {{baseUrl}}/users
+Authorization: Bearer {{token}}
-``` bash
-docker run --rm --pull=always weihanli/dotnet-httpie:latest -v github.com
+###
-docker run --rm --pull=always weihanli/dotnet-httpie:latest reservation.weihanli.xyz/health job:='{"id":1,"name":"tester"}' --offline
+# @name createUser
+POST {{baseUrl}}/users
+Authorization: Bearer {{token}}
+Content-Type: application/json
-docker run --rm --pull=always weihanli/dotnet-httpie:latest PUT httpbin.org hello=world
+{
+ "name": "John Doe",
+ "email": "john@example.com"
+}
-docker run --rm --pull=always weihanli/dotnet-httpie:latest get httpbin.org/status/400
+###
+
+# Reference previous response
+GET {{baseUrl}}/users/{{createUser.response.body.id}}
+Authorization: Bearer {{token}}
```
-## More
+### Environment Support
+
+Create `http-client.env.json`:
+
+```json
+{
+ "development": {
+ "baseUrl": "http://localhost:3000",
+ "token": "dev-token"
+ },
+ "production": {
+ "baseUrl": "https://api.example.com",
+ "token": "prod-token"
+ }
+}
+```
+
+## 🐳 Docker
+
+Use dotnet-httpie without installing .NET:
+
+```bash
+# Basic usage
+docker run --rm weihanli/dotnet-httpie:latest httpbin.org/get
+
+# POST with data
+docker run --rm weihanli/dotnet-httpie:latest POST httpbin.org/post name=test
+
+# Execute HTTP files
+docker run --rm -v $(pwd):/workspace -w /workspace \
+ weihanli/dotnet-httpie:latest exec requests.http
+
+# With environment variables
+docker run --rm -e API_TOKEN="your-token" \
+ weihanli/dotnet-httpie:latest GET api.example.com/protected \
+ Authorization:"Bearer $API_TOKEN"
+```
+
+### Create an alias for easier usage:
+
+```bash
+# Add to your shell profile (.bashrc, .zshrc, etc.)
+alias http='docker run --rm weihanli/dotnet-httpie:latest'
+
+# Now use it like the installed version
+http GET httpbin.org/get
+http POST httpbin.org/post name=John
+```
+
+## 🔧 Advanced Features
+
+### Authentication
+- **JWT Tokens**: `Authorization:"Bearer token"`
+- **API Keys**: `X-API-Key:"key"` or `api_key==key`
+- **Basic Auth**: `--auth username:password` or `Authorization:"Basic base64"`
+
+### File Operations
+- **Form data**: `--form field=value`
+- **Download**: `--download` flag
+- **Send raw data**: `--raw "data"`
+
+### Request Features
+- **Query parameters**: `param==value`
+- **Custom headers**: `Header-Name:"value"`
+- **JSON data**: `field=value` or `field:=rawjson`
+- **Form data**: `--form` flag
+- **Raw data**: `--raw "data"`
+
+### Execution Modes
+- **Offline mode**: `--offline` (preview requests)
+- **Debug mode**: `--debug` (detailed logging)
+- **Environment**: `--env production`
+
+### Response Handling
+- **Body only**: `--body` flag
+- **Follow redirects**: `--follow`
+- **JSON processing**: Pipe to `jq` for advanced processing
+
+## 🚀 Use Cases
+
+- **API Development**: Test endpoints during development
+- **API Documentation**: Executable examples in documentation
+- **CI/CD Testing**: Automated API testing in pipelines
+- **Load Testing**: Built-in load testing capabilities
+- **Integration Testing**: Test service-to-service communication
+- **Debugging**: Inspect HTTP requests and responses
+- **Scripting**: Automate API interactions in shell scripts
+
+## 🤝 Contributing
+
+We welcome contributions! Here's how you can help:
+
+1. **Report Issues**: Found a bug? [Open an issue](https://github.com/WeihanLi/dotnet-httpie/issues)
+2. **Feature Requests**: Have an idea? [Open an issue](https://github.com/WeihanLi/dotnet-httpie/issues)
+3. **Documentation**: Help improve the docs
+4. **Code**: Submit pull requests for bug fixes or features
+
+### Development Setup
+
+```bash
+# Clone the repository
+git clone https://github.com/WeihanLi/dotnet-httpie.git
+cd dotnet-httpie
+
+# Build the project
+dotnet build
+
+# Run tests
+dotnet test
+
+# Install locally for testing
+dotnet pack
+dotnet tool install --global --add-source ./artifacts dotnet-httpie
+```
+
+## 📚 Resources
+
+- **📖 [Complete Documentation](docs/articles/README.md)** - Comprehensive guides and tutorials
+- **🎯 [Examples](docs/articles/examples/common-use-cases.md)** - Real-world usage patterns
+- **🐳 [Docker Guide](docs/articles/docker-usage.md)** - Containerized usage
+- **📄 [Release Notes](docs/ReleaseNotes.md)** - What's new in each version
+- **💬 [Issues](https://github.com/WeihanLi/dotnet-httpie/issues)** - Community Q&A, bug reports, and feature requests
+
+## 🙏 Acknowledgments
+
+- Inspired by the amazing [HTTPie](https://github.com/httpie/httpie) project
+- Built with ❤️ for the .NET community
+- Special thanks to all [contributors](https://github.com/WeihanLi/dotnet-httpie/contributors)
+
+## 📄 License
+
+This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
+
+---
+
+
-For detailed document: have a look at HTTPie documents
+**⭐ Star this repository if you find it useful!**
-## References
+[🏠 Homepage](https://github.com/WeihanLi/dotnet-httpie) •
+[📖 Documentation](docs/articles/README.md) •
+[🐳 Docker Hub](https://hub.docker.com/r/weihanli/dotnet-httpie) •
+[📦 NuGet](https://www.nuget.org/packages/dotnet-httpie/)
-- httpie:
-- httpie docs:
-- Curl to HTTPie request tool:
+
diff --git a/build.sh b/build.sh
old mode 100644
new mode 100755
diff --git a/build/version.props b/build/version.props
index 7d03ce9..f51b368 100644
--- a/build/version.props
+++ b/build/version.props
@@ -1,7 +1,7 @@
0
- 14
+ 15
0
$(VersionMajor).$(VersionMinor).$(VersionPatch)
$(PackageVersion)
diff --git a/docs/articles/README.md b/docs/articles/README.md
new file mode 100644
index 0000000..ca94486
--- /dev/null
+++ b/docs/articles/README.md
@@ -0,0 +1,62 @@
+# dotnet-httpie Documentation
+
+Welcome to the comprehensive documentation for dotnet-httpie, a modern command-line HTTP client for .NET developers.
+
+## Table of Contents
+
+### Getting Started
+- [Installation](installation.md)
+- [Quick Start Guide](quick-start.md)
+- [Basic Usage](basic-usage.md)
+
+### Core Features
+- [Making HTTP Requests](http-requests.md)
+- [Request Data Types](request-data-types.md)
+- [Authentication](authentication.md)
+- [File Operations](file-operations.md)
+
+### Advanced Features
+- [Executing .http/.rest Files](file-execution.md)
+- [Curl Command Execution](curl-execution.md)
+- [Variable Substitution](variables.md)
+- [Request Referencing](request-referencing.md)
+- [JSON Schema Validation](json-schema-validation.md)
+- [Request Caching](request-caching.md)
+- [Load Testing](load-testing.md)
+
+### Configuration
+- [Proxy Configuration](proxy-configuration.md)
+- [SSL/TLS Configuration](ssl-configuration.md)
+- [Environment Variables](environment-variables.md)
+
+### Docker & Deployment
+- [Docker Usage](docker-usage.md)
+- [CI/CD Integration](ci-cd-integration.md)
+
+### Advanced Topics
+- [Middleware System](middleware-system.md)
+- [Debugging & Troubleshooting](debugging.md)
+- [Performance Tips](performance-tips.md)
+
+### Examples & Recipes
+- [Common Use Cases](examples/common-use-cases.md)
+- [API Testing Scenarios](examples/api-testing.md)
+- [Integration Examples](examples/integrations.md)
+
+### Reference
+- [Command Line Options](reference/command-line-options.md)
+- [Configuration Reference](reference/configuration.md)
+- [Error Codes](reference/error-codes.md)
+
+## Quick Links
+
+- [GitHub Repository](https://github.com/WeihanLi/dotnet-httpie)
+- [NuGet Package](https://www.nuget.org/packages/dotnet-httpie/)
+- [Release Notes](../ReleaseNotes.md)
+- [Contributing Guidelines](../../CONTRIBUTING.md)
+
+## Need Help?
+
+- Check the [troubleshooting guide](debugging.md)
+- Review [common examples](examples/common-use-cases.md)
+- Visit our [GitHub Issues](https://github.com/WeihanLi/dotnet-httpie/issues) page
\ No newline at end of file
diff --git a/docs/articles/authentication.md b/docs/articles/authentication.md
new file mode 100644
index 0000000..92aaaa9
--- /dev/null
+++ b/docs/articles/authentication.md
@@ -0,0 +1,506 @@
+# Authentication
+
+This guide covers various authentication methods supported by dotnet-httpie for securing your API requests.
+
+## Overview
+
+dotnet-httpie supports all common authentication methods used in modern APIs:
+
+- Bearer Token (JWT)
+- API Key Authentication
+- Basic Authentication
+- Custom Header Authentication
+- OAuth 2.0 flows
+- Cookie-based Authentication
+
+## Bearer Token Authentication
+
+Most commonly used for JWT tokens in modern APIs.
+
+### Header-based Bearer Token
+
+```bash
+# Standard Bearer token
+dotnet-http GET api.example.com/protected \
+ Authorization:"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
+
+# Environment variable token
+dotnet-http GET api.example.com/protected \
+ Authorization:"Bearer $JWT_TOKEN"
+```
+
+### Getting JWT Tokens
+
+```bash
+# Login to get JWT token
+LOGIN_RESPONSE=$(dotnet-http POST api.example.com/auth/login \
+ username="admin" \
+ password="password" \
+ --body)
+
+# Extract token using jq
+TOKEN=$(echo $LOGIN_RESPONSE | jq -r '.access_token')
+
+# Use token for protected requests
+dotnet-http GET api.example.com/users \
+ Authorization:"Bearer $TOKEN"
+```
+
+### Refresh Token Flow
+
+```bash
+# Use refresh token to get new access token
+REFRESH_RESPONSE=$(dotnet-http POST api.example.com/auth/refresh \
+ refresh_token="$REFRESH_TOKEN" \
+ --body)
+
+NEW_TOKEN=$(echo $REFRESH_RESPONSE | jq -r '.access_token')
+
+# Use new token
+dotnet-http GET api.example.com/protected \
+ Authorization:"Bearer $NEW_TOKEN"
+```
+
+## API Key Authentication
+
+Common in REST APIs for service-to-service communication.
+
+### Header-based API Keys
+
+```bash
+# Standard API key header
+dotnet-http GET api.example.com/data \
+ X-API-Key:"your-api-key-here"
+
+# Custom header names
+dotnet-http GET api.example.com/data \
+ X-RapidAPI-Key:"your-rapidapi-key" \
+ X-RapidAPI-Host:"api.example.com"
+
+# Multiple API keys
+dotnet-http GET api.example.com/data \
+ X-API-Key:"primary-key" \
+ X-Secondary-Key:"secondary-key"
+```
+
+### Query Parameter API Keys
+
+```bash
+# API key as query parameter
+dotnet-http GET api.example.com/data \
+ api_key==your-api-key
+
+# Multiple parameters
+dotnet-http GET api.example.com/data \
+ key==your-api-key \
+ format==json \
+ version==v2
+```
+
+### Environment-based API Keys
+
+```bash
+# Store API key in environment variable
+export API_KEY="your-secret-api-key"
+
+# Use in requests
+dotnet-http GET api.example.com/data \
+ X-API-Key:"$API_KEY"
+```
+
+## Basic Authentication
+
+Traditional username/password authentication.
+
+### Manual Basic Auth
+
+```bash
+# Encode credentials manually
+CREDENTIALS=$(echo -n 'username:password' | base64)
+dotnet-http GET api.example.com/secure \
+ Authorization:"Basic $CREDENTIALS"
+
+# Direct encoding
+dotnet-http GET api.example.com/secure \
+ Authorization:"Basic $(echo -n 'admin:secret123' | base64)"
+```
+
+### HTTPie-style Basic Auth
+
+```bash
+# Using --auth flag (username:password format)
+dotnet-http GET api.example.com/secure \
+ --auth username:password
+
+# With explicit auth type
+dotnet-http GET api.example.com/secure \
+ --auth-type Basic --auth username:password
+```
+
+## OAuth 2.0 Flows
+
+### Client Credentials Flow
+
+```bash
+# Get access token
+TOKEN_RESPONSE=$(dotnet-http POST oauth.provider.com/token \
+ grant_type="client_credentials" \
+ client_id="your-client-id" \
+ client_secret="your-client-secret" \
+ scope="read write" \
+ --body)
+
+ACCESS_TOKEN=$(echo $TOKEN_RESPONSE | jq -r '.access_token')
+
+# Use access token
+dotnet-http GET api.example.com/protected \
+ Authorization:"Bearer $ACCESS_TOKEN"
+```
+
+### Authorization Code Flow (Manual)
+
+```bash
+# Step 1: Get authorization code (manual browser step)
+echo "Visit: https://oauth.provider.com/authorize?client_id=your-client-id&response_type=code&redirect_uri=http://localhost:8080/callback&scope=read"
+
+# Step 2: Exchange code for token
+TOKEN_RESPONSE=$(dotnet-http POST oauth.provider.com/token \
+ grant_type="authorization_code" \
+ client_id="your-client-id" \
+ client_secret="your-client-secret" \
+ code="authorization-code-from-callback" \
+ redirect_uri="http://localhost:8080/callback" \
+ --body)
+
+ACCESS_TOKEN=$(echo $TOKEN_RESPONSE | jq -r '.access_token')
+```
+
+### Resource Owner Password Credentials
+
+```bash
+# Direct username/password exchange (less secure)
+TOKEN_RESPONSE=$(dotnet-http POST oauth.provider.com/token \
+ grant_type="password" \
+ username="user@example.com" \
+ password="user-password" \
+ client_id="your-client-id" \
+ client_secret="your-client-secret" \
+ --body)
+
+ACCESS_TOKEN=$(echo $TOKEN_RESPONSE | jq -r '.access_token')
+```
+
+## Custom Authentication Schemes
+
+### Signature-based Authentication
+
+```bash
+# AWS-style signature
+SIGNATURE=$(echo -n "GET\n/api/data\n$(date -u)" | openssl dgst -sha256 -hmac "$SECRET_KEY" -binary | base64)
+
+dotnet-http GET api.example.com/data \
+ Authorization:"AWS4-HMAC-SHA256 Credential=$ACCESS_KEY/$(date -u +%Y%m%d)/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=$SIGNATURE" \
+ X-Amz-Date:"$(date -u +%Y%m%dT%H%M%SZ)"
+```
+
+### HMAC Authentication
+
+```bash
+# Generate HMAC signature
+TIMESTAMP=$(date +%s)
+PAYLOAD="GET/api/data$TIMESTAMP"
+SIGNATURE=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "$SECRET_KEY" -binary | base64)
+
+dotnet-http GET api.example.com/data \
+ X-API-Key:"$API_KEY" \
+ X-Timestamp:"$TIMESTAMP" \
+ X-Signature:"$SIGNATURE"
+```
+
+### Digest Authentication
+
+```bash
+# Simple digest implementation (for demonstration)
+NONCE=$(openssl rand -hex 16)
+HASH=$(echo -n "username:realm:password" | md5sum | cut -d' ' -f1)
+RESPONSE=$(echo -n "$HASH:$NONCE:GET:/api/data" | md5sum | cut -d' ' -f1)
+
+dotnet-http GET api.example.com/data \
+ Authorization:"Digest username=\"username\", realm=\"realm\", nonce=\"$NONCE\", uri=\"/api/data\", response=\"$RESPONSE\""
+```
+
+## Cookie-based Authentication
+
+### Session Cookies
+
+```bash
+# Login and save cookies
+dotnet-http POST api.example.com/login \
+ username="admin" \
+ password="password" \
+ --session=api-session
+
+# Use saved session for subsequent requests
+dotnet-http GET api.example.com/protected \
+ --session=api-session
+```
+
+### Manual Cookie Handling
+
+```bash
+# Set cookies manually
+dotnet-http GET api.example.com/protected \
+ Cookie:"sessionid=abc123; csrftoken=xyz789"
+
+# Multiple cookies
+dotnet-http GET api.example.com/protected \
+ Cookie:"auth_token=token123; user_pref=dark_mode; lang=en"
+```
+
+## Multi-factor Authentication
+
+### TOTP (Time-based One-time Password)
+
+```bash
+# Generate TOTP code (using external tool)
+TOTP_CODE=$(oathtool --totp --base32 "$TOTP_SECRET")
+
+# Include in request
+dotnet-http POST api.example.com/sensitive-action \
+ Authorization:"Bearer $TOKEN" \
+ X-TOTP-Code:"$TOTP_CODE" \
+ action="transfer" \
+ amount:=1000
+```
+
+### SMS/Email Verification
+
+```bash
+# Request verification code
+dotnet-http POST api.example.com/request-verification \
+ Authorization:"Bearer $TOKEN" \
+ phone="+1-555-0123"
+
+# Submit verification code
+dotnet-http POST api.example.com/verify \
+ Authorization:"Bearer $TOKEN" \
+ verification_code="123456" \
+ action="sensitive-operation"
+```
+
+## Authentication in HTTP Files
+
+### Environment Variables
+
+```http
+# auth-example.http
+@baseUrl = https://api.example.com
+@token = {{$env JWT_TOKEN}}
+@apiKey = {{$env API_KEY}}
+
+###
+
+# Bearer token from environment
+GET {{baseUrl}}/protected
+Authorization: Bearer {{token}}
+
+###
+
+# API key from environment
+GET {{baseUrl}}/data
+X-API-Key: {{apiKey}}
+```
+
+### Login Flow in HTTP Files
+
+```http
+# complete-auth-flow.http
+@baseUrl = https://api.example.com
+
+###
+
+# @name login
+POST {{baseUrl}}/auth/login
+Content-Type: application/json
+
+{
+ "username": "admin",
+ "password": "password"
+}
+
+###
+
+# @name getProfile
+GET {{baseUrl}}/profile
+Authorization: Bearer {{login.response.body.access_token}}
+
+###
+
+# @name updateProfile
+PUT {{baseUrl}}/profile
+Authorization: Bearer {{login.response.body.access_token}}
+Content-Type: application/json
+
+{
+ "name": "Updated Name",
+ "email": "new@example.com"
+}
+```
+
+## Security Best Practices
+
+### Environment Variables
+
+```bash
+# Never hardcode secrets in commands or files
+# Use environment variables instead
+
+# Bad
+dotnet-http GET api.example.com/data X-API-Key:"secret-key-123"
+
+# Good
+export API_KEY="secret-key-123"
+dotnet-http GET api.example.com/data X-API-Key:"$API_KEY"
+```
+
+### Secure Storage
+
+```bash
+# Use secure credential storage
+# Example with macOS Keychain
+security add-internet-password -s "api.example.com" -a "myapp" -w "secret-api-key"
+API_KEY=$(security find-internet-password -s "api.example.com" -a "myapp" -w)
+
+dotnet-http GET api.example.com/data X-API-Key:"$API_KEY"
+```
+
+### Token Rotation
+
+```bash
+#!/bin/bash
+# token-rotation.sh
+
+# Check if token is expired
+if ! dotnet-http GET api.example.com/verify Authorization:"Bearer $ACCESS_TOKEN" >/dev/null 2>&1; then
+ echo "Token expired, refreshing..."
+
+ # Refresh token
+ NEW_TOKEN_RESPONSE=$(dotnet-http POST api.example.com/auth/refresh \
+ refresh_token="$REFRESH_TOKEN" --body)
+
+ ACCESS_TOKEN=$(echo $NEW_TOKEN_RESPONSE | jq -r '.access_token')
+ export ACCESS_TOKEN
+
+ echo "Token refreshed successfully"
+fi
+
+# Use current token
+dotnet-http GET api.example.com/protected Authorization:"Bearer $ACCESS_TOKEN"
+```
+
+## Platform-Specific Examples
+
+### GitHub API
+
+```bash
+# Personal access token
+dotnet-http GET api.github.com/user \
+ Authorization:"token $GITHUB_TOKEN"
+
+# Create repository
+dotnet-http POST api.github.com/user/repos \
+ Authorization:"token $GITHUB_TOKEN" \
+ name="new-repo" \
+ description="Created via dotnet-httpie"
+```
+
+### AWS API
+
+```bash
+# AWS Signature Version 4 (simplified)
+AWS_ACCESS_KEY="your-access-key"
+AWS_SECRET_KEY="your-secret-key"
+AWS_REGION="us-east-1"
+SERVICE="s3"
+
+# Note: Full AWS sig v4 implementation would be more complex
+dotnet-http GET s3.amazonaws.com/bucket-name \
+ Authorization:"AWS4-HMAC-SHA256 ..." \
+ X-Amz-Date:"$(date -u +%Y%m%dT%H%M%SZ)"
+```
+
+### Google APIs
+
+```bash
+# OAuth 2.0 with Google
+# First, get OAuth token through browser flow
+# Then use the access token
+
+dotnet-http GET www.googleapis.com/oauth2/v1/userinfo \
+ Authorization:"Bearer $GOOGLE_ACCESS_TOKEN"
+
+# Service account authentication (with JWT)
+dotnet-http GET www.googleapis.com/storage/v1/b \
+ Authorization:"Bearer $SERVICE_ACCOUNT_JWT"
+```
+
+## Testing Authentication
+
+### Verify Token Validity
+
+```bash
+# Test if token is valid
+if dotnet-http GET api.example.com/verify Authorization:"Bearer $TOKEN" --check-status; then
+ echo "Token is valid"
+else
+ echo "Token is invalid or expired"
+fi
+```
+
+### Authentication Debugging
+
+```bash
+# Debug authentication issues
+dotnet-http GET api.example.com/protected \
+ Authorization:"Bearer $TOKEN" \
+ --debug \
+ --offline # Preview the request first
+```
+
+### Automated Authentication Testing
+
+```bash
+#!/bin/bash
+# auth-test.sh
+
+# Test various authentication methods
+echo "Testing authentication methods..."
+
+# Test API key
+if dotnet-http GET api.example.com/test X-API-Key:"$API_KEY" --check-status; then
+ echo "✓ API Key authentication works"
+else
+ echo "✗ API Key authentication failed"
+fi
+
+# Test JWT token
+if dotnet-http GET api.example.com/test Authorization:"Bearer $JWT_TOKEN" --check-status; then
+ echo "✓ JWT authentication works"
+else
+ echo "✗ JWT authentication failed"
+fi
+
+# Test basic auth
+if dotnet-http GET api.example.com/test Authorization:"Basic $BASIC_AUTH" --check-status; then
+ echo "✓ Basic authentication works"
+else
+ echo "✗ Basic authentication failed"
+fi
+```
+
+## Next Steps
+
+- Learn about [request data types](request-data-types.md) for sending authenticated requests
+- Explore [file execution](file-execution.md) for managing authentication in HTTP files
+- Check out [environment variables](environment-variables.md) for secure credential management
+- Review [examples](examples/common-use-cases.md) for real-world authentication patterns
\ No newline at end of file
diff --git a/docs/articles/basic-usage.md b/docs/articles/basic-usage.md
new file mode 100644
index 0000000..9fd28b4
--- /dev/null
+++ b/docs/articles/basic-usage.md
@@ -0,0 +1,500 @@
+# Basic Usage
+
+This guide covers the fundamental concepts and basic usage patterns of dotnet-httpie.
+
+## Command Structure
+
+The basic syntax for dotnet-httpie commands:
+
+```
+dotnet-http [flags] [METHOD] URL [ITEM [ITEM]]
+```
+
+### Components
+
+- **flags**: Optional command flags (e.g., `--offline`, `--debug`, `--body`)
+- **METHOD**: HTTP method (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS)
+- **URL**: Target URL (can be full URL or shortened format)
+- **ITEM**: Request items (query parameters, headers, data)
+
+## HTTP Methods
+
+### GET (Default)
+
+```bash
+# Simple GET request
+dotnet-http httpbin.org/get
+
+# GET with query parameters
+dotnet-http httpbin.org/get name==John age==30
+
+# Explicit GET method
+dotnet-http GET httpbin.org/get search==query
+```
+
+### POST
+
+```bash
+# POST with JSON data
+dotnet-http POST httpbin.org/post name=John email=john@example.com
+
+# POST with form data
+dotnet-http POST httpbin.org/post --form name=John email=john@example.com
+```
+
+### PUT
+
+```bash
+# PUT request (typically for updates)
+dotnet-http PUT httpbin.org/put id:=123 name=John
+```
+
+### DELETE
+
+```bash
+# DELETE request
+dotnet-http DELETE httpbin.org/delete
+
+# DELETE with parameters
+dotnet-http DELETE api.example.com/users/123
+```
+
+### Other Methods
+
+```bash
+# PATCH for partial updates
+dotnet-http PATCH httpbin.org/patch status=active
+
+# HEAD for headers only
+dotnet-http HEAD httpbin.org/get
+
+# OPTIONS for allowed methods
+dotnet-http OPTIONS httpbin.org
+```
+
+## URL Formats
+
+### Full URLs
+
+```bash
+# HTTPS URLs
+dotnet-http https://api.example.com/users
+
+# HTTP URLs
+dotnet-http http://localhost:3000/api/data
+
+# URLs with ports
+dotnet-http https://api.example.com:8443/secure
+```
+
+### Shortened URLs
+
+```bash
+# Localhost shortcuts
+dotnet-http :3000/api/users # → http://localhost:3000/api/users
+dotnet-http localhost:5000/health # → http://localhost:5000/health
+
+# HTTPS by default for domains
+dotnet-http api.example.com/data # → https://api.example.com/data
+```
+
+### URL with Paths
+
+```bash
+# Simple paths
+dotnet-http api.example.com/v1/users
+
+# Complex paths with parameters
+dotnet-http api.example.com/users/123/posts/456
+
+# Paths with special characters
+dotnet-http "api.example.com/search?q=hello world"
+```
+
+## Request Items
+
+### Query Parameters (`==`)
+
+Query parameters are added to the URL:
+
+```bash
+# Single parameter
+dotnet-http httpbin.org/get name==John
+
+# Multiple parameters
+dotnet-http httpbin.org/get name==John age==30 city=="New York"
+
+# Arrays/multiple values
+dotnet-http httpbin.org/get tag==javascript tag==web tag==api
+```
+
+### Headers (`:`)
+
+Headers control request behavior:
+
+```bash
+# Authentication header
+dotnet-http httpbin.org/headers Authorization:"Bearer token123"
+
+# Content type
+dotnet-http POST httpbin.org/post Content-Type:"application/xml"
+
+# Multiple headers
+dotnet-http httpbin.org/headers \
+ Authorization:"Bearer token" \
+ User-Agent:"MyApp/1.0" \
+ Accept:"application/json"
+```
+
+### JSON Data (`=`)
+
+Creates JSON request body:
+
+```bash
+# Simple fields
+dotnet-http POST httpbin.org/post name=John age=30
+
+# Creates: {"name": "John", "age": "30"}
+```
+
+### Raw JSON Data (`:=`)
+
+For typed JSON values:
+
+```bash
+# Numbers
+dotnet-http POST httpbin.org/post age:=30 price:=19.99
+
+# Booleans
+dotnet-http POST httpbin.org/post active:=true published:=false
+
+# Arrays
+dotnet-http POST httpbin.org/post tags:='["web", "api", "tool"]'
+
+# Objects
+dotnet-http POST httpbin.org/post profile:='{"name": "John", "level": 5}'
+
+# Creates: {"age": 30, "price": 19.99, "active": true, "published": false, "tags": ["web", "api", "tool"], "profile": {"name": "John", "level": 5}}
+```
+
+## Common Patterns
+
+### API Testing
+
+```bash
+# Health check
+dotnet-http GET api.example.com/health
+
+# Get list of resources
+dotnet-http GET api.example.com/users
+
+# Get specific resource
+dotnet-http GET api.example.com/users/123
+
+# Create new resource
+dotnet-http POST api.example.com/users name=John email=john@example.com
+
+# Update resource
+dotnet-http PUT api.example.com/users/123 name="John Smith"
+
+# Delete resource
+dotnet-http DELETE api.example.com/users/123
+```
+
+### Authentication Patterns
+
+```bash
+# Bearer token
+dotnet-http GET api.example.com/protected \
+ Authorization:"Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
+
+# API key in header
+dotnet-http GET api.example.com/data \
+ X-API-Key:"your-api-key"
+
+# API key in query
+dotnet-http GET api.example.com/data \
+ api_key==your-api-key
+
+# Basic authentication
+dotnet-http GET api.example.com/secure \
+ Authorization:"Basic $(echo -n 'user:pass' | base64)"
+```
+
+### Data Submission Patterns
+
+```bash
+# Simple form data
+dotnet-http POST api.example.com/contact \
+ name=John \
+ email=john@example.com \
+ message="Hello from dotnet-httpie"
+
+# Complex nested data
+dotnet-http POST api.example.com/orders \
+ customer[name]=John \
+ customer[email]=john@example.com \
+ items[0][id]:=1 \
+ items[0][quantity]:=2 \
+ items[1][id]:=2 \
+ items[1][quantity]:=1 \
+ total:=99.99
+
+# File upload
+dotnet-http POST api.example.com/upload \
+ --multipart \
+ description="My document" \
+ file@/path/to/document.pdf
+```
+
+## Response Handling
+
+### Default Response
+
+Shows headers and body:
+
+```bash
+dotnet-http GET httpbin.org/get
+```
+
+### Body Only
+
+```bash
+# Only response body
+dotnet-http GET httpbin.org/get --body
+
+# Useful for piping to other tools
+dotnet-http GET api.example.com/users --body | jq '.users[0]'
+```
+
+### Headers Only
+
+```bash
+# Only response headers
+dotnet-http HEAD httpbin.org/get
+```
+
+### Save Response
+
+```bash
+# Save to file
+dotnet-http GET api.example.com/report --body > report.json
+
+# Download files
+dotnet-http GET api.example.com/files/document.pdf --download
+```
+
+## Useful Flags
+
+### Debug Mode
+
+Get detailed information about the request:
+
+```bash
+dotnet-http GET api.example.com/data --debug
+```
+
+### Offline Mode
+
+Preview the request without sending it:
+
+```bash
+dotnet-http POST api.example.com/users name=John --offline
+```
+
+### Check Status
+
+Exit with non-zero code for HTTP errors:
+
+```bash
+if dotnet-http GET api.example.com/health --check-status; then
+ echo "API is healthy"
+else
+ echo "API is down"
+fi
+```
+
+## Working with JSON
+
+### Simple JSON
+
+```bash
+# String values (default)
+dotnet-http POST httpbin.org/post name=John title="Software Engineer"
+
+# Number values
+dotnet-http POST httpbin.org/post age:=30 salary:=75000
+
+# Boolean values
+dotnet-http POST httpbin.org/post active:=true verified:=false
+
+# Null values
+dotnet-http POST httpbin.org/post middle_name:=null
+```
+
+### Complex JSON
+
+```bash
+# Arrays
+dotnet-http POST httpbin.org/post \
+ skills:='["C#", "JavaScript", "Python"]' \
+ scores:='[95, 87, 92]'
+
+# Nested objects
+dotnet-http POST httpbin.org/post \
+ address:='{"street": "123 Main St", "city": "Seattle", "zip": "98101"}' \
+ contact:='{"email": "john@example.com", "phone": "+1-555-0123"}'
+
+# Mixed complex data
+dotnet-http POST httpbin.org/post \
+ name=John \
+ age:=30 \
+ active:=true \
+ skills:='["programming", "testing"]' \
+ address:='{"city": "Seattle", "state": "WA"}' \
+ metadata:=null
+```
+
+## Error Handling
+
+### HTTP Status Codes
+
+```bash
+# dotnet-httpie shows HTTP errors clearly
+dotnet-http GET httpbin.org/status/404 # Shows 404 Not Found
+dotnet-http GET httpbin.org/status/500 # Shows 500 Internal Server Error
+```
+
+### Debugging Errors
+
+```bash
+# Use debug mode to see detailed error information
+dotnet-http GET api.example.com/broken --debug
+
+# Check request format first
+dotnet-http POST api.example.com/users invalid-data --offline
+```
+
+## Tips and Best Practices
+
+### 1. Use Environment Variables
+
+```bash
+# Store API tokens in environment variables
+export API_TOKEN="your-secret-token"
+dotnet-http GET api.example.com/protected Authorization:"Bearer $API_TOKEN"
+
+# Store base URLs
+export API_BASE="https://api.example.com"
+dotnet-http GET "$API_BASE/users"
+```
+
+### 2. Quote Special Characters
+
+```bash
+# Quote values with spaces or special characters
+dotnet-http POST httpbin.org/post message="Hello, world!" tags:='["tag with spaces", "special!chars"]'
+```
+
+### 3. Use Files for Large Data
+
+```bash
+# Instead of long command lines, use files
+cat > user.json << EOF
+{
+ "name": "John Doe",
+ "email": "john@example.com",
+ "address": {
+ "street": "123 Main St",
+ "city": "Seattle",
+ "state": "WA",
+ "zip": "98101"
+ }
+}
+EOF
+
+dotnet-http POST api.example.com/users @user.json
+```
+
+### 4. Combine with Other Tools
+
+```bash
+# Extract specific data with jq
+USER_ID=$(dotnet-http POST api.example.com/users name=John --body | jq -r '.id')
+dotnet-http GET "api.example.com/users/$USER_ID"
+
+# Format JSON output
+dotnet-http GET api.example.com/users | jq .
+
+# Save and process responses
+dotnet-http GET api.example.com/users --body > users.json
+jq '.users[] | select(.active == true)' users.json
+```
+
+### 5. Test Incrementally
+
+```bash
+# Start with simple requests
+dotnet-http GET api.example.com/health
+
+# Add authentication
+dotnet-http GET api.example.com/protected Authorization:"Bearer $TOKEN"
+
+# Add data gradually
+dotnet-http POST api.example.com/users name=John
+dotnet-http POST api.example.com/users name=John email=john@example.com
+dotnet-http POST api.example.com/users name=John email=john@example.com age:=30
+```
+
+## Common Use Cases
+
+### Development Workflow
+
+```bash
+# 1. Check if API is running
+dotnet-http GET localhost:3000/health
+
+# 2. Test authentication
+dotnet-http POST localhost:3000/auth/login username=admin password=password
+
+# 3. Test CRUD operations
+dotnet-http GET localhost:3000/api/users
+dotnet-http POST localhost:3000/api/users name=Test email=test@example.com
+dotnet-http PUT localhost:3000/api/users/1 name="Updated Name"
+dotnet-http DELETE localhost:3000/api/users/1
+```
+
+### API Exploration
+
+```bash
+# Discover API endpoints
+dotnet-http OPTIONS api.example.com
+
+# Check API documentation endpoint
+dotnet-http GET api.example.com/docs
+
+# Test different response formats
+dotnet-http GET api.example.com/users Accept:"application/json"
+dotnet-http GET api.example.com/users Accept:"application/xml"
+```
+
+### Integration Testing
+
+```bash
+# Test service dependencies
+dotnet-http GET auth-service.internal/health
+dotnet-http GET user-service.internal/health
+dotnet-http GET order-service.internal/health
+
+# Test cross-service communication
+TOKEN=$(dotnet-http POST auth-service.internal/token client_id=test --body | jq -r '.access_token')
+dotnet-http GET user-service.internal/profile Authorization:"Bearer $TOKEN"
+```
+
+## Next Steps
+
+- Learn about [advanced request data types](request-data-types.md)
+- Explore [authentication methods](authentication.md)
+- Try [file execution](file-execution.md) for complex workflows
+- Check out [common use cases](examples/common-use-cases.md) for real-world examples
+- Use [debugging techniques](debugging.md) when things go wrong
\ No newline at end of file
diff --git a/docs/articles/ci-cd-integration.md b/docs/articles/ci-cd-integration.md
new file mode 100644
index 0000000..b69cda0
--- /dev/null
+++ b/docs/articles/ci-cd-integration.md
@@ -0,0 +1,824 @@
+# CI/CD Integration
+
+This guide shows how to integrate dotnet-httpie into various CI/CD pipelines for automated API testing, health checks, and deployment verification.
+
+## Overview
+
+dotnet-httpie is perfect for CI/CD scenarios because it:
+- Provides deterministic exit codes
+- Supports scriptable automation
+- Works in containerized environments
+- Handles authentication securely
+- Offers offline mode for validation
+
+## GitHub Actions
+
+### Basic API Testing
+
+```yaml
+name: API Tests
+on: [push, pull_request]
+
+jobs:
+ api-tests:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: '8.0'
+
+ - name: Install dotnet-httpie
+ run: dotnet tool install --global dotnet-httpie
+
+ - name: API Health Check
+ run: dotnet-http GET ${{ vars.API_BASE_URL }}/health
+
+ - name: Run API Test Suite
+ run: dotnet-http exec tests/api-integration.http --env testing
+ env:
+ API_TOKEN: ${{ secrets.API_TOKEN }}
+```
+
+### Multi-Environment Testing
+
+```yaml
+name: Multi-Environment Tests
+on: [push, pull_request]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ environment: [development, staging, production]
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: '8.0'
+
+ - name: Install dotnet-httpie
+ run: dotnet tool install --global dotnet-httpie
+
+ - name: Test ${{ matrix.environment }}
+ run: dotnet-http exec tests/smoke-tests.http --env ${{ matrix.environment }}
+ env:
+ API_TOKEN: ${{ secrets[format('API_TOKEN_{0}', matrix.environment)] }}
+ API_BASE_URL: ${{ vars[format('API_BASE_URL_{0}', matrix.environment)] }}
+```
+
+### Docker-based Testing
+
+```yaml
+name: Docker API Tests
+on: [push, pull_request]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ services:
+ api:
+ image: my-api:latest
+ ports:
+ - 3000:3000
+ env:
+ DATABASE_URL: postgresql://test:test@postgres:5432/testdb
+ postgres:
+ image: postgres:13
+ env:
+ POSTGRES_DB: testdb
+ POSTGRES_USER: test
+ POSTGRES_PASSWORD: test
+ options: >-
+ --health-cmd pg_isready
+ --health-interval 10s
+ --health-timeout 5s
+ --health-retries 5
+
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Wait for API to be ready
+ run: |
+ timeout 60 bash -c 'until docker run --rm --network host weihanli/dotnet-httpie:latest GET localhost:3000/health; do sleep 2; done'
+
+ - name: Run Integration Tests
+ run: |
+ docker run --rm --network host \
+ -v ${{ github.workspace }}:/workspace -w /workspace \
+ weihanli/dotnet-httpie:latest exec tests/integration.http --env ci
+```
+
+### Deployment Verification
+
+```yaml
+name: Deploy and Verify
+on:
+ push:
+ branches: [main]
+
+jobs:
+ deploy-and-verify:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ # Deploy steps here...
+
+ - name: Install dotnet-httpie
+ run: dotnet tool install --global dotnet-httpie
+
+ - name: Verify Deployment
+ run: |
+ # Wait for deployment to be ready
+ sleep 30
+
+ # Health check
+ dotnet-http GET ${{ vars.PRODUCTION_API_URL }}/health
+
+ # Smoke tests
+ dotnet-http exec tests/post-deployment.http --env production
+ env:
+ PRODUCTION_API_TOKEN: ${{ secrets.PRODUCTION_API_TOKEN }}
+
+ - name: Rollback on Failure
+ if: failure()
+ run: |
+ echo "Deployment verification failed, initiating rollback..."
+ # Rollback logic here
+```
+
+## Azure DevOps
+
+### Basic Pipeline
+
+```yaml
+trigger:
+- main
+
+pool:
+ vmImage: 'ubuntu-latest'
+
+variables:
+ apiBaseUrl: 'https://api.example.com'
+
+steps:
+- task: UseDotNet@2
+ displayName: 'Setup .NET SDK'
+ inputs:
+ packageType: 'sdk'
+ version: '8.0.x'
+
+- script: dotnet tool install --global dotnet-httpie
+ displayName: 'Install dotnet-httpie'
+
+- script: dotnet-http GET $(apiBaseUrl)/health
+ displayName: 'API Health Check'
+
+- script: dotnet-http exec tests/api-tests.http --env $(Environment)
+ displayName: 'Run API Tests'
+ env:
+ API_TOKEN: $(ApiToken)
+```
+
+### Multi-Stage Pipeline
+
+```yaml
+trigger:
+- main
+
+stages:
+- stage: Test
+ displayName: 'Test Stage'
+ jobs:
+ - job: ApiTests
+ displayName: 'API Tests'
+ pool:
+ vmImage: 'ubuntu-latest'
+ steps:
+ - task: UseDotNet@2
+ inputs:
+ packageType: 'sdk'
+ version: '8.0.x'
+
+ - script: dotnet tool install --global dotnet-httpie
+ displayName: 'Install dotnet-httpie'
+
+ - script: dotnet-http exec tests/unit-api-tests.http --env testing
+ displayName: 'Unit API Tests'
+ env:
+ API_TOKEN: $(TestApiToken)
+
+- stage: Deploy
+ displayName: 'Deploy Stage'
+ dependsOn: Test
+ condition: succeeded()
+ jobs:
+ - deployment: DeployAPI
+ displayName: 'Deploy API'
+ environment: 'production'
+ strategy:
+ runOnce:
+ deploy:
+ steps:
+ # Deployment steps...
+
+ - script: dotnet tool install --global dotnet-httpie
+ displayName: 'Install dotnet-httpie'
+
+ - script: |
+ # Wait for deployment
+ sleep 60
+
+ # Verify deployment
+ dotnet-http GET $(ProductionApiUrl)/health
+ dotnet-http exec tests/production-smoke.http --env production
+ displayName: 'Verify Deployment'
+ env:
+ PRODUCTION_API_TOKEN: $(ProductionApiToken)
+```
+
+## GitLab CI
+
+### Basic Configuration
+
+```yaml
+stages:
+ - test
+ - deploy
+ - verify
+
+variables:
+ DOTNET_VERSION: "8.0"
+
+before_script:
+ - apt-get update -qy
+ - apt-get install -y dotnet-sdk-8.0
+ - dotnet tool install --global dotnet-httpie
+ - export PATH="$PATH:/root/.dotnet/tools"
+
+api-tests:
+ stage: test
+ script:
+ - dotnet-http GET $API_BASE_URL/health
+ - dotnet-http exec tests/api-suite.http --env $CI_ENVIRONMENT_NAME
+ variables:
+ API_BASE_URL: "https://api-test.example.com"
+ environment:
+ name: testing
+
+deploy-production:
+ stage: deploy
+ script:
+ - echo "Deploying to production..."
+ # Deployment logic here
+ only:
+ - main
+
+verify-production:
+ stage: verify
+ script:
+ - sleep 30 # Wait for deployment
+ - dotnet-http GET $PRODUCTION_API_URL/health
+ - dotnet-http exec tests/production-verification.http --env production
+ variables:
+ PRODUCTION_API_URL: "https://api.example.com"
+ environment:
+ name: production
+ dependencies:
+ - deploy-production
+ only:
+ - main
+```
+
+### Docker-based GitLab CI
+
+```yaml
+image: mcr.microsoft.com/dotnet/sdk:8.0
+
+stages:
+ - test
+ - deploy
+
+api-tests:
+ stage: test
+ services:
+ - name: postgres:13
+ alias: postgres
+ - name: redis:6
+ alias: redis
+ before_script:
+ - dotnet tool install --global dotnet-httpie
+ - export PATH="$PATH:/root/.dotnet/tools"
+ script:
+ - dotnet-http GET http://api-container:3000/health
+ - dotnet-http exec tests/integration.http --env gitlab-ci
+ variables:
+ POSTGRES_DB: testdb
+ POSTGRES_USER: test
+ POSTGRES_PASSWORD: test
+```
+
+## Jenkins
+
+### Declarative Pipeline
+
+```groovy
+pipeline {
+ agent any
+
+ environment {
+ DOTNET_VERSION = '8.0'
+ API_BASE_URL = 'https://api.example.com'
+ }
+
+ stages {
+ stage('Setup') {
+ steps {
+ sh '''
+ # Install .NET SDK if not available
+ if ! command -v dotnet &> /dev/null; then
+ wget https://dot.net/v1/dotnet-install.sh
+ chmod +x dotnet-install.sh
+ ./dotnet-install.sh --version ${DOTNET_VERSION}
+ export PATH="$PATH:$HOME/.dotnet"
+ fi
+
+ # Install dotnet-httpie
+ dotnet tool install --global dotnet-httpie
+ '''
+ }
+ }
+
+ stage('API Health Check') {
+ steps {
+ sh 'dotnet-http GET ${API_BASE_URL}/health'
+ }
+ }
+
+ stage('API Tests') {
+ steps {
+ withCredentials([string(credentialsId: 'api-token', variable: 'API_TOKEN')]) {
+ sh '''
+ export API_TOKEN=${API_TOKEN}
+ dotnet-http exec tests/api-tests.http --env ${BRANCH_NAME}
+ '''
+ }
+ }
+ }
+
+ stage('Deploy') {
+ when {
+ branch 'main'
+ }
+ steps {
+ sh 'echo "Deploying to production..."'
+ // Deployment steps
+ }
+ }
+
+ stage('Verify Deployment') {
+ when {
+ branch 'main'
+ }
+ steps {
+ sh '''
+ sleep 30
+ dotnet-http GET ${API_BASE_URL}/health
+ dotnet-http exec tests/production-smoke.http --env production
+ '''
+ }
+ }
+ }
+
+ post {
+ failure {
+ emailext (
+ subject: "Pipeline Failed: ${env.JOB_NAME} - ${env.BUILD_NUMBER}",
+ body: "API tests failed. Check the build logs for details.",
+ to: "${env.CHANGE_AUTHOR_EMAIL}"
+ )
+ }
+ }
+}
+```
+
+## CircleCI
+
+```yaml
+version: 2.1
+
+orbs:
+ dotnet: circleci/dotnet@2.0.0
+
+jobs:
+ api-tests:
+ docker:
+ - image: mcr.microsoft.com/dotnet/sdk:8.0
+ steps:
+ - checkout
+ - run:
+ name: Install dotnet-httpie
+ command: dotnet tool install --global dotnet-httpie
+ - run:
+ name: Add tools to PATH
+ command: echo 'export PATH="$PATH:/root/.dotnet/tools"' >> $BASH_ENV
+ - run:
+ name: API Health Check
+ command: dotnet-http GET $API_BASE_URL/health
+ - run:
+ name: Run API Tests
+ command: dotnet-http exec tests/api-tests.http --env testing
+
+ deploy:
+ docker:
+ - image: cimg/base:stable
+ steps:
+ - checkout
+ - run:
+ name: Deploy to production
+ command: echo "Deploying..."
+
+ verify-deployment:
+ docker:
+ - image: mcr.microsoft.com/dotnet/sdk:8.0
+ steps:
+ - checkout
+ - run:
+ name: Install dotnet-httpie
+ command: dotnet tool install --global dotnet-httpie
+ - run:
+ name: Add tools to PATH
+ command: echo 'export PATH="$PATH:/root/.dotnet/tools"' >> $BASH_ENV
+ - run:
+ name: Verify Production Deployment
+ command: |
+ sleep 30
+ dotnet-http GET $PRODUCTION_API_URL/health
+ dotnet-http exec tests/production-verification.http --env production
+
+workflows:
+ test-deploy-verify:
+ jobs:
+ - api-tests
+ - deploy:
+ requires:
+ - api-tests
+ filters:
+ branches:
+ only: main
+ - verify-deployment:
+ requires:
+ - deploy
+```
+
+## Docker Compose for Testing
+
+### Local Integration Testing
+
+```yaml
+# docker-compose.test.yml
+version: '3.8'
+
+services:
+ api:
+ build: .
+ ports:
+ - "3000:3000"
+ environment:
+ - NODE_ENV=test
+ - DATABASE_URL=postgresql://test:test@postgres:5432/testdb
+ depends_on:
+ postgres:
+ condition: service_healthy
+
+ postgres:
+ image: postgres:13
+ environment:
+ POSTGRES_DB: testdb
+ POSTGRES_USER: test
+ POSTGRES_PASSWORD: test
+ healthcheck:
+ test: ["CMD-SHELL", "pg_isready -U test"]
+ interval: 5s
+ timeout: 5s
+ retries: 5
+
+ api-tests:
+ image: weihanli/dotnet-httpie:latest
+ depends_on:
+ - api
+ volumes:
+ - ./tests:/tests
+ command: >
+ sh -c "
+ sleep 10 &&
+ dotnet-http GET http://api:3000/health &&
+ dotnet-http exec /tests/integration-tests.http --env docker
+ "
+ environment:
+ - API_BASE_URL=http://api:3000
+```
+
+## Kubernetes Jobs
+
+### API Testing Job
+
+```yaml
+apiVersion: batch/v1
+kind: Job
+metadata:
+ name: api-tests
+spec:
+ template:
+ spec:
+ containers:
+ - name: api-tests
+ image: weihanli/dotnet-httpie:latest
+ command: ["/bin/sh"]
+ args:
+ - -c
+ - |
+ dotnet-http GET $API_BASE_URL/health
+ dotnet-http exec /tests/k8s-tests.http --env kubernetes
+ env:
+ - name: API_BASE_URL
+ value: "http://api-service:8080"
+ - name: API_TOKEN
+ valueFrom:
+ secretKeyRef:
+ name: api-secrets
+ key: token
+ volumeMounts:
+ - name: test-files
+ mountPath: /tests
+ volumes:
+ - name: test-files
+ configMap:
+ name: api-test-files
+ restartPolicy: Never
+ backoffLimit: 3
+```
+
+### CronJob for Health Monitoring
+
+```yaml
+apiVersion: batch/v1
+kind: CronJob
+metadata:
+ name: api-health-monitor
+spec:
+ schedule: "*/5 * * * *" # Every 5 minutes
+ jobTemplate:
+ spec:
+ template:
+ spec:
+ containers:
+ - name: health-check
+ image: weihanli/dotnet-httpie:latest
+ command: ["/bin/sh"]
+ args:
+ - -c
+ - |
+ if ! dotnet-http GET $API_BASE_URL/health --check-status; then
+ echo "Health check failed"
+ exit 1
+ fi
+ env:
+ - name: API_BASE_URL
+ value: "http://api-service:8080"
+ restartPolicy: OnFailure
+```
+
+## Test Patterns
+
+### Health Check Scripts
+
+```bash
+#!/bin/bash
+# health-check.sh
+
+set -e
+
+API_BASE_URL="${API_BASE_URL:-http://localhost:3000}"
+MAX_RETRIES="${MAX_RETRIES:-30}"
+RETRY_DELAY="${RETRY_DELAY:-2}"
+
+echo "Waiting for API to be ready at $API_BASE_URL..."
+
+for i in $(seq 1 $MAX_RETRIES); do
+ if dotnet-http GET "$API_BASE_URL/health" --check-status >/dev/null 2>&1; then
+ echo "API is ready after $i attempts"
+ exit 0
+ fi
+
+ echo "Attempt $i/$MAX_RETRIES failed, retrying in ${RETRY_DELAY}s..."
+ sleep $RETRY_DELAY
+done
+
+echo "API failed to become ready after $MAX_RETRIES attempts"
+exit 1
+```
+
+### Smoke Test Suite
+
+```bash
+#!/bin/bash
+# smoke-tests.sh
+
+set -e
+
+API_BASE_URL="${API_BASE_URL:-http://localhost:3000}"
+ENVIRONMENT="${ENVIRONMENT:-development}"
+
+echo "Running smoke tests for $ENVIRONMENT environment..."
+
+# Critical endpoints
+ENDPOINTS=(
+ "/health"
+ "/api/v1/status"
+ "/api/v1/version"
+)
+
+for endpoint in "${ENDPOINTS[@]}"; do
+ echo "Testing $endpoint..."
+ if dotnet-http GET "$API_BASE_URL$endpoint" --check-status; then
+ echo "✓ $endpoint OK"
+ else
+ echo "✗ $endpoint FAILED"
+ exit 1
+ fi
+done
+
+echo "All smoke tests passed!"
+```
+
+### Load Testing
+
+```bash
+#!/bin/bash
+# load-test.sh
+
+ENDPOINT="${1:-http://localhost:3000/api/test}"
+CONCURRENT="${2:-10}"
+REQUESTS="${3:-100}"
+
+echo "Load testing $ENDPOINT with $CONCURRENT concurrent users, $REQUESTS total requests"
+
+# Create temporary results file
+RESULTS_FILE=$(mktemp)
+
+# Function to run requests
+run_requests() {
+ local requests_per_worker=$1
+ for i in $(seq 1 $requests_per_worker); do
+ start_time=$(date +%s%N)
+ if dotnet-http GET "$ENDPOINT" >/dev/null 2>&1; then
+ end_time=$(date +%s%N)
+ duration=$(((end_time - start_time) / 1000000))
+ echo "SUCCESS,$duration" >> "$RESULTS_FILE"
+ else
+ echo "FAILURE,0" >> "$RESULTS_FILE"
+ fi
+ done
+}
+
+# Start concurrent workers
+REQUESTS_PER_WORKER=$((REQUESTS / CONCURRENT))
+for i in $(seq 1 $CONCURRENT); do
+ run_requests $REQUESTS_PER_WORKER &
+done
+
+# Wait for all workers to complete
+wait
+
+# Analyze results
+total=$(wc -l < "$RESULTS_FILE")
+successful=$(grep "SUCCESS" "$RESULTS_FILE" | wc -l)
+failed=$((total - successful))
+
+if [ $successful -gt 0 ]; then
+ avg_response_time=$(grep "SUCCESS" "$RESULTS_FILE" | cut -d, -f2 | awk '{sum+=$1} END {print sum/NR}')
+else
+ avg_response_time=0
+fi
+
+echo "Load test results:"
+echo " Total requests: $total"
+echo " Successful: $successful"
+echo " Failed: $failed"
+echo " Success rate: $(( successful * 100 / total ))%"
+echo " Average response time: ${avg_response_time}ms"
+
+# Cleanup
+rm "$RESULTS_FILE"
+
+# Exit with error if failure rate is too high
+if [ $((failed * 100 / total)) -gt 5 ]; then
+ echo "Failure rate too high!"
+ exit 1
+fi
+```
+
+## Best Practices
+
+### 1. Environment Management
+
+```bash
+# Use environment-specific configurations
+dotnet-http exec tests/api-tests.http --env $CI_ENVIRONMENT_NAME
+
+# Store secrets securely in CI/CD variables
+export API_TOKEN="$CI_API_TOKEN"
+dotnet-http GET api.example.com/protected Authorization:"Bearer $API_TOKEN"
+```
+
+### 2. Error Handling
+
+```bash
+# Proper error handling in scripts
+if ! dotnet-http GET api.example.com/health --check-status; then
+ echo "Health check failed, aborting deployment"
+ exit 1
+fi
+
+# Retry logic for flaky endpoints
+for i in {1..3}; do
+ if dotnet-http GET api.example.com/flaky-endpoint; then
+ break
+ elif [ $i -eq 3 ]; then
+ echo "Endpoint failed after 3 attempts"
+ exit 1
+ else
+ echo "Attempt $i failed, retrying..."
+ sleep 5
+ fi
+done
+```
+
+### 3. Parallel Testing
+
+```bash
+# Run tests in parallel for faster execution
+{
+ dotnet-http exec tests/user-api.http --env $ENV &
+ dotnet-http exec tests/order-api.http --env $ENV &
+ dotnet-http exec tests/payment-api.http --env $ENV &
+ wait
+} && echo "All API tests completed successfully"
+```
+
+### 4. Reporting
+
+```bash
+# Generate test reports
+{
+ echo "# API Test Report"
+ echo "Generated: $(date)"
+ echo ""
+
+ if dotnet-http GET api.example.com/health; then
+ echo "✅ Health Check: PASSED"
+ else
+ echo "❌ Health Check: FAILED"
+ fi
+
+ # More test results...
+} > test-report.md
+```
+
+## Troubleshooting CI/CD Issues
+
+### Common Problems
+
+1. **Tool not found**: Ensure dotnet-httpie is installed and in PATH
+2. **Network issues**: Check firewall rules and DNS resolution
+3. **Authentication failures**: Verify secrets and environment variables
+4. **Timeout issues**: Increase timeouts for slow networks
+5. **SSL certificate problems**: Use `--verify=no` for development (not production)
+
+### Debug CI/CD Issues
+
+```bash
+# Enable debug mode in CI
+dotnet-http GET api.example.com/data --debug
+
+# Check environment variables
+env | grep -i api
+
+# Test network connectivity
+dotnet-http GET httpbin.org/get # External connectivity
+dotnet-http GET localhost:3000/health # Local connectivity
+```
+
+## Next Steps
+
+- Set up [monitoring and alerting](../examples/common-use-cases.md) with dotnet-httpie
+- Explore [Docker usage](../docker-usage.md) for containerized CI/CD
+- Learn about [debugging techniques](../debugging.md) for troubleshooting
+- Review [authentication methods](../authentication.md) for secure CI/CD
\ No newline at end of file
diff --git a/docs/articles/debugging.md b/docs/articles/debugging.md
new file mode 100644
index 0000000..5e68b1e
--- /dev/null
+++ b/docs/articles/debugging.md
@@ -0,0 +1,593 @@
+# Debugging & Troubleshooting
+
+This guide helps you debug issues with dotnet-httpie and troubleshoot common problems.
+
+## Debug Mode
+
+Enable debug mode to get detailed information about request processing:
+
+```bash
+dotnet-http GET api.example.com/data --debug
+```
+
+Debug mode provides:
+- Detailed request/response logging
+- Middleware execution information
+- Error stack traces
+- Performance timing
+- Configuration details
+
+## Offline Mode (Request Preview)
+
+Preview requests without sending them:
+
+```bash
+# Preview a single request
+dotnet-http POST api.example.com/users name=John --offline
+
+# Preview HTTP file execution
+dotnet-http exec requests.http --offline
+
+# Preview with debug information
+dotnet-http POST api.example.com/users name=John --debug --offline
+```
+
+Offline mode is useful for:
+- Validating request structure
+- Checking JSON formatting
+- Verifying headers and parameters
+- Testing variable substitution
+
+## Common Issues
+
+### 1. Installation Problems
+
+#### Tool Not Found After Installation
+
+**Problem**: `dotnet-http: command not found`
+
+**Solutions**:
+```bash
+# Check if tool is installed
+dotnet tool list --global
+
+# Verify .NET tools path is in PATH
+echo $PATH | grep -q "$HOME/.dotnet/tools" || echo "Tools path not in PATH"
+
+# Add to shell profile (bash/zsh)
+echo 'export PATH="$PATH:$HOME/.dotnet/tools"' >> ~/.bashrc
+source ~/.bashrc
+
+# Reinstall if corrupted
+dotnet tool uninstall --global dotnet-httpie
+dotnet tool install --global dotnet-httpie
+```
+
+#### Permission Denied
+
+**Problem**: Permission issues during installation
+
+**Solutions**:
+```bash
+# Check permissions on tools directory
+ls -la ~/.dotnet/tools/
+
+# Fix permissions if needed
+chmod +x ~/.dotnet/tools/dotnet-http
+
+# Install for current user only
+dotnet tool install --global dotnet-httpie --tool-path ~/.local/bin
+```
+
+### 2. Request Issues
+
+#### SSL/TLS Certificate Errors
+
+**Problem**: SSL certificate validation failures
+
+**Solutions**:
+```bash
+# Skip SSL verification (development only)
+dotnet-http GET https://self-signed-site.com --verify=no
+
+# Use custom CA certificate
+dotnet-http GET https://internal-api.company.com \
+ --ca-cert /path/to/ca-certificate.pem
+
+# Check SSL certificate details
+openssl s_client -connect api.example.com:443 -servername api.example.com
+```
+
+#### Connection Timeouts
+
+**Problem**: Requests timing out
+
+**Solutions**:
+```bash
+# Increase timeout (if supported)
+dotnet-http GET api.example.com/slow-endpoint --timeout 60
+
+# Check network connectivity
+ping api.example.com
+curl -I api.example.com
+
+# Test with simpler request first
+dotnet-http GET api.example.com/health
+```
+
+#### Authentication Failures
+
+**Problem**: 401 Unauthorized responses
+
+**Debug Steps**:
+```bash
+# Check token validity
+echo $JWT_TOKEN | base64 -d
+
+# Verify token format
+dotnet-http GET api.example.com/verify \
+ Authorization:"Bearer $JWT_TOKEN" \
+ --debug
+
+# Test with minimal request
+dotnet-http GET api.example.com/public
+
+# Check header format
+dotnet-http GET httpbin.org/headers \
+ Authorization:"Bearer $JWT_TOKEN"
+```
+
+### 3. JSON and Data Issues
+
+#### JSON Parsing Errors
+
+**Problem**: Invalid JSON in request body
+
+**Debug**:
+```bash
+# Preview JSON structure
+dotnet-http POST api.example.com/users \
+ name=John \
+ age:=30 \
+ tags:='["dev", "api"]' \
+ --offline
+
+# Validate JSON manually
+echo '{"name": "John", "age": 30}' | jq .
+
+# Use file for complex JSON
+cat > user.json << EOF
+{
+ "name": "John",
+ "age": 30,
+ "skills": ["C#", "JavaScript"]
+}
+EOF
+
+dotnet-http POST api.example.com/users @user.json
+```
+
+#### Character Encoding Issues
+
+**Problem**: Special characters not handled correctly
+
+**Solutions**:
+```bash
+# Specify charset
+dotnet-http POST api.example.com/data \
+ Content-Type:"application/json; charset=utf-8" \
+ message="Hello 世界"
+
+# Use file with proper encoding
+echo '{"message": "Hello 世界"}' > data.json
+dotnet-http POST api.example.com/data @data.json
+```
+
+### 4. File Execution Issues
+
+#### File Not Found
+
+**Problem**: HTTP files not loading
+
+**Debug**:
+```bash
+# Check file exists and permissions
+ls -la requests.http
+
+# Use absolute path
+dotnet-http exec /full/path/to/requests.http
+
+# Check current directory
+pwd
+dotnet-http exec ./requests.http
+```
+
+#### Variable Substitution Failures
+
+**Problem**: Variables not being replaced
+
+**Debug**:
+```bash
+# Check environment file
+cat http-client.env.json
+
+# Verify environment selection
+dotnet-http exec requests.http --env development --debug
+
+# Test variable syntax
+# Good: {{baseUrl}}
+# Bad: {baseUrl} or $baseUrl
+```
+
+#### Request Reference Errors
+
+**Problem**: Cannot reference previous responses
+
+**Debug**:
+```bash
+# Ensure request names are defined
+# @name createUser
+POST {{baseUrl}}/users
+
+# Reference with correct syntax
+GET {{baseUrl}}/users/{{createUser.response.body.id}}
+
+# Check response structure
+dotnet-http exec requests.http --debug --offline
+```
+
+## Debugging Tools and Techniques
+
+### 1. Network Analysis
+
+#### Using tcpdump/Wireshark
+
+```bash
+# Capture network traffic (Linux/macOS)
+sudo tcpdump -i any -w capture.pcap host api.example.com
+
+# Run your request
+dotnet-http GET api.example.com/data
+
+# Analyze capture with Wireshark or tcpdump
+tcpdump -r capture.pcap -A
+```
+
+#### Using curl for comparison
+
+```bash
+# Compare with curl behavior
+curl -v https://api.example.com/data \
+ -H "Authorization: Bearer $TOKEN"
+
+# Convert to dotnet-httpie equivalent
+dotnet-http GET api.example.com/data \
+ Authorization:"Bearer $TOKEN" \
+ --debug
+```
+
+### 2. Response Analysis
+
+#### JSON Processing
+
+```bash
+# Pretty print JSON response
+dotnet-http GET api.example.com/users | jq .
+
+# Extract specific fields
+dotnet-http GET api.example.com/users | jq '.users[0].id'
+
+# Validate JSON schema
+dotnet-http GET api.example.com/users | jq 'type'
+```
+
+#### Header Analysis
+
+```bash
+# Show response headers only
+dotnet-http HEAD api.example.com/data
+
+# Check specific headers
+dotnet-http GET httpbin.org/headers | jq '.headers'
+
+# Trace header propagation
+dotnet-http GET api.example.com/data \
+ X-Trace-ID:"$(uuidgen)" \
+ --debug
+```
+
+### 3. Performance Debugging
+
+#### Response Time Analysis
+
+```bash
+# Measure response time
+time dotnet-http GET api.example.com/data
+
+# Multiple requests for average
+for i in {1..10}; do
+ time dotnet-http GET api.example.com/data >/dev/null
+done
+```
+
+#### Memory and Resource Usage
+
+```bash
+# Monitor resource usage
+top -p $(pgrep dotnet-http)
+
+# Memory usage
+ps aux | grep dotnet-http
+```
+
+## Error Analysis
+
+### HTTP Status Codes
+
+#### 4xx Client Errors
+
+```bash
+# 400 Bad Request
+dotnet-http POST api.example.com/users \
+ invalid-json \
+ --debug # Check request format
+
+# 401 Unauthorized
+dotnet-http GET api.example.com/protected \
+ --debug # Check authentication
+
+# 403 Forbidden
+dotnet-http GET api.example.com/admin \
+ Authorization:"Bearer $USER_TOKEN" \
+ --debug # Check permissions
+
+# 404 Not Found
+dotnet-http GET api.example.com/nonexistent \
+ --debug # Check URL
+
+# 429 Too Many Requests
+dotnet-http GET api.example.com/data \
+ --debug # Check rate limiting
+```
+
+#### 5xx Server Errors
+
+```bash
+# 500 Internal Server Error
+dotnet-http POST api.example.com/users \
+ name=John \
+ --debug # Check server logs
+
+# 502 Bad Gateway
+dotnet-http GET api.example.com/data \
+ --debug # Check proxy/load balancer
+
+# 503 Service Unavailable
+dotnet-http GET api.example.com/health \
+ --debug # Check service status
+```
+
+### Error Response Analysis
+
+```bash
+# Capture error details
+ERROR_RESPONSE=$(dotnet-http GET api.example.com/error --body 2>&1)
+echo "$ERROR_RESPONSE" | jq .
+
+# Check error structure
+dotnet-http GET api.example.com/error | jq '{error, message, code}'
+```
+
+## Logging and Monitoring
+
+### Request Logging
+
+```bash
+# Log all requests to file
+dotnet-http GET api.example.com/data --debug > request.log 2>&1
+
+# Structured logging
+dotnet-http GET api.example.com/data 2>&1 | \
+ grep -E "(Request|Response|Error)" > structured.log
+```
+
+### Automated Health Checks
+
+```bash
+#!/bin/bash
+# health-monitor.sh
+
+LOG_FILE="/var/log/api-health.log"
+
+check_endpoint() {
+ local endpoint=$1
+ local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
+
+ if dotnet-http GET "$endpoint" --check-status >/dev/null 2>&1; then
+ echo "[$timestamp] OK: $endpoint" >> "$LOG_FILE"
+ return 0
+ else
+ echo "[$timestamp] FAIL: $endpoint" >> "$LOG_FILE"
+ return 1
+ fi
+}
+
+# Monitor multiple endpoints
+check_endpoint "https://api.example.com/health"
+check_endpoint "https://api.example.com/status"
+check_endpoint "https://auth.example.com/health"
+```
+
+## Docker Debugging
+
+### Container Issues
+
+```bash
+# Run with debug output
+docker run --rm weihanli/dotnet-httpie:latest \
+ GET api.example.com/data --debug
+
+# Check container logs
+docker run --name httpie-debug weihanli/dotnet-httpie:latest \
+ GET api.example.com/data
+docker logs httpie-debug
+docker rm httpie-debug
+
+# Interactive debugging
+docker run -it --rm weihanli/dotnet-httpie:latest /bin/sh
+```
+
+### Network Issues in Docker
+
+```bash
+# Test network connectivity
+docker run --rm weihanli/dotnet-httpie:latest \
+ GET httpbin.org/get
+
+# Use host network
+docker run --rm --network host \
+ weihanli/dotnet-httpie:latest GET localhost:3000/api
+
+# Check DNS resolution
+docker run --rm weihanli/dotnet-httpie:latest \
+ nslookup api.example.com
+```
+
+## Environment Debugging
+
+### Environment Variables
+
+```bash
+# Check all environment variables
+env | grep -i http
+env | grep -i api
+
+# Verify specific variables
+echo "API_TOKEN: $API_TOKEN"
+echo "BASE_URL: $BASE_URL"
+
+# Debug variable expansion
+dotnet-http GET "$BASE_URL/data" \
+ Authorization:"Bearer $API_TOKEN" \
+ --debug
+```
+
+### Configuration Files
+
+```bash
+# Check HTTP client environment
+cat http-client.env.json | jq .
+
+# Validate JSON syntax
+jq empty http-client.env.json && echo "Valid JSON" || echo "Invalid JSON"
+
+# Check file permissions
+ls -la http-client.env.json
+```
+
+## Performance Troubleshooting
+
+### Slow Requests
+
+```bash
+# Add timing information
+time dotnet-http GET api.example.com/slow-endpoint
+
+# Profile with curl for comparison
+time curl -s https://api.example.com/slow-endpoint >/dev/null
+
+# Check DNS resolution time
+time nslookup api.example.com
+
+# Test with different endpoints
+time dotnet-http GET httpbin.org/delay/5
+```
+
+### Memory Issues
+
+```bash
+# Monitor memory usage during large requests
+dotnet-http GET api.example.com/large-dataset &
+PID=$!
+while kill -0 $PID 2>/dev/null; do
+ ps -p $PID -o pid,vsz,rss,comm
+ sleep 1
+done
+```
+
+## Advanced Debugging
+
+### Custom Middleware Debugging
+
+If you're developing custom middleware:
+
+```bash
+# Enable detailed middleware logging
+dotnet-http GET api.example.com/data \
+ --debug \
+ -v # Verbose mode if available
+```
+
+### Source Code Debugging
+
+```bash
+# Clone repository for local debugging
+git clone https://github.com/WeihanLi/dotnet-httpie.git
+cd dotnet-httpie
+
+# Build in debug mode
+dotnet build -c Debug
+
+# Run with debugger
+dotnet run --project src/HTTPie -- GET api.example.com/data --debug
+```
+
+## Getting Help
+
+### Information to Include in Bug Reports
+
+When reporting issues, include:
+
+1. **Version information**:
+ ```bash
+ dotnet-http --version
+ dotnet --version
+ ```
+
+2. **Command that failed**:
+ ```bash
+ dotnet-http GET api.example.com/data --debug
+ ```
+
+3. **Expected vs actual behavior**
+
+4. **Error messages** (full output with `--debug`)
+
+5. **Environment details**:
+ - Operating system
+ - .NET version
+ - Docker version (if using Docker)
+
+### Community Resources
+
+- [GitHub Issues](https://github.com/WeihanLi/dotnet-httpie/issues)
+- [GitHub Discussions](https://github.com/WeihanLi/dotnet-httpie/discussions)
+- [Stack Overflow](https://stackoverflow.com/questions/tagged/dotnet-httpie)
+
+### Self-Help Checklist
+
+Before asking for help:
+
+- [ ] Tried with `--debug` flag
+- [ ] Tested with `--offline` to check request structure
+- [ ] Verified authentication tokens/keys
+- [ ] Checked network connectivity
+- [ ] Tested with a simple request first
+- [ ] Reviewed relevant documentation
+- [ ] Searched existing issues
+
+## Next Steps
+
+- Review [performance tips](performance-tips.md) for optimization
+- Check [common use cases](examples/common-use-cases.md) for working examples
+- Explore [advanced features](middleware-system.md) for complex scenarios
\ No newline at end of file
diff --git a/docs/articles/docker-usage.md b/docs/articles/docker-usage.md
new file mode 100644
index 0000000..5c56517
--- /dev/null
+++ b/docs/articles/docker-usage.md
@@ -0,0 +1,428 @@
+# Docker Usage
+
+dotnet-httpie is available as a Docker image, making it easy to use in containerized environments, CI/CD pipelines, and systems without .NET installed.
+
+## Docker Image
+
+The official Docker image is available at: `weihanli/dotnet-httpie`
+
+### Available Tags
+
+- `latest` - Latest stable release
+- `preview` - Latest preview/pre-release version
+- `0.12.0` - Specific version tags
+
+## Quick Start
+
+### Pull the Image
+
+```bash
+docker pull weihanli/dotnet-httpie:latest
+```
+
+### Basic Usage
+
+```bash
+# Simple GET request
+docker run --rm weihanli/dotnet-httpie:latest httpbin.org/get
+
+# POST with data
+docker run --rm weihanli/dotnet-httpie:latest POST httpbin.org/post name=John age:=30
+
+# With headers
+docker run --rm weihanli/dotnet-httpie:latest GET httpbin.org/headers Authorization:"Bearer token"
+```
+
+## Common Usage Patterns
+
+### Interactive Usage
+
+```bash
+# Create an alias for easier usage
+alias http='docker run --rm -i weihanli/dotnet-httpie:latest'
+
+# Now use it like the installed version
+http GET httpbin.org/get
+http POST httpbin.org/post name=John
+```
+
+### With Local Files
+
+Mount local directories to access files:
+
+```bash
+# Mount current directory
+docker run --rm -v $(pwd):/workspace -w /workspace \
+ weihanli/dotnet-httpie:latest exec requests.http
+
+# Mount specific directory
+docker run --rm -v /path/to/files:/files \
+ weihanli/dotnet-httpie:latest exec /files/api-tests.http
+```
+
+### Environment Variables
+
+Pass environment variables to the container:
+
+```bash
+# Single environment variable
+docker run --rm -e API_TOKEN="your-token" \
+ weihanli/dotnet-httpie:latest GET api.example.com/protected \
+ Authorization:"Bearer $API_TOKEN"
+
+# Multiple environment variables
+docker run --rm \
+ -e API_BASE_URL="https://api.example.com" \
+ -e API_TOKEN="your-token" \
+ weihanli/dotnet-httpie:latest GET "$API_BASE_URL/users" \
+ Authorization:"Bearer $API_TOKEN"
+
+# Environment file
+docker run --rm --env-file .env \
+ weihanli/dotnet-httpie:latest GET api.example.com/data
+```
+
+## File Operations
+
+### Executing HTTP Files
+
+```bash
+# Mount and execute HTTP file
+docker run --rm -v $(pwd):/workspace -w /workspace \
+ weihanli/dotnet-httpie:latest exec tests/api.http
+
+# With environment
+docker run --rm -v $(pwd):/workspace -w /workspace \
+ weihanli/dotnet-httpie:latest exec tests/api.http --env production
+```
+
+### File Downloads
+
+```bash
+# Download to mounted volume
+docker run --rm -v $(pwd)/downloads:/downloads \
+ weihanli/dotnet-httpie:latest GET httpbin.org/image/png \
+ --download --output /downloads/image.png
+```
+
+### Upload Files
+
+```bash
+# Upload file from mounted volume
+docker run --rm -v $(pwd):/workspace -w /workspace \
+ weihanli/dotnet-httpie:latest POST api.example.com/upload \
+ @data.json
+```
+
+## Networking
+
+### Host Network
+
+Access services running on the host:
+
+```bash
+# Access localhost services (Linux)
+docker run --rm --network host \
+ weihanli/dotnet-httpie:latest GET localhost:3000/api/health
+
+# Access host services (macOS/Windows)
+docker run --rm \
+ weihanli/dotnet-httpie:latest GET host.docker.internal:3000/api/health
+```
+
+### Custom Networks
+
+```bash
+# Create network
+docker network create api-test-network
+
+# Run API server in network
+docker run -d --name api-server --network api-test-network my-api-image
+
+# Test API using dotnet-httpie in same network
+docker run --rm --network api-test-network \
+ weihanli/dotnet-httpie:latest GET api-server:3000/health
+```
+
+## CI/CD Integration
+
+### GitHub Actions
+
+```yaml
+name: API Tests
+on: [push, pull_request]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+
+ - name: Test API Health
+ run: |
+ docker run --rm --network host \
+ weihanli/dotnet-httpie:latest GET localhost:3000/health
+
+ - name: Run API Test Suite
+ run: |
+ docker run --rm -v ${{ github.workspace }}:/workspace -w /workspace \
+ weihanli/dotnet-httpie:latest exec tests/api-suite.http --env testing
+
+ - name: Test with Authentication
+ env:
+ API_TOKEN: ${{ secrets.API_TOKEN }}
+ run: |
+ docker run --rm -e API_TOKEN \
+ weihanli/dotnet-httpie:latest GET api.example.com/protected \
+ Authorization:"Bearer $API_TOKEN"
+```
+
+### Azure DevOps
+
+```yaml
+stages:
+- stage: ApiTests
+ jobs:
+ - job: RunTests
+ pool:
+ vmImage: 'ubuntu-latest'
+ steps:
+ - script: |
+ docker run --rm -v $(System.DefaultWorkingDirectory):/workspace -w /workspace \
+ weihanli/dotnet-httpie:latest exec tests/integration.http --env $(Environment)
+ displayName: 'Run Integration Tests'
+ env:
+ API_TOKEN: $(ApiToken)
+```
+
+### GitLab CI
+
+```yaml
+test-api:
+ image: docker:latest
+ services:
+ - docker:dind
+ script:
+ - docker run --rm -v $PWD:/workspace -w /workspace
+ weihanli/dotnet-httpie:latest exec tests/api.http --env $CI_ENVIRONMENT_NAME
+ variables:
+ API_TOKEN: $API_TOKEN
+```
+
+## Docker Compose Integration
+
+### Basic Setup
+
+```yaml
+# docker-compose.yml
+
+services:
+ api:
+ image: my-api:latest
+ ports:
+ - "3000:3000"
+ environment:
+ - NODE_ENV=development
+
+ api-tests:
+ image: weihanli/dotnet-httpie:latest
+ depends_on:
+ - api
+ volumes:
+ - ./tests:/tests
+ command: exec /tests/api-suite.http
+ environment:
+ - API_BASE_URL=http://api:3000
+```
+
+### Health Checks
+
+```yaml
+version: '3.8'
+
+services:
+ api:
+ image: my-api:latest
+ healthcheck:
+ test: ["CMD", "docker", "run", "--rm", "--network", "container:my-api",
+ "weihanli/dotnet-httpie:latest", "GET", "localhost:3000/health"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+```
+
+## Advanced Scenarios
+
+### Multi-Stage Testing
+
+```bash
+# Test development environment
+docker run --rm -v $(pwd):/workspace -w /workspace \
+ weihanli/dotnet-httpie:latest exec tests/smoke.http --env development
+
+# Test staging environment
+docker run --rm -v $(pwd):/workspace -w /workspace \
+ -e API_BASE_URL="https://staging.api.example.com" \
+ weihanli/dotnet-httpie:latest exec tests/full-suite.http --env staging
+
+# Test production environment
+docker run --rm -v $(pwd):/workspace -w /workspace \
+ -e API_BASE_URL="https://api.example.com" \
+ weihanli/dotnet-httpie:latest exec tests/health-check.http --env production
+```
+
+### Proxy Testing
+
+```bash
+# Test through proxy
+docker run --rm \
+ -e HTTP_PROXY="http://proxy.company.com:8080" \
+ -e HTTPS_PROXY="http://proxy.company.com:8080" \
+ weihanli/dotnet-httpie:latest GET api.example.com/data
+```
+
+## Shell Scripts and Automation
+
+### Bash Scripts
+
+```bash
+#!/bin/bash
+# api-test.sh
+
+set -e
+
+API_BASE_URL="${API_BASE_URL:-http://localhost:3000}"
+DOCKER_IMAGE="weihanli/dotnet-httpie:latest"
+
+echo "Testing API at $API_BASE_URL..."
+
+# Health check
+echo "Checking API health..."
+docker run --rm $DOCKER_IMAGE GET "$API_BASE_URL/health"
+
+# Login to get token (JSON data, not Basic Auth)
+echo "Testing login..."
+TOKEN=$(docker run --rm $DOCKER_IMAGE POST "$API_BASE_URL/auth/login" \
+ username=testuser password=testpass --body | jq -r '.token')
+
+# Protected endpoint test with Bearer token
+echo "Testing protected endpoint..."
+docker run --rm $DOCKER_IMAGE GET "$API_BASE_URL/protected" \
+ Authorization:"Bearer $TOKEN"
+
+# Basic Auth test (HTTP Basic Authentication)
+echo "Testing Basic Auth..."
+docker run --rm $DOCKER_IMAGE GET "$API_BASE_URL/basic-protected" \
+ --auth testuser:testpass
+
+echo "All tests passed!"
+```
+
+### PowerShell Scripts
+
+```powershell
+# api-test.ps1
+
+param(
+ [string]$ApiBaseUrl = "http://localhost:3000",
+ [string]$Environment = "development"
+)
+
+$dockerImage = "weihanli/dotnet-httpie:latest"
+
+Write-Host "Testing API at $ApiBaseUrl..."
+
+# Run test suite
+docker run --rm -v "${PWD}:/workspace" -w /workspace `
+ -e API_BASE_URL=$ApiBaseUrl `
+ $dockerImage exec tests/api-suite.http --env $Environment
+
+Write-Host "Tests completed!"
+```
+
+## Configuration
+
+### Custom Configuration
+
+```bash
+# Mount custom configuration
+docker run --rm -v $(pwd)/config:/config \
+ -e DOTNET_HTTPIE_CONFIG="/config/httpie.json" \
+ weihanli/dotnet-httpie:latest GET api.example.com/data
+```
+
+### SSL Certificates
+
+```bash
+# Mount custom CA certificates
+docker run --rm -v $(pwd)/certs:/certs \
+ -e SSL_CERT_DIR="/certs" \
+ weihanli/dotnet-httpie:latest GET https://internal-api.company.com/data
+```
+
+## Troubleshooting
+
+### Debug Mode
+
+```bash
+# Enable debug output
+docker run --rm \
+ weihanli/dotnet-httpie:latest GET httpbin.org/get --debug
+```
+
+### Offline Mode
+
+```bash
+# Preview requests without sending
+docker run --rm -v $(pwd):/workspace -w /workspace \
+ weihanli/dotnet-httpie:latest exec tests/api.http --offline
+```
+
+### Container Logs
+
+```bash
+# Run with verbose output
+docker run --rm \
+ weihanli/dotnet-httpie:latest GET httpbin.org/get --verbose
+
+# Save logs
+docker run --rm \
+ weihanli/dotnet-httpie:latest GET httpbin.org/get > request.log 2>&1
+```
+
+## Performance Considerations
+
+### Image Size
+
+The dotnet-httpie Docker image is optimized for size using:
+- Multi-stage builds
+- Alpine Linux base (where applicable)
+- AOT compilation for reduced runtime dependencies
+
+### Caching
+
+```bash
+# Pre-pull image for faster execution
+docker pull weihanli/dotnet-httpie:latest
+
+# Use specific version for consistency
+docker run --rm weihanli/dotnet-httpie:0.12.0 GET httpbin.org/get
+```
+
+## Best Practices
+
+1. **Use specific image tags** in production environments
+2. **Mount volumes efficiently** - only mount what you need
+3. **Use environment variables** for configuration
+4. **Leverage Docker networks** for service-to-service communication
+5. **Clean up containers** with `--rm` flag
+6. **Pre-pull images** in CI/CD for faster execution
+7. **Use multi-stage testing** for different environments
+8. **Secure sensitive data** using Docker secrets or external secret management
+
+## Next Steps
+
+- Set up [CI/CD integration](ci-cd-integration.md) with Docker
+- Learn about [environment configuration](environment-variables.md)
+- Explore [advanced examples](examples/integrations.md) with Docker
+- Review [troubleshooting guide](debugging.md) for common issues
\ No newline at end of file
diff --git a/docs/articles/examples/common-use-cases.md b/docs/articles/examples/common-use-cases.md
new file mode 100644
index 0000000..095c6c4
--- /dev/null
+++ b/docs/articles/examples/common-use-cases.md
@@ -0,0 +1,612 @@
+# Common Use Cases
+
+This guide provides practical examples for the most common scenarios when using dotnet-httpie.
+
+## API Development & Testing
+
+### REST API CRUD Operations
+
+```bash
+# Users API example
+BASE_URL="https://api.example.com"
+TOKEN="your-jwt-token"
+
+# Create user
+dotnet-http POST $BASE_URL/users \
+ Authorization:"Bearer $TOKEN" \
+ Content-Type:"application/json" \
+ name="John Doe" \
+ email="john@example.com" \
+ role="user"
+
+# Get all users
+dotnet-http GET $BASE_URL/users \
+ Authorization:"Bearer $TOKEN"
+
+# Get specific user
+dotnet-http GET $BASE_URL/users/123 \
+ Authorization:"Bearer $TOKEN"
+
+# Update user
+dotnet-http PUT $BASE_URL/users/123 \
+ Authorization:"Bearer $TOKEN" \
+ name="John Smith" \
+ email="john.smith@example.com"
+
+# Partial update
+dotnet-http PATCH $BASE_URL/users/123 \
+ Authorization:"Bearer $TOKEN" \
+ email="newemail@example.com"
+
+# Delete user
+dotnet-http DELETE $BASE_URL/users/123 \
+ Authorization:"Bearer $TOKEN"
+```
+
+### GraphQL API
+
+```bash
+# GraphQL query
+dotnet-http POST https://api.github.com/graphql \
+ Authorization:"Bearer $GITHUB_TOKEN" \
+ query='query { viewer { login name } }'
+
+# GraphQL mutation
+dotnet-http POST https://api.github.com/graphql \
+ Authorization:"Bearer $GITHUB_TOKEN" \
+ query='mutation { createIssue(input: {repositoryId: "repo-id", title: "Bug report", body: "Description"}) { issue { id title } } }'
+```
+
+## Authentication Patterns
+
+### JWT Authentication
+
+```bash
+# Login and get token
+LOGIN_RESPONSE=$(dotnet-http POST api.example.com/auth/login \
+ username="admin" \
+ password="password" \
+ --body)
+
+TOKEN=$(echo $LOGIN_RESPONSE | jq -r '.token')
+
+# Use token for protected requests
+dotnet-http GET api.example.com/protected \
+ Authorization:"Bearer $TOKEN"
+```
+
+### API Key Authentication
+
+```bash
+# Header-based API key
+dotnet-http GET api.example.com/data \
+ X-API-Key:"your-api-key"
+
+# Query parameter API key
+dotnet-http GET api.example.com/data \
+ api_key==your-api-key
+```
+
+### Basic Authentication
+
+```bash
+# Basic auth
+dotnet-http GET api.example.com/secure \
+ Authorization:"Basic $(echo -n 'username:password' | base64)"
+
+# Or with HTTPie-style auth
+dotnet-http GET api.example.com/secure \
+ --auth username:password
+```
+
+### OAuth 2.0
+
+```bash
+# Get access token
+TOKEN_RESPONSE=$(dotnet-http POST oauth.example.com/token \
+ grant_type="client_credentials" \
+ client_id="your-client-id" \
+ client_secret="your-client-secret" \
+ scope="read write" \
+ --body)
+
+ACCESS_TOKEN=$(echo $TOKEN_RESPONSE | jq -r '.access_token')
+
+# Use access token
+dotnet-http GET api.example.com/protected \
+ Authorization:"Bearer $ACCESS_TOKEN"
+```
+
+## File Operations
+
+### File Uploads
+
+```bash
+# Single file upload
+dotnet-http POST api.example.com/upload \
+ Authorization:"Bearer $TOKEN" \
+ --multipart \
+ file@/path/to/document.pdf \
+ description="Important document"
+
+# Multiple file upload
+dotnet-http POST api.example.com/batch-upload \
+ --multipart \
+ doc1@/path/to/file1.pdf \
+ doc2@/path/to/file2.pdf \
+ metadata@/path/to/metadata.json
+
+# Image upload with metadata
+dotnet-http POST api.example.com/images \
+ --multipart \
+ image@/path/to/photo.jpg \
+ title="Vacation Photo" \
+ tags:='["vacation", "travel", "beach"]' \
+ public:=true
+```
+
+### File Downloads
+
+```bash
+# Download file
+dotnet-http GET api.example.com/files/document.pdf \
+ Authorization:"Bearer $TOKEN" \
+ --download
+
+# Download with custom filename
+dotnet-http GET api.example.com/exports/data.csv \
+ --download \
+ --output "$(date +%Y%m%d)-export.csv"
+
+# Download large files with progress
+dotnet-http GET api.example.com/large-file.zip \
+ --download \
+ --progress
+```
+
+## Data Processing
+
+### JSON Processing with jq
+
+```bash
+# Extract specific fields
+USER_ID=$(dotnet-http POST api.example.com/users name="John" --body | jq -r '.id')
+
+# Filter arrays
+dotnet-http GET api.example.com/users | jq '.users[] | select(.active == true)'
+
+# Transform data
+dotnet-http GET api.example.com/users | jq '.users | map({id, name, email})'
+
+# Count results
+COUNT=$(dotnet-http GET api.example.com/users | jq '.users | length')
+echo "Total users: $COUNT"
+```
+
+### Pagination
+
+```bash
+# Fetch all pages
+page=1
+all_data="[]"
+
+while true; do
+ response=$(dotnet-http GET api.example.com/users page==$page limit==50 --body)
+ data=$(echo $response | jq '.data')
+
+ if [ "$(echo $data | jq 'length')" -eq 0 ]; then
+ break
+ fi
+
+ all_data=$(echo $all_data $data | jq -s 'add')
+ ((page++))
+done
+
+echo $all_data | jq .
+```
+
+## CI/CD Integration
+
+### Health Checks
+
+```bash
+#!/bin/bash
+# health-check.sh
+
+check_service() {
+ local service_url=$1
+ local service_name=$2
+
+ echo "Checking $service_name..."
+
+ if dotnet-http GET $service_url/health --check-status; then
+ echo "✓ $service_name is healthy"
+ return 0
+ else
+ echo "✗ $service_name is unhealthy"
+ return 1
+ fi
+}
+
+# Check multiple services
+check_service "https://api.example.com" "API Service"
+check_service "https://auth.example.com" "Auth Service"
+check_service "https://cache.example.com" "Cache Service"
+```
+
+### Deployment Verification
+
+```bash
+#!/bin/bash
+# verify-deployment.sh
+
+ENVIRONMENT=${1:-staging}
+BASE_URL="https://$ENVIRONMENT.api.example.com"
+
+echo "Verifying deployment in $ENVIRONMENT..."
+
+# Check API version
+VERSION=$(dotnet-http GET $BASE_URL/version --body | jq -r '.version')
+echo "API Version: $VERSION"
+
+# Run smoke tests
+dotnet-http exec tests/smoke-tests.http --env $ENVIRONMENT
+
+# Check critical endpoints
+dotnet-http GET $BASE_URL/health
+dotnet-http GET $BASE_URL/metrics
+dotnet-http GET $BASE_URL/ready
+
+echo "Deployment verification complete!"
+```
+
+### Load Testing
+
+```bash
+#!/bin/bash
+# load-test.sh
+
+URL="https://api.example.com/endpoint"
+CONCURRENT=10
+REQUESTS=100
+
+echo "Running load test: $REQUESTS requests with $CONCURRENT concurrent users"
+
+# Create temporary file for results
+RESULTS_FILE=$(mktemp)
+
+# Run concurrent requests
+for i in $(seq 1 $CONCURRENT); do
+ (
+ for j in $(seq 1 $((REQUESTS / CONCURRENT))); do
+ start_time=$(date +%s%N)
+
+ if dotnet-http GET $URL > /dev/null 2>&1; then
+ end_time=$(date +%s%N)
+ duration=$(((end_time - start_time) / 1000000))
+ echo "SUCCESS,$duration" >> $RESULTS_FILE
+ else
+ echo "FAILURE,0" >> $RESULTS_FILE
+ fi
+ done
+ ) &
+done
+
+wait
+
+# Analyze results
+total=$(wc -l < $RESULTS_FILE)
+success=$(grep "SUCCESS" $RESULTS_FILE | wc -l)
+failures=$((total - success))
+avg_time=$(grep "SUCCESS" $RESULTS_FILE | cut -d, -f2 | awk '{sum+=$1} END {print sum/NR}')
+
+echo "Results:"
+echo " Total requests: $total"
+echo " Successful: $success"
+echo " Failed: $failures"
+echo " Success rate: $(( success * 100 / total ))%"
+echo " Average response time: ${avg_time}ms"
+
+rm $RESULTS_FILE
+```
+
+## API Testing Workflows
+
+### End-to-End Testing
+
+```http
+# tests/e2e-workflow.http
+@baseUrl = https://api.example.com
+@contentType = application/json
+
+###
+
+# @name login
+POST {{baseUrl}}/auth/login
+Content-Type: {{contentType}}
+
+{
+ "username": "testuser",
+ "password": "testpass"
+}
+
+###
+
+# @name createUser
+POST {{baseUrl}}/users
+Authorization: Bearer {{login.response.body.token}}
+Content-Type: {{contentType}}
+
+{
+ "name": "Test User",
+ "email": "test@example.com",
+ "role": "user"
+}
+
+###
+
+# @name getUser
+GET {{baseUrl}}/users/{{createUser.response.body.id}}
+Authorization: Bearer {{login.response.body.token}}
+
+###
+
+# @name updateUser
+PUT {{baseUrl}}/users/{{createUser.response.body.id}}
+Authorization: Bearer {{login.response.body.token}}
+Content-Type: {{contentType}}
+
+{
+ "name": "Updated Test User",
+ "email": "updated@example.com"
+}
+
+###
+
+# @name deleteUser
+DELETE {{baseUrl}}/users/{{createUser.response.body.id}}
+Authorization: Bearer {{login.response.body.token}}
+```
+
+### Contract Testing
+
+```bash
+#!/bin/bash
+# contract-test.sh
+
+echo "Running API contract tests..."
+
+# Test required fields
+response=$(dotnet-http POST api.example.com/users name="Test" email="test@example.com" --body)
+
+# Validate response structure
+echo $response | jq -e '.id' > /dev/null || { echo "Missing id field"; exit 1; }
+echo $response | jq -e '.name' > /dev/null || { echo "Missing name field"; exit 1; }
+echo $response | jq -e '.email' > /dev/null || { echo "Missing email field"; exit 1; }
+echo $response | jq -e '.created_at' > /dev/null || { echo "Missing created_at field"; exit 1; }
+
+# Validate data types
+[ "$(echo $response | jq -r '.id | type')" = "string" ] || { echo "ID should be string"; exit 1; }
+[ "$(echo $response | jq -r '.name | type')" = "string" ] || { echo "Name should be string"; exit 1; }
+
+echo "✓ All contract tests passed"
+```
+
+## Microservices Testing
+
+### Service Discovery
+
+```bash
+#!/bin/bash
+# test-microservices.sh
+
+SERVICES=("user-service" "order-service" "payment-service" "notification-service")
+BASE_URL="https://api.example.com"
+
+for service in "${SERVICES[@]}"; do
+ echo "Testing $service..."
+
+ # Health check
+ dotnet-http GET $BASE_URL/$service/health
+
+ # Version check
+ VERSION=$(dotnet-http GET $BASE_URL/$service/version --body | jq -r '.version')
+ echo "$service version: $VERSION"
+
+ # Basic functionality test
+ case $service in
+ "user-service")
+ dotnet-http GET $BASE_URL/users/1
+ ;;
+ "order-service")
+ dotnet-http GET $BASE_URL/orders limit==5
+ ;;
+ "payment-service")
+ dotnet-http GET $BASE_URL/payments/methods
+ ;;
+ "notification-service")
+ dotnet-http GET $BASE_URL/notifications/templates
+ ;;
+ esac
+
+ echo "✓ $service test completed"
+ echo
+done
+```
+
+### Cross-Service Integration
+
+```http
+# tests/cross-service.http
+@baseUrl = https://api.example.com
+
+###
+
+# @name createUser
+POST {{baseUrl}}/users
+Content-Type: application/json
+
+{
+ "name": "Integration Test User",
+ "email": "integration@example.com"
+}
+
+###
+
+# @name createOrder
+POST {{baseUrl}}/orders
+Content-Type: application/json
+
+{
+ "user_id": "{{createUser.response.body.id}}",
+ "items": [
+ {"product_id": "prod-123", "quantity": 2},
+ {"product_id": "prod-456", "quantity": 1}
+ ]
+}
+
+###
+
+# @name processPayment
+POST {{baseUrl}}/payments
+Content-Type: application/json
+
+{
+ "order_id": "{{createOrder.response.body.id}}",
+ "amount": "{{createOrder.response.body.total}}",
+ "method": "credit_card",
+ "card_token": "test-token-123"
+}
+
+###
+
+# @name sendNotification
+POST {{baseUrl}}/notifications
+Content-Type: application/json
+
+{
+ "user_id": "{{createUser.response.body.id}}",
+ "type": "order_confirmation",
+ "data": {
+ "order_id": "{{createOrder.response.body.id}}",
+ "payment_id": "{{processPayment.response.body.id}}"
+ }
+}
+```
+
+## Development Workflows
+
+### Local Development
+
+```bash
+#!/bin/bash
+# dev-setup.sh
+
+echo "Setting up local development environment..."
+
+# Start local services
+docker-compose up -d
+
+# Wait for services to be ready
+sleep 10
+
+# Seed test data
+dotnet-http POST localhost:3000/api/seed
+
+# Run initial tests
+dotnet-http exec tests/local-smoke-tests.http --env development
+
+echo "Development environment ready!"
+```
+
+### API Documentation Testing
+
+```bash
+#!/bin/bash
+# test-api-docs.sh
+
+# Extract API endpoints from OpenAPI spec
+ENDPOINTS=$(curl -s https://api.example.com/openapi.json | jq -r '.paths | keys[]')
+
+echo "Testing API endpoints from documentation..."
+
+for endpoint in $ENDPOINTS; do
+ # Convert OpenAPI path to actual URL
+ url="https://api.example.com${endpoint//\{[^}]*\}/123}"
+
+ echo "Testing: $url"
+
+ if dotnet-http GET "$url" > /dev/null 2>&1; then
+ echo "✓ $endpoint"
+ else
+ echo "✗ $endpoint"
+ fi
+done
+```
+
+## Monitoring & Alerting
+
+### Uptime Monitoring
+
+```bash
+#!/bin/bash
+# uptime-monitor.sh
+
+SERVICES=(
+ "https://api.example.com/health"
+ "https://auth.example.com/health"
+ "https://cdn.example.com/status"
+)
+
+for service in "${SERVICES[@]}"; do
+ if ! dotnet-http GET "$service" --check-status; then
+ # Send alert
+ dotnet-http POST "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK" \
+ text="🚨 Service down: $service"
+ fi
+done
+```
+
+### Performance Monitoring
+
+```bash
+#!/bin/bash
+# perf-monitor.sh
+
+ENDPOINT="https://api.example.com/users"
+THRESHOLD=1000 # milliseconds
+
+start_time=$(date +%s%N)
+dotnet-http GET "$ENDPOINT" > /dev/null
+end_time=$(date +%s%N)
+
+duration=$(((end_time - start_time) / 1000000))
+
+if [ $duration -gt $THRESHOLD ]; then
+ echo "⚠️ Slow response detected: ${duration}ms (threshold: ${THRESHOLD}ms)"
+
+ # Send performance alert
+ dotnet-http POST "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK" \
+ text="⚠️ Slow API response: $ENDPOINT took ${duration}ms"
+fi
+```
+
+## Best Practices Summary
+
+1. **Use environment variables** for configuration and secrets
+2. **Implement proper error handling** in scripts
+3. **Create reusable test suites** with .http files
+4. **Combine with other tools** like jq for data processing
+5. **Use meaningful names** for saved requests
+6. **Document your API tests** with comments
+7. **Version control your test files** alongside your code
+8. **Implement retry logic** for flaky endpoints
+9. **Use offline mode** to preview requests
+10. **Monitor and alert** on API health and performance
+
+## Next Steps
+
+- Explore [API testing scenarios](api-testing.md) for more advanced patterns
+- Learn about [integration examples](integrations.md) with other tools
+- Check out [performance tips](../performance-tips.md) for optimization
+- Review [debugging guide](../debugging.md) for troubleshooting
\ No newline at end of file
diff --git a/docs/articles/file-execution.md b/docs/articles/file-execution.md
new file mode 100644
index 0000000..546501d
--- /dev/null
+++ b/docs/articles/file-execution.md
@@ -0,0 +1,479 @@
+# File Execution
+
+dotnet-httpie can execute HTTP requests from `.http` and `.rest` files, making it perfect for API testing, documentation, and automation.
+
+## Overview
+
+The `exec` command allows you to run HTTP requests defined in files, supporting:
+- Standard `.http` and `.rest` file formats
+- Variable substitution
+- Environment-specific configurations
+- Request chaining and referencing
+
+## Basic Usage
+
+### Execute Single File
+
+```bash
+dotnet-http exec requests.http
+```
+
+### Execute with Environment
+
+```bash
+dotnet-http exec requests.http --env production
+```
+
+### Execute Specific Request Type
+
+```bash
+dotnet-http exec requests.http --type http
+dotnet-http exec curl-commands.curl --type curl
+```
+
+## HTTP File Format
+
+### Basic Request
+
+```http
+# Get user information
+GET https://api.example.com/users/123
+Authorization: Bearer your-token
+```
+
+### Multiple Requests
+
+```http
+# Get all users
+GET https://api.example.com/users
+Authorization: Bearer your-token
+
+###
+
+# Create new user
+POST https://api.example.com/users
+Content-Type: application/json
+Authorization: Bearer your-token
+
+{
+ "name": "John Doe",
+ "email": "john@example.com"
+}
+
+###
+
+# Update user
+PUT https://api.example.com/users/123
+Content-Type: application/json
+Authorization: Bearer your-token
+
+{
+ "name": "John Smith",
+ "email": "john.smith@example.com"
+}
+```
+
+### Request with Variables
+
+```http
+@baseUrl = https://api.example.com
+@token = your-bearer-token
+
+# Get user
+GET {{baseUrl}}/users/123
+Authorization: Bearer {{token}}
+
+###
+
+# Create user with dynamic data
+POST {{baseUrl}}/users
+Content-Type: application/json
+Authorization: Bearer {{token}}
+
+{
+ "name": "User {{$randomInt}}",
+ "email": "user{{$randomInt}}@example.com",
+ "timestamp": "{{$datetime iso8601}}"
+}
+```
+
+### Named Requests
+
+```http
+@baseUrl = https://api.example.com
+
+###
+
+# @name getUser
+GET {{baseUrl}}/users/123
+
+###
+
+# @name createUser
+POST {{baseUrl}}/users
+Content-Type: application/json
+
+{
+ "name": "John Doe",
+ "email": "john@example.com"
+}
+```
+
+## Environment Files
+
+### HTTP Client Environment File
+
+Create `http-client.env.json`:
+
+```json
+{
+ "development": {
+ "baseUrl": "http://localhost:3000",
+ "apiKey": "dev-api-key"
+ },
+ "staging": {
+ "baseUrl": "https://staging-api.example.com",
+ "apiKey": "staging-api-key"
+ },
+ "production": {
+ "baseUrl": "https://api.example.com",
+ "apiKey": "prod-api-key"
+ }
+}
+```
+
+### Using Environment Variables
+
+```http
+# This will use variables from the specified environment
+GET {{baseUrl}}/users
+X-API-Key: {{apiKey}}
+```
+
+Execute with specific environment:
+
+```bash
+dotnet-http exec api-requests.http --env production
+```
+
+## Variable Types
+
+### Built-in Variables
+
+```http
+# Random values
+POST {{baseUrl}}/users
+Content-Type: application/json
+
+{
+ "id": "{{$uuid}}",
+ "name": "User {{$randomInt}}",
+ "email": "user{{$randomInt}}@example.com",
+ "timestamp": "{{$datetime iso8601}}",
+ "created": "{{$timestamp}}"
+}
+```
+
+### Environment Variables
+
+```http
+# Access system environment variables
+GET {{baseUrl}}/secure
+Authorization: Bearer {{$env API_TOKEN}}
+```
+
+### Custom Variables
+
+```http
+@userId = 123
+@apiVersion = v2
+
+GET {{baseUrl}}/{{apiVersion}}/users/{{userId}}
+```
+
+## Request Referencing
+
+Reference responses from previous requests:
+
+```http
+# @name login
+POST {{baseUrl}}/auth/login
+Content-Type: application/json
+
+{
+ "username": "admin",
+ "password": "password"
+}
+
+###
+
+# Use token from login response
+GET {{baseUrl}}/protected/data
+Authorization: Bearer {{login.response.body.token}}
+
+###
+
+# Reference request headers
+GET {{baseUrl}}/audit
+X-Original-Request-Id: {{login.request.headers.X-Request-ID}}
+```
+
+## Curl File Execution
+
+dotnet-httpie can also execute curl commands from files:
+
+### Curl File Format
+
+```bash
+# file: api-calls.curl
+
+# Get user data
+curl -X GET "https://api.example.com/users/123" \
+ -H "Authorization: Bearer token" \
+ -H "Accept: application/json"
+
+# Create new user
+curl -X POST "https://api.example.com/users" \
+ -H "Content-Type: application/json" \
+ -H "Authorization: Bearer token" \
+ -d '{
+ "name": "John Doe",
+ "email": "john@example.com"
+ }'
+```
+
+### Execute Curl File
+
+```bash
+dotnet-http exec api-calls.curl --type curl
+```
+
+## Advanced Features
+
+### Request Chaining
+
+```http
+# @name createUser
+POST {{baseUrl}}/users
+Content-Type: application/json
+
+{
+ "name": "John Doe",
+ "email": "john@example.com"
+}
+
+###
+
+# @name getUserProfile
+# @depends createUser
+GET {{baseUrl}}/users/{{createUser.response.body.id}}/profile
+
+###
+
+# @name updateProfile
+# @depends getUserProfile
+PUT {{baseUrl}}/users/{{createUser.response.body.id}}/profile
+Content-Type: application/json
+
+{
+ "bio": "Updated bio",
+ "avatar": "{{getUserProfile.response.body.avatar}}"
+}
+```
+
+## Testing and Validation
+
+### Response Assertions
+
+```http
+GET {{baseUrl}}/users/123
+
+# Test response
+# @test status === 200
+# @test response.body.name === "John Doe"
+# @test response.headers["content-type"] includes "application/json"
+```
+
+### Schema Validation
+
+```http
+POST {{baseUrl}}/users
+Content-Type: application/json
+
+{
+ "name": "John Doe",
+ "email": "john@example.com"
+}
+
+# Validate response against JSON schema
+# @schema user-schema.json
+```
+
+## Debugging File Execution
+
+### Debug Mode
+
+```bash
+dotnet-http exec requests.http --debug
+```
+
+### Offline Mode (Preview)
+
+```bash
+dotnet-http exec requests.http --offline
+```
+
+This shows what requests would be sent without actually executing them.
+
+### Verbose Output
+
+```bash
+dotnet-http exec requests.http --verbose
+```
+
+## Organization Strategies
+
+### Project Structure
+
+```
+project/
+├── api-tests/
+│ ├── auth/
+│ │ ├── login.http
+│ │ └── logout.http
+│ ├── users/
+│ │ ├── create-user.http
+│ │ ├── get-user.http
+│ │ └── update-user.http
+│ └── http-client.env.json
+├── environments/
+│ ├── development.env.json
+│ ├── staging.env.json
+│ └── production.env.json
+└── scripts/
+ ├── setup.http
+ ├── cleanup.http
+ └── health-check.http
+```
+
+### File Naming Conventions
+
+- Use descriptive names: `create-user.http`, `get-order-details.http`
+- Group by feature: `auth/`, `users/`, `orders/`
+- Use environment prefixes: `dev-setup.http`, `prod-health.http`
+
+## CI/CD Integration
+
+### GitHub Actions Example
+
+```yaml
+name: API Tests
+on: [push, pull_request]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: '8.0'
+ - name: Install dotnet-httpie
+ run: dotnet tool install --global dotnet-httpie
+ - name: Run API tests
+ run: dotnet-http exec tests/api-tests.http --env testing
+```
+
+### Azure DevOps Example
+
+```yaml
+steps:
+- task: DotNetCoreCLI@2
+ displayName: 'Install dotnet-httpie'
+ inputs:
+ command: 'custom'
+ custom: 'tool'
+ arguments: 'install --global dotnet-httpie'
+
+- script: dotnet-http exec api-tests/health-check.http --env $(Environment)
+ displayName: 'Run Health Check'
+```
+
+## Best Practices
+
+1. **Use environment files** for different deployment environments
+2. **Name your requests** for better organization and referencing
+3. **Group related requests** in the same file
+4. **Use variables** instead of hardcoding values
+5. **Add comments** to explain complex requests
+6. **Validate responses** where critical
+7. **Test offline first** to verify request structure
+8. **Version control** your HTTP files alongside your code
+
+## Examples
+
+### Complete API Test Suite
+
+```http
+@baseUrl = https://api.example.com
+@contentType = application/json
+
+###
+
+# @name healthCheck
+GET {{baseUrl}}/health
+
+###
+
+# @name authenticate
+POST {{baseUrl}}/auth/login
+Content-Type: {{contentType}}
+
+{
+ "username": "testuser",
+ "password": "testpass"
+}
+
+###
+
+# @name createUser
+POST {{baseUrl}}/users
+Authorization: Bearer {{authenticate.response.body.token}}
+Content-Type: {{contentType}}
+
+{
+ "name": "Test User",
+ "email": "test@example.com"
+}
+
+###
+
+# @name getUser
+GET {{baseUrl}}/users/{{createUser.response.body.id}}
+Authorization: Bearer {{authenticate.response.body.token}}
+
+###
+
+# @name updateUser
+PUT {{baseUrl}}/users/{{createUser.response.body.id}}
+Authorization: Bearer {{authenticate.response.body.token}}
+Content-Type: {{contentType}}
+
+{
+ "name": "Updated Test User"
+}
+
+###
+
+# @name deleteUser
+DELETE {{baseUrl}}/users/{{createUser.response.body.id}}
+Authorization: Bearer {{authenticate.response.body.token}}
+```
+
+## Next Steps
+
+- Learn about [variable substitution](variables.md) in detail
+- Explore [request referencing](request-referencing.md) patterns
+- Set up [CI/CD integration](ci-cd-integration.md) with HTTP files
+- Check [common use cases](examples/common-use-cases.md) for more examples
\ No newline at end of file
diff --git a/docs/articles/http-requests.md b/docs/articles/http-requests.md
new file mode 100644
index 0000000..8d4b854
--- /dev/null
+++ b/docs/articles/http-requests.md
@@ -0,0 +1,336 @@
+# HTTP Requests
+
+This guide covers how to make various types of HTTP requests using dotnet-httpie.
+
+## HTTP Methods
+
+dotnet-httpie supports all standard HTTP methods. If no method is specified, GET is used by default.
+
+### GET Requests
+
+```bash
+# Simple GET
+dotnet-http httpbin.org/get
+
+# GET with query parameters
+dotnet-http httpbin.org/get name==John age==30
+
+# GET with headers
+dotnet-http httpbin.org/get Authorization:"Bearer token"
+```
+
+### POST Requests
+
+```bash
+# JSON POST request
+dotnet-http POST httpbin.org/post name=John email=john@example.com
+
+# Form data POST request
+dotnet-http POST httpbin.org/post --form name=John email=john@example.com
+
+# Raw data POST request
+dotnet-http POST httpbin.org/post --raw "Custom raw data"
+```
+
+### PUT Requests
+
+```bash
+# Update resource
+dotnet-http PUT api.example.com/users/123 name="John Smith" email="john.smith@example.com"
+
+# Replace entire resource
+dotnet-http PUT api.example.com/users/123 @user.json
+```
+
+### PATCH Requests
+
+```bash
+# Partial update
+dotnet-http PATCH api.example.com/users/123 email="newemail@example.com"
+```
+
+### DELETE Requests
+
+```bash
+# Delete resource
+dotnet-http DELETE api.example.com/users/123
+
+# Delete with confirmation header
+dotnet-http DELETE api.example.com/users/123 X-Confirm:"yes"
+```
+
+### HEAD Requests
+
+```bash
+# Get headers only
+dotnet-http HEAD httpbin.org/get
+```
+
+### OPTIONS Requests
+
+```bash
+# Check allowed methods
+dotnet-http OPTIONS api.example.com/users
+```
+
+## Request URLs
+
+### Full URLs
+
+```bash
+dotnet-http https://api.example.com/users
+dotnet-http http://localhost:3000/api/data
+```
+
+### Shortened Local URLs
+
+```bash
+# These are equivalent to http://localhost:PORT
+dotnet-http :3000/api/users
+dotnet-http localhost:3000/api/users
+```
+
+### URL with Parameters
+
+```bash
+# Query parameters are added automatically
+dotnet-http api.example.com/search q==httpie type==tool
+# Results in: api.example.com/search?q=httpie&type=tool
+```
+
+## Request Headers
+
+### Standard Headers
+
+```bash
+# Authorization
+dotnet-http api.example.com/protected Authorization:"Bearer jwt-token"
+
+# Content-Type
+dotnet-http POST api.example.com/data Content-Type:"application/xml" @data.xml
+
+# User-Agent
+dotnet-http api.example.com/get User-Agent:"MyApp/1.0"
+
+# Accept
+dotnet-http api.example.com/data Accept:"application/json"
+```
+
+### Custom Headers
+
+```bash
+# API keys
+dotnet-http api.example.com/data X-API-Key:"your-api-key"
+
+# Custom headers
+dotnet-http api.example.com/data X-Custom-Header:"custom-value"
+```
+
+### Multiple Headers
+
+```bash
+dotnet-http api.example.com/data \
+ Authorization:"Bearer token" \
+ X-API-Key:"api-key" \
+ User-Agent:"MyApp/1.0" \
+ Accept:"application/json"
+```
+
+## Request Body
+
+### JSON Body (Default)
+
+```bash
+# Simple JSON
+dotnet-http POST api.example.com/users name=John age:=30 active:=true
+
+# Nested JSON
+dotnet-http POST api.example.com/users name=John address[city]=Seattle address[country]=USA
+
+# Array values
+dotnet-http POST api.example.com/users name=John tags:='["developer", "dotnet"]'
+
+# Raw JSON objects
+dotnet-http POST api.example.com/users profile:='{"name": "John", "age": 30}'
+```
+
+### Form Data
+
+```bash
+# URL-encoded form data
+dotnet-http POST httpbin.org/post --form name=John email=john@example.com
+```
+
+### Raw Data
+
+```bash
+# Send raw string
+dotnet-http POST api.example.com/webhook --raw "Raw webhook payload"
+
+# Send from stdin
+echo "data" | dotnet-http POST api.example.com/data
+```
+
+## Complex JSON Structures
+
+### Nested Objects
+
+```bash
+dotnet-http POST api.example.com/users \
+ name=John \
+ address[street]="123 Main St" \
+ address[city]=Seattle \
+ address[zipcode]:=98101
+```
+
+### Arrays
+
+```bash
+# Array of strings
+dotnet-http POST api.example.com/users name=John skills:='["C#", "JavaScript", "Python"]'
+
+# Array of numbers
+dotnet-http POST api.example.com/data values:='[1, 2, 3, 4, 5]'
+
+# Array of objects
+dotnet-http POST api.example.com/batch items:='[{"id": 1, "name": "Item 1"}, {"id": 2, "name": "Item 2"}]'
+```
+
+### Boolean and Null Values
+
+```bash
+# Boolean values
+dotnet-http POST api.example.com/users name=John active:=true verified:=false
+
+# Null values
+dotnet-http POST api.example.com/users name=John middle_name:=null
+
+# Numbers
+dotnet-http POST api.example.com/users name=John age:=30 salary:=50000.50
+```
+
+## Response Handling
+
+### View Full Response
+
+```bash
+# Default: shows headers and body
+dotnet-http httpbin.org/get
+```
+
+### Body Only
+
+```bash
+# Show only response body
+dotnet-http httpbin.org/get --body
+```
+
+### Headers Only
+
+```bash
+# Show only response headers
+dotnet-http HEAD httpbin.org/get
+```
+
+### Save Response
+
+```bash
+# Save to file
+dotnet-http httpbin.org/get > response.json
+
+# Download files
+dotnet-http httpbin.org/image/png --download
+```
+
+## Error Handling
+
+### HTTP Error Codes
+
+```bash
+# dotnet-httpie shows HTTP errors clearly
+dotnet-http httpbin.org/status/404
+dotnet-http httpbin.org/status/500
+```
+
+### Timeout Configuration
+
+```bash
+# Set request timeout (if supported by middleware)
+dotnet-http api.example.com/slow-endpoint --timeout 30
+```
+
+## Advanced Features
+
+### Follow Redirects
+
+```bash
+# Automatically follow redirects
+dotnet-http httpbin.org/redirect/3 --follow
+```
+
+### Ignore SSL Errors
+
+```bash
+# For development/testing only
+dotnet-http https://self-signed.badssl.com/ --verify=no
+```
+
+### Proxy Support
+
+```bash
+# Use proxy
+dotnet-http httpbin.org/get --proxy http://proxy.example.com:8080
+```
+
+## Examples with Real APIs
+
+### GitHub API
+
+```bash
+# Get user info
+dotnet-http api.github.com/users/octocat
+
+# Get repositories (with authentication)
+dotnet-http api.github.com/user/repos Authorization:"token your-token"
+
+# Create issue
+dotnet-http POST api.github.com/repos/owner/repo/issues \
+ Authorization:"token your-token" \
+ title="Bug report" \
+ body="Description of the bug"
+```
+
+### REST API CRUD Operations
+
+```bash
+# Create
+dotnet-http POST api.example.com/articles \
+ title="My Article" \
+ content="Article content" \
+ published:=false
+
+# Read
+dotnet-http GET api.example.com/articles/123
+
+# Update
+dotnet-http PUT api.example.com/articles/123 \
+ title="Updated Article" \
+ published:=true
+
+# Delete
+dotnet-http DELETE api.example.com/articles/123
+```
+
+## Best Practices
+
+1. **Use meaningful names** for your request files and variables
+2. **Store sensitive data** like API keys in environment variables
+3. **Use --offline mode** to preview requests before sending
+4. **Combine with jq** for JSON processing: `dotnet-http api.example.com/data | jq .`
+5. **Use files for complex data** instead of inline JSON for better maintainability
+
+## Next Steps
+
+- Learn about [authentication methods](authentication.md)
+- Explore [file execution](file-execution.md) for repeatable requests
+- Check out [variable substitution](variables.md) for dynamic requests
diff --git a/docs/articles/installation.md b/docs/articles/installation.md
new file mode 100644
index 0000000..05bb92f
--- /dev/null
+++ b/docs/articles/installation.md
@@ -0,0 +1,145 @@
+# Installation
+
+This guide covers how to install dotnet-httpie on different platforms and environments.
+
+## Prerequisites
+
+- .NET SDK 8.0 or later
+- Internet connection for package installation
+
+## Global Tool Installation (Recommended)
+
+### Install Latest Stable Version
+
+```bash
+dotnet tool update --global dotnet-httpie
+```
+
+### Install Latest Preview Version
+
+```bash
+dotnet tool update --global dotnet-httpie --prerelease
+```
+
+### Install Specific Version
+
+```bash
+dotnet tool install --global dotnet-httpie --version 0.12.0
+```
+
+## Alternative Installation Methods
+
+### Option 2: Pre-built Binaries
+
+Download platform-specific executables from [GitHub Releases](https://github.com/WeihanLi/dotnet-httpie/releases):
+
+- **Windows**: `dotnet-httpie-win-x64.exe`
+- **Linux**: `dotnet-httpie-linux-x64`
+- **macOS**: `dotnet-httpie-osx-x64`
+
+Extract and add to your system PATH for global access.
+
+### Option 3: Docker
+
+See the [Docker Usage Guide](docker-usage.md) for containerized usage.
+
+## Verification
+
+After installation, verify that dotnet-httpie is working correctly:
+
+```bash
+dotnet-http --version
+```
+
+You should see output similar to:
+```
+dotnet-httpie/0.12.0 (.NET; HTTPie-like)
+```
+
+## Docker Installation
+
+If you prefer using Docker instead of installing globally:
+
+### Pull Latest Image
+
+```bash
+docker pull weihanli/dotnet-httpie:latest
+```
+
+### Use Without Installation
+
+```bash
+docker run --rm weihanli/dotnet-httpie:latest --help
+```
+
+## Updating
+
+### Update Global Tool
+
+```bash
+dotnet tool update --global dotnet-httpie
+```
+
+### Update to Preview Version
+
+```bash
+dotnet tool update --global dotnet-httpie --prerelease
+```
+
+## Uninstallation
+
+### Remove Global Tool
+
+```bash
+dotnet tool uninstall --global dotnet-httpie
+```
+
+### Remove Docker Image
+
+```bash
+docker rmi weihanli/dotnet-httpie:latest
+```
+
+## Troubleshooting Installation
+
+### Common Issues
+
+1. **Permission Denied**: Make sure you have proper permissions to install global tools
+2. **PATH Issues**: Ensure the .NET tools directory is in your PATH
+3. **Old .NET Version**: Verify you have .NET 8.0 or later installed
+
+### Check .NET Version
+
+```bash
+dotnet --version
+```
+
+### Check Installed Tools
+
+```bash
+dotnet tool list --global
+```
+
+### Reinstall if Corrupted
+
+```bash
+dotnet tool uninstall --global dotnet-httpie
+dotnet tool install --global dotnet-httpie
+```
+
+## Platform-Specific Notes
+
+### Windows
+- Tools are installed to `%USERPROFILE%\.dotnet\tools`
+- May require restart of command prompt/PowerShell
+
+### macOS/Linux
+- Tools are installed to `~/.dotnet/tools`
+- May need to restart terminal session
+
+### CI/CD Environments
+See [CI/CD Integration](ci-cd-integration.md) for specific setup instructions for continuous integration environments.
+
+## Next Steps
+
+Once installed, continue with the [Quick Start Guide](quick-start.md) to begin using dotnet-httpie.
\ No newline at end of file
diff --git a/docs/articles/quick-start.md b/docs/articles/quick-start.md
new file mode 100644
index 0000000..ed03b1e
--- /dev/null
+++ b/docs/articles/quick-start.md
@@ -0,0 +1,178 @@
+# Quick Start Guide
+
+Get up and running with dotnet-httpie in minutes! This guide shows you the essential commands to start making HTTP requests.
+
+## Your First Request
+
+Make a simple GET request:
+
+```bash
+dotnet-http httpbin.org/get
+```
+
+This will send a GET request to httpbin.org and display the response.
+
+## Basic Command Structure
+
+```
+dotnet-http [flags] [METHOD] URL [ITEM [ITEM]]
+```
+
+Where:
+- `flags`: Optional command flags (e.g., `--offline`, `--debug`)
+- `METHOD`: HTTP method (GET, POST, PUT, DELETE, etc.) - defaults to GET
+- `URL`: The target URL
+- `ITEM`: Request items (query parameters, headers, data)
+
+## Request Item Types
+
+dotnet-httpie supports three types of request items:
+
+| Type | Syntax | Example | Description |
+|------|--------|---------|-------------|
+| Query Parameters | `name==value` | `search==dotnet` | URL query parameters |
+| Headers | `name:value` | `Authorization:Bearer token` | HTTP headers |
+| JSON Data | `name=value` | `title=hello` | JSON request body fields |
+| Raw JSON | `name:=value` | `age:=25` | Raw JSON values (numbers, booleans, objects) |
+
+## Common Examples
+
+### GET with Query Parameters
+
+```bash
+dotnet-http httpbin.org/get search==httpie limit==10
+```
+
+### POST with JSON Data
+
+```bash
+dotnet-http POST httpbin.org/post title=Hello body="World"
+```
+
+### Custom Headers
+
+```bash
+dotnet-http httpbin.org/headers Authorization:"Bearer your-token" User-Agent:"MyApp/1.0"
+```
+
+### Mixed Request Types
+
+```bash
+dotnet-http POST api.example.com/users \
+ Authorization:"Bearer token" \
+ name="John Doe" \
+ age:=30 \
+ active:=true \
+ search==users
+```
+
+## Working with APIs
+
+### RESTful API Example
+
+```bash
+# List users
+dotnet-http GET api.example.com/users
+
+# Get specific user
+dotnet-http GET api.example.com/users/123
+
+# Create new user
+dotnet-http POST api.example.com/users name="John" email="john@example.com"
+
+# Update user
+dotnet-http PUT api.example.com/users/123 name="John Smith"
+
+# Delete user
+dotnet-http DELETE api.example.com/users/123
+```
+
+### JSON API with Authentication
+
+```bash
+dotnet-http POST api.example.com/posts \
+ Authorization:"Bearer your-jwt-token" \
+ Content-Type:"application/json" \
+ title="My Post" \
+ content="This is my post content" \
+ published:=true
+```
+
+## Useful Flags
+
+### Offline Mode (Preview Request)
+
+```bash
+dotnet-http POST api.example.com/data name=test --offline
+```
+
+This shows what request would be sent without actually sending it.
+
+### Debug Mode
+
+```bash
+dotnet-http httpbin.org/get --debug
+```
+
+Enables detailed logging and debugging information.
+
+### Response Body Only
+
+```bash
+dotnet-http httpbin.org/get --body
+```
+
+Shows only the response body, useful for piping to other tools.
+
+## File Operations
+
+### Execute HTTP Files
+
+```bash
+dotnet-http exec requests.http
+```
+
+### Download Files
+
+```bash
+dotnet-http httpbin.org/image/png --download
+```
+
+## Docker Usage
+
+If you're using the Docker version:
+
+```bash
+# Basic request
+docker run --rm weihanli/dotnet-httpie:latest httpbin.org/get
+
+# With data
+docker run --rm weihanli/dotnet-httpie:latest POST httpbin.org/post name=test
+```
+
+## Local Development
+
+For local APIs, you can use shortened URLs:
+
+```bash
+# Instead of http://localhost:5000/api/users
+dotnet-http :5000/api/users
+
+# Or
+dotnet-http localhost:5000/api/users
+```
+
+## Next Steps
+
+Now that you're familiar with the basics:
+
+1. Learn about [advanced request data types](request-data-types.md)
+2. Explore [file execution capabilities](file-execution.md)
+3. Set up [authentication](authentication.md) for your APIs
+4. Check out [common use cases](examples/common-use-cases.md)
+
+## Need Help?
+
+- Use `dotnet-http --help` for command-line help
+- See [debugging guide](debugging.md) for troubleshooting
+- Check [examples](examples/common-use-cases.md) for more usage patterns
\ No newline at end of file
diff --git a/docs/articles/reference/command-line-options.md b/docs/articles/reference/command-line-options.md
new file mode 100644
index 0000000..326a6a4
--- /dev/null
+++ b/docs/articles/reference/command-line-options.md
@@ -0,0 +1,376 @@
+# Command Line Options Reference
+
+This comprehensive reference covers all command line options and flags available in dotnet-httpie.
+
+## Command Syntax
+
+```
+dotnet-http [global-flags] [METHOD] URL [request-items...] [request-flags]
+```
+
+## Global Flags
+
+### Help and Version
+
+| Flag | Description | Example |
+|------|-------------|---------|
+| `--help`, `-h` | Show help information | `dotnet-http --help` |
+| `--version` | Show version information | `dotnet-http --version` |
+
+### Debug and Logging
+
+| Flag | Description | Example |
+|------|-------------|---------|
+| `--debug` | Enable debug mode with detailed logging | `dotnet-http GET api.example.com --debug` |
+| `--verbose`, `-v` | Enable verbose output | `dotnet-http GET api.example.com --verbose` |
+| `--quiet`, `-q` | Suppress non-error output | `dotnet-http GET api.example.com --quiet` |
+
+### Request Preview
+
+| Flag | Description | Example |
+|------|-------------|---------|
+| `--offline` | Preview request without sending | `dotnet-http POST api.example.com --offline` |
+| `--print` | Specify what to print (request/response) | `dotnet-http GET api.example.com --print=HhBb` |
+
+## HTTP Methods
+
+All standard HTTP methods are supported:
+
+```bash
+# GET (default)
+dotnet-http GET api.example.com/users
+dotnet-http api.example.com/users # GET is default when there's no body data parameter
+
+# POST
+dotnet-http POST api.example.com/users
+
+# PUT
+dotnet-http PUT api.example.com/users/123
+
+# PATCH
+dotnet-http PATCH api.example.com/users/123
+
+# DELETE
+dotnet-http DELETE api.example.com/users/123
+
+# HEAD
+dotnet-http HEAD api.example.com/users
+
+# OPTIONS
+dotnet-http OPTIONS api.example.com/users
+```
+
+## Request Flags
+
+### Authentication
+
+| Flag | Description | Example |
+|------|-------------|---------|
+| `--auth`, `-a` | Basic authentication | `dotnet-http GET api.example.com --auth user:pass` |
+| `--auth-type` | Authentication type | `dotnet-http GET api.example.com --auth-type bearer` |
+
+### Request Body
+
+| Flag | Description | Example |
+|------|-------------|---------|
+| `--json`, `-j` | Force JSON content type | `dotnet-http POST api.example.com --json` |
+| `--form`, `-f` | Send as form data | `dotnet-http POST api.example.com --form` |
+| `--raw` | Send raw data | `dotnet-http POST api.example.com --raw "text data"` |
+
+### File Operations
+
+| Flag | Description | Example |
+|------|-------------|---------|
+| `--download`, `-d` | Download response to file | `dotnet-http GET api.example.com/file.pdf --download` |
+| `--output`, `-o` | Save response to specific file | `dotnet-http GET api.example.com/data --output data.json` |
+| `--continue`, `-C` | Resume interrupted download | `dotnet-http GET api.example.com/large.zip --download --continue` |
+
+
+
+## Execute Command Options
+
+The `exec` command has its own set of options:
+
+```bash
+dotnet-http exec [options] [file-path]
+```
+
+### Execute Flags
+
+| Flag | Description | Example |
+|------|-------------|---------|
+| `--env` | Environment to use | `dotnet-http exec requests.http --env production` |
+| `--type`, `-t` | Script type (http/curl) | `dotnet-http exec script.curl --type curl` |
+| `--debug` | Debug mode for execution | `dotnet-http exec requests.http --debug` |
+| `--offline` | Preview execution without sending | `dotnet-http exec requests.http --offline` |
+
+### Supported Script Types
+
+| Type | Description | File Extensions |
+|------|-------------|-----------------|
+| `http` | HTTP request files | `.http`, `.rest` |
+| `curl` | cURL command files | `.curl`, `.sh` |
+
+## Request Item Types
+
+### Query Parameters
+
+```bash
+# Syntax: name==value
+dotnet-http GET api.example.com/search query==httpie limit==10
+```
+
+### Headers
+
+```bash
+# Syntax: name:value
+dotnet-http GET api.example.com/data Authorization:"Bearer token"
+```
+
+### JSON Fields
+
+```bash
+# Syntax: name=value (creates JSON)
+dotnet-http POST api.example.com/users name=John email=john@example.com
+```
+
+### Raw JSON Values
+
+```bash
+# Syntax: name:=value (typed JSON)
+dotnet-http POST api.example.com/users age:=30 active:=true
+```
+
+
+
+## Output Formats
+
+### Response Output Control
+
+```bash
+# Default: headers + body
+dotnet-http GET api.example.com/users
+
+# Headers only
+dotnet-http HEAD api.example.com/users
+
+# Body only
+dotnet-http GET api.example.com/users --body
+
+# Specific components with --print
+dotnet-http GET api.example.com/users --print=HhBb
+```
+
+### Print Option Values
+
+| Code | Component |
+|------|-----------|
+| `H` | Request headers |
+| `B` | Request body |
+| `h` | Response headers |
+| `b` | Response body |
+| `p` | Request/Response properties |
+
+## Exit Codes
+
+| Code | Meaning |
+|------|---------|
+| `0` | Success |
+| `1` | Generic error |
+| `2` | Request timeout |
+| `3` | Too many redirects |
+| `4` | HTTP 4xx error |
+| `5` | HTTP 5xx error |
+| `6` | Network error |
+
+## Examples by Category
+
+### Basic Requests
+
+```bash
+# Simple GET
+dotnet-http GET httpbin.org/get
+
+# POST with data
+dotnet-http POST httpbin.org/post name=John age:=30
+
+# Custom headers
+dotnet-http GET httpbin.org/headers User-Agent:"MyApp/1.0"
+```
+
+### Authentication Examples
+
+```bash
+# Bearer token
+dotnet-http GET api.example.com/protected Authorization:"Bearer token"
+
+# Basic auth
+dotnet-http GET api.example.com/secure --auth user:pass
+
+# API key
+dotnet-http GET api.example.com/data X-API-Key:"key123"
+```
+
+### File Operations
+
+```bash
+# Download file
+dotnet-http GET api.example.com/report.pdf --download
+
+# Send file as body
+dotnet-http POST api.example.com/data @data.json
+```
+
+### Form Data
+
+```bash
+# URL-encoded form
+dotnet-http POST httpbin.org/post --form name=John email=john@example.com
+```
+
+### Response Handling
+
+```bash
+# Save response
+dotnet-http GET api.example.com/data --output response.json
+
+# Body only to stdout
+dotnet-http GET api.example.com/data --body
+
+# Headers only
+dotnet-http HEAD api.example.com/data
+```
+
+### Network Options
+
+```bash
+# With proxy
+dotnet-http GET api.example.com/data --proxy http://proxy:8080
+
+# Custom timeout
+dotnet-http GET api.example.com/slow --timeout 60
+
+# Skip SSL verification
+dotnet-http GET https://self-signed.local --verify=no
+```
+
+### Debug and Development
+
+```bash
+# Debug mode
+dotnet-http GET api.example.com/data --debug
+
+# Preview request
+dotnet-http POST api.example.com/users name=John --offline
+
+# Verbose output
+dotnet-http GET api.example.com/data --verbose
+```
+
+## Advanced Usage Patterns
+
+### Environment-Specific Requests
+
+```bash
+# Development
+dotnet-http GET localhost:3000/api/users --debug
+
+# Staging
+dotnet-http GET staging-api.example.com/users \
+ Authorization:"Bearer $STAGING_TOKEN"
+
+# Production
+dotnet-http GET api.example.com/users \
+ Authorization:"Bearer $PROD_TOKEN" \
+ --timeout 30
+```
+
+### Conditional Requests
+
+```bash
+# Check status code
+if dotnet-http GET api.example.com/health --check-status; then
+ echo "API is healthy"
+fi
+
+# With error handling
+dotnet-http GET api.example.com/data || echo "Request failed"
+```
+
+### Scripting Integration
+
+```bash
+# Extract data for further processing
+USER_ID=$(dotnet-http POST api.example.com/users name=John --body | jq -r '.id')
+dotnet-http GET "api.example.com/users/$USER_ID/profile"
+
+# Batch operations
+for user in alice bob charlie; do
+ dotnet-http POST api.example.com/users name="$user"
+done
+```
+
+## Migration from Other Tools
+
+### From cURL
+
+```bash
+# cURL
+curl -X POST https://api.example.com/users \
+ -H "Content-Type: application/json" \
+ -H "Authorization: Bearer token" \
+ -d '{"name": "John", "age": 30}'
+
+# dotnet-httpie equivalent
+dotnet-http POST api.example.com/users \
+ Authorization:"Bearer token" \
+ name=John \
+ age:=30
+```
+
+### From HTTPie
+
+```bash
+# HTTPie
+http POST api.example.com/users Authorization:"Bearer token" name=John age:=30
+
+# dotnet-httpie (very similar)
+dotnet-http POST api.example.com/users Authorization:"Bearer token" name=John age:=30
+```
+
+## Platform-Specific Notes
+
+### Windows
+
+```powershell
+# PowerShell escaping
+dotnet-http POST api.example.com/users name=John tags:='[\"web\", \"api\"]'
+
+# Command Prompt escaping
+dotnet-http POST api.example.com/users name=John tags:="[\"web\", \"api\"]"
+```
+
+### macOS/Linux
+
+```bash
+# Bash/Zsh (standard escaping)
+dotnet-http POST api.example.com/users name=John tags:='["web", "api"]'
+
+# Fish shell
+dotnet-http POST api.example.com/users name=John tags:=\'["web", "api"]\'
+```
+
+## Performance Tips
+
+1. **Use `--body` for piping**: Avoids header processing overhead
+2. **Reuse connections**: Use session management where available
+3. **Minimize debug output**: Only use `--debug` when troubleshooting
+4. **Optimize JSON**: Use `:=` for numbers/booleans instead of strings
+5. **Batch requests**: Use file execution for multiple related requests
+
+## Next Steps
+
+- Review [common use cases](../examples/common-use-cases.md) for practical applications
+- Learn about [file execution](../file-execution.md) for advanced workflows
+- Check [debugging guide](../debugging.md) for troubleshooting
+- Explore [Docker usage](../docker-usage.md) for containerized environments
\ No newline at end of file
diff --git a/docs/articles/request-data-types.md b/docs/articles/request-data-types.md
new file mode 100644
index 0000000..ea1d558
--- /dev/null
+++ b/docs/articles/request-data-types.md
@@ -0,0 +1,460 @@
+# Request Data Types
+
+This guide explains the different ways to structure and send data with your HTTP requests using dotnet-httpie.
+
+## Overview
+
+dotnet-httpie supports multiple request data formats and provides intuitive syntax for different data types:
+
+- **Query Parameters**: `name==value`
+- **Headers**: `name:value`
+- **JSON Fields**: `name=value`
+- **Raw JSON Values**: `name:=value`
+
+## Query Parameters
+
+Query parameters are appended to the URL and use the `==` syntax.
+
+### Basic Query Parameters
+
+```bash
+# Single parameter
+dotnet-http httpbin.org/get search==httpie
+
+# Multiple parameters
+dotnet-http httpbin.org/get search==httpie lang==en page==1
+
+# URL encoding is automatic
+dotnet-http httpbin.org/get query=="hello world" special=="chars!@#"
+```
+
+### Arrays in Query Parameters
+
+```bash
+# Multiple values for same parameter
+dotnet-http httpbin.org/get tags==javascript tags==web tags==api
+
+# Results in: ?tags=javascript&tags=web&tags=api
+```
+
+### Empty Values
+
+```bash
+# Empty parameter
+dotnet-http httpbin.org/get empty==
+
+# Null parameter (omitted)
+dotnet-http httpbin.org/get param==null
+```
+
+## HTTP Headers
+
+Headers use the `:` syntax and control how requests are processed.
+
+### Common Headers
+
+```bash
+# Authorization
+dotnet-http httpbin.org/headers Authorization:"Bearer jwt-token"
+
+# Content-Type
+dotnet-http POST httpbin.org/post Content-Type:"application/xml"
+
+# User-Agent
+dotnet-http httpbin.org/headers User-Agent:"MyApp/1.0"
+
+# Accept
+dotnet-http httpbin.org/headers Accept:"application/json, text/plain"
+
+# API Keys
+dotnet-http api.example.com/data X-API-Key:"your-api-key"
+```
+
+### Custom Headers
+
+```bash
+# Multiple custom headers
+dotnet-http api.example.com/webhook \
+ X-Webhook-Source:"github" \
+ X-Signature:"sha256=signature" \
+ X-Event-Type:"push"
+```
+
+### Header Values with Spaces
+
+```bash
+# Quote values containing spaces
+dotnet-http httpbin.org/headers User-Agent:"My Application v1.0"
+```
+
+## JSON Request Body
+
+### Simple JSON Fields
+
+Using `=` creates JSON fields automatically:
+
+```bash
+dotnet-http POST httpbin.org/post name=John email=john@example.com
+
+# Generates:
+# {
+# "name": "John",
+# "email": "john@example.com"
+# }
+```
+
+### Data Types
+
+#### Strings (Default)
+
+```bash
+dotnet-http POST httpbin.org/post title="Hello World" description="A test post"
+```
+
+#### Numbers
+
+```bash
+# Integers
+dotnet-http POST httpbin.org/post age:=30 count:=100
+
+# Floats
+dotnet-http POST httpbin.org/post price:=19.99 rating:=4.5
+```
+
+#### Booleans
+
+```bash
+dotnet-http POST httpbin.org/post active:=true verified:=false published:=true
+```
+
+#### Null Values
+
+```bash
+dotnet-http POST httpbin.org/post middle_name:=null optional_field:=null
+```
+
+#### Arrays
+
+```bash
+# Array of strings
+dotnet-http POST httpbin.org/post tags:='["javascript", "web", "api"]'
+
+# Array of numbers
+dotnet-http POST httpbin.org/post scores:='[95, 87, 92, 78]'
+
+# Array of objects
+dotnet-http POST httpbin.org/post items:='[{"id": 1, "name": "Item 1"}, {"id": 2, "name": "Item 2"}]'
+```
+
+#### Objects
+
+```bash
+# Nested objects
+dotnet-http POST httpbin.org/post profile:='{"name": "John", "age": 30, "skills": ["C#", "JavaScript"]}'
+
+# Complex nested structure
+dotnet-http POST httpbin.org/post config:='{"database": {"host": "localhost", "port": 5432}, "features": {"auth": true, "cache": false}}'
+```
+
+## Nested JSON Structures
+
+### Bracket Notation
+
+```bash
+# Nested objects using bracket notation
+dotnet-http POST httpbin.org/post \
+ user[name]=John \
+ user[email]=john@example.com \
+ user[address][street]="123 Main St" \
+ user[address][city]=Seattle \
+ user[address][zipcode]:=98101
+
+# Generates:
+# {
+# "user": {
+# "name": "John",
+# "email": "john@example.com",
+# "address": {
+# "street": "123 Main St",
+# "city": "Seattle",
+# "zipcode": 98101
+# }
+# }
+# }
+```
+
+### Array Elements
+
+```bash
+# Array with indexed elements
+dotnet-http POST httpbin.org/post \
+ items[0][name]=First \
+ items[0][value]:=100 \
+ items[1][name]=Second \
+ items[1][value]:=200
+
+# Generates:
+# {
+# "items": [
+# {"name": "First", "value": 100},
+# {"name": "Second", "value": 200}
+# ]
+# }
+```
+
+## Form Data
+
+### URL-Encoded Forms
+
+```bash
+# Use --form flag for application/x-www-form-urlencoded
+dotnet-http POST httpbin.org/post --form name=John email=john@example.com
+
+# Mixed with other options
+dotnet-http POST httpbin.org/post --form \
+ name=John \
+ age=30 \
+ Authorization:"Bearer token"
+```
+
+### Multipart Forms
+
+```bash
+# Use --multipart for multipart/form-data
+dotnet-http POST httpbin.org/post --multipart \
+ name=John \
+ file@/path/to/document.pdf
+
+# Multiple files
+dotnet-http POST httpbin.org/post --multipart \
+ name=John \
+ avatar@/path/to/avatar.jpg \
+ resume@/path/to/resume.pdf
+```
+
+## File Uploads
+
+### Send File as Body
+
+```bash
+# Send entire file as request body
+dotnet-http POST api.example.com/upload @/path/to/data.json
+
+# With content type
+dotnet-http POST api.example.com/upload \
+ Content-Type:"application/json" \
+ @/path/to/data.json
+```
+
+### File in Multipart Form
+
+```bash
+# File as form field
+dotnet-http POST api.example.com/upload --multipart \
+ description="My document" \
+ file@/path/to/document.pdf
+```
+
+### Multiple Files
+
+```bash
+dotnet-http POST api.example.com/batch-upload --multipart \
+ batch_name="Document Batch" \
+ doc1@/path/to/file1.pdf \
+ doc2@/path/to/file2.pdf \
+ metadata@/path/to/metadata.json
+```
+
+## Raw Data
+
+### Raw String Data
+
+```bash
+# Send raw text
+dotnet-http POST api.example.com/webhook \
+ Content-Type:"text/plain" \
+ --raw "This is raw text data"
+
+# Raw JSON (alternative to field syntax)
+dotnet-http POST api.example.com/data \
+ Content-Type:"application/json" \
+ --raw '{"name": "John", "age": 30}'
+
+# Raw XML
+dotnet-http POST api.example.com/xml \
+ Content-Type:"application/xml" \
+ --raw 'John30'
+```
+
+### Data from Stdin
+
+```bash
+# Pipe data from command
+echo '{"message": "Hello"}' | dotnet-http POST api.example.com/data
+
+# From file via stdin
+cat data.json | dotnet-http POST api.example.com/upload
+
+# From other tools
+curl -s api.example.com/export | dotnet-http POST api.example.com/import
+```
+
+## Data Type Examples
+
+### E-commerce API
+
+```bash
+# Create product
+dotnet-http POST api.shop.com/products \
+ Authorization:"Bearer token" \
+ name="Laptop Computer" \
+ description="High-performance laptop" \
+ price:=999.99 \
+ in_stock:=true \
+ categories:='["electronics", "computers"]' \
+ specifications:='{"cpu": "Intel i7", "ram": "16GB", "storage": "512GB SSD"}' \
+ tags==electronics tags==computers
+```
+
+### User Registration
+
+```bash
+# Complex user object
+dotnet-http POST api.example.com/users \
+ personal[first_name]=John \
+ personal[last_name]=Doe \
+ personal[email]=john.doe@example.com \
+ personal[phone]="+1-555-0123" \
+ address[street]="123 Main Street" \
+ address[city]=Seattle \
+ address[state]=WA \
+ address[zipcode]:=98101 \
+ address[country]=USA \
+ preferences[newsletter]:=true \
+ preferences[notifications]:=false \
+ role=user \
+ active:=true
+```
+
+### API Configuration
+
+```bash
+# Configuration update
+dotnet-http PUT api.example.com/config \
+ Authorization:"Bearer admin-token" \
+ database[host]=localhost \
+ database[port]:=5432 \
+ database[ssl]:=true \
+ cache[enabled]:=true \
+ cache[ttl]:=3600 \
+ features:='["auth", "logging", "monitoring"]' \
+ limits[requests_per_minute]:=1000 \
+ limits[max_file_size]:=10485760
+```
+
+## Content-Type Handling
+
+### Automatic Content-Type
+
+```bash
+# JSON (default for field syntax)
+dotnet-http POST api.example.com/data name=John
+# Content-Type: application/json
+
+# Form data
+dotnet-http POST api.example.com/data --form name=John
+# Content-Type: application/x-www-form-urlencoded
+
+# Multipart
+dotnet-http POST api.example.com/data --multipart name=John file@data.txt
+# Content-Type: multipart/form-data
+```
+
+### Manual Content-Type
+
+```bash
+# Override content type
+dotnet-http POST api.example.com/data \
+ Content-Type:"application/vnd.api+json" \
+ name=John age:=30
+
+# XML content
+dotnet-http POST api.example.com/data \
+ Content-Type:"application/xml" \
+ @data.xml
+```
+
+## Advanced Data Handling
+
+### Conditional Fields
+
+```bash
+# Only include fields if they have values
+dotnet-http POST api.example.com/users \
+ name=John \
+ email=john@example.com \
+ $([ "$PHONE" ] && echo "phone=$PHONE") \
+ $([ "$COMPANY" ] && echo "company=$COMPANY")
+```
+
+### Dynamic Values
+
+```bash
+# Use command substitution
+dotnet-http POST api.example.com/events \
+ timestamp:=$(date +%s) \
+ uuid="$(uuidgen)" \
+ hostname="$(hostname)"
+```
+
+### Environment Variables
+
+```bash
+# Reference environment variables
+dotnet-http POST api.example.com/deploy \
+ Authorization:"Bearer $API_TOKEN" \
+ version="$BUILD_VERSION" \
+ environment="$DEPLOY_ENV"
+```
+
+## Validation and Testing
+
+### Schema Validation
+
+```bash
+# Validate response against schema
+dotnet-http POST api.example.com/users \
+ name=John \
+ email=john@example.com \
+ --schema user-schema.json
+```
+
+### Response Testing
+
+```bash
+# Test specific fields in response
+dotnet-http POST api.example.com/users name=John | jq '.id != null'
+
+# Combine with shell scripting
+response=$(dotnet-http POST api.example.com/users name=John --body)
+user_id=$(echo $response | jq -r '.id')
+dotnet-http GET api.example.com/users/$user_id
+```
+
+## Best Practices
+
+1. **Use appropriate data types** - Numbers as `:=123`, booleans as `:=true`
+2. **Quote complex values** - Especially JSON objects and arrays
+3. **Be consistent with naming** - Use snake_case or camelCase consistently
+4. **Validate data structure** - Use `--offline` to preview requests
+5. **Use files for large data** - Avoid very long command lines
+6. **Consider security** - Don't put sensitive data in command history
+7. **Use environment variables** - For tokens and configuration
+8. **Test incrementally** - Start simple and add complexity
+
+## Next Steps
+
+- Learn about [authentication methods](authentication.md)
+- Explore [file execution](file-execution.md) for complex data scenarios
+- Check out [variable substitution](variables.md) for dynamic values
+- See [examples](examples/common-use-cases.md) for real-world usage patterns
\ No newline at end of file
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index 5820c73..30ec76e 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -7,7 +7,8 @@
MIT
https://github.com/WeihanLi/dotnet-httpie
https://github.com/WeihanLi/dotnet-httpie/tree/main/docs/ReleaseNotes.md
- true
+ true
+ true
diff --git a/src/HTTPie/Implement/OutputFormatter.cs b/src/HTTPie/Implement/OutputFormatter.cs
index 2efff84..8c32fca 100644
--- a/src/HTTPie/Implement/OutputFormatter.cs
+++ b/src/HTTPie/Implement/OutputFormatter.cs
@@ -51,7 +51,7 @@ public sealed class OutputFormatter(IServiceProvider serviceProvider, ILogger OutputVerboseOption = new("-v", "--verbose")
{
- Description = "output request/response, response headers and response body"
+ Description = "output all request/response info, including request/response headers,properties,body"
};
private static readonly Option OutputPrintModeOption = new("-p", "--print")
@@ -131,8 +131,9 @@ private static string GetCommonOutput(HttpContext httpContext, OutputFormat outp
var responseModel = httpContext.Response;
var hasValidResponse = (int)responseModel.StatusCode > 0;
+ // The HttpVersion in ResponseMessage is the version used for the request after negotiation
var requestVersion = hasValidResponse
- ? httpContext.Response.RequestHttpVersion ?? httpContext.Response.HttpVersion
+ ? httpContext.Response.HttpVersion
: httpContext.Request.HttpVersion ?? new Version(2, 0)
;
var prettyOption = requestModel.ParseResult.GetValue(PrettyOption);
@@ -266,17 +267,17 @@ private static string GetRequestVersionAndStatus(HttpContext httpContext, Versio
var uri = new Uri(requestModel.Url);
return
$"""
- {requestModel.Method.Method.ToUpper()} {uri.PathAndQuery} HTTP/{requestVersion.NormalizeHttpVersion()}
+ {requestModel.Method.Method.ToUpper()} {uri.PathAndQuery} {requestVersion.NormalizeHttpVersion()}
Host: {uri.Host}{(uri.IsDefaultPort ? "" : $":{uri.Port}")}
Schema: {uri.Scheme}
- Url: {requestModel.Url}
+ [Url]: {requestModel.Url}
""";
}
private static string GetResponseVersionAndStatus(HttpResponseModel responseModel)
{
return
- $"HTTP/{responseModel.HttpVersion.NormalizeHttpVersion()} {(int)responseModel.StatusCode} {responseModel.StatusCode}";
+ $"{responseModel.HttpVersion.NormalizeHttpVersion()} {(int)responseModel.StatusCode} {responseModel.StatusCode}";
}
private static string GetHeadersString(IDictionary headers)
diff --git a/src/HTTPie/Implement/RequestExecutor.cs b/src/HTTPie/Implement/RequestExecutor.cs
index 96944d9..ea7ddd3 100644
--- a/src/HTTPie/Implement/RequestExecutor.cs
+++ b/src/HTTPie/Implement/RequestExecutor.cs
@@ -2,12 +2,14 @@
// Licensed under the MIT license.
using HTTPie.Abstractions;
+using HTTPie.Middleware;
using HTTPie.Models;
using HTTPie.Utilities;
using Microsoft.Extensions.Logging;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Net;
+using System.Text;
using WeihanLi.Common.Extensions;
namespace HTTPie.Implement;
@@ -50,9 +52,14 @@ ILogger logger
Description = "Request duration, 10s/1m or 00:01:00 ..."
};
+ private static readonly Option StreamOption = new("--stream", "-S")
+ {
+ Description = "Stream response body output as it arrives (text responses only)"
+ };
+
public Option[] SupportedOptions()
{
- return [TimeoutOption, IterationOption, DurationOption, VirtualUserOption];
+ return [TimeoutOption, IterationOption, DurationOption, VirtualUserOption, StreamOption];
}
public async ValueTask ExecuteAsync(HttpContext httpContext)
@@ -60,6 +67,11 @@ public async ValueTask ExecuteAsync(HttpContext httpContext)
var requestModel = httpContext.Request;
await requestPipeline(requestModel);
LogRequestModel(requestModel);
+
+ // Set streaming mode flag early, before any early returns
+ var streamMode = requestModel.ParseResult.HasOption(StreamOption);
+ httpContext.UpdateFlag(Constants.FlagNames.IsStreamingMode, streamMode);
+
if (requestModel.ParseResult.HasOption(OutputFormatter.OfflineOption))
{
RequestShouldBeOffline();
@@ -104,8 +116,17 @@ public async ValueTask ExecuteAsync(HttpContext httpContext)
}
else
{
- httpContext.Response = await InvokeRequest(client, httpContext, httpContext.RequestCancelled);
- await responsePipeline(httpContext);
+ if (streamMode)
+ {
+ await InvokeStreamingRequest(client, httpContext, httpContext.RequestCancelled);
+ // Mark that streaming actually completed
+ httpContext.UpdateFlag(Constants.FlagNames.StreamingCompleted, true);
+ }
+ else
+ {
+ httpContext.Response = await InvokeRequest(client, httpContext, httpContext.RequestCancelled);
+ await responsePipeline(httpContext);
+ }
}
async Task InvokeLoadTest(HttpClient httpClient)
@@ -187,6 +208,176 @@ private async Task InvokeRequest(HttpClient httpClient, HttpC
return responseModel;
}
+ private async Task InvokeStreamingRequest(HttpClient httpClient, HttpContext httpContext,
+ CancellationToken cancellationToken)
+ {
+ try
+ {
+ using var requestMessage = await requestMapper.ToRequestMessage(httpContext);
+ LogRequestMessage(requestMessage);
+ httpContext.Request.Timestamp = DateTimeOffset.Now;
+ var startTime = Stopwatch.GetTimestamp();
+
+ // Send request with HttpCompletionOption.ResponseHeadersRead to start streaming
+ using var responseMessage = await httpClient.SendAsync(requestMessage,
+ HttpCompletionOption.ResponseHeadersRead, cancellationToken);
+
+ var elapsed = ProfilerHelper.GetElapsedTime(startTime);
+ LogResponseMessage(responseMessage);
+
+ // Build response model with headers only
+ var responseModel = new HttpResponseModel
+ {
+ RequestHttpVersion = responseMessage.RequestMessage?.Version,
+ HttpVersion = responseMessage.Version,
+ StatusCode = responseMessage.StatusCode,
+ Headers = responseMessage.Headers
+ .Union(responseMessage.Content.Headers)
+ .ToDictionary(x => x.Key, x => new Microsoft.Extensions.Primitives.StringValues(x.Value.ToArray())),
+ Timestamp = httpContext.Request.Timestamp.Add(elapsed),
+ Elapsed = elapsed
+ };
+
+ httpContext.Response = responseModel;
+
+ // Run response pipeline for headers (e.g., to set properties)
+ await responsePipeline(httpContext);
+
+ // Check if we should stream based on content type
+ var isTextResponse = IsTextResponse(responseMessage);
+ var downloadMode = httpContext.Request.ParseResult.HasOption(DownloadMiddleware.DownloadOption);
+
+ if (!isTextResponse || downloadMode)
+ {
+ // Fall back to buffered mode for binary content or downloads
+ responseModel.Bytes = await responseMessage.Content.ReadAsByteArrayAsync(cancellationToken);
+ if (isTextResponse)
+ {
+ try
+ {
+ responseModel.Body = responseModel.Bytes.GetString();
+ }
+ catch (Exception ex)
+ {
+ // Unable to decode response as text, likely encoding issue
+ LogException(ex);
+ }
+ }
+ return;
+ }
+
+ // Output headers immediately
+ var outputFormat = OutputFormatter.GetOutputFormat(httpContext);
+
+ if (outputFormat.HasFlag(OutputFormat.ResponseHeaders) || outputFormat == OutputFormat.ResponseInfo)
+ {
+ var headerOutput = GetStreamingHeaderOutput(httpContext);
+ await Console.Out.WriteLineAsync(headerOutput);
+ }
+
+ // Stream the body
+ if (outputFormat.HasFlag(OutputFormat.ResponseBody) || outputFormat == OutputFormat.ResponseInfo)
+ {
+ await using var stream = await responseMessage.Content.ReadAsStreamAsync(cancellationToken);
+
+ // Get encoding from Content-Type header or default to UTF-8
+ var encoding = responseMessage.Content.Headers.ContentType?.CharSet is { } charset
+ ? System.Text.Encoding.GetEncoding(charset)
+ : System.Text.Encoding.UTF8;
+
+ using var reader = new StreamReader(stream, encoding);
+
+ var bodyBuilder = new StringBuilder();
+ string? line;
+ while ((line = await reader.ReadLineAsync(cancellationToken)) is not null)
+ {
+ await Console.Out.WriteLineAsync(line);
+ bodyBuilder.AppendLine(line);
+ }
+
+ // Store the body for potential later use
+ responseModel.Body = bodyBuilder.ToString();
+ responseModel.Bytes = encoding.GetBytes(responseModel.Body);
+ }
+ else
+ {
+ // Even if not outputting body, we need to consume it
+ responseModel.Bytes = await responseMessage.Content.ReadAsByteArrayAsync(cancellationToken);
+ responseModel.Body = responseModel.Bytes.GetString();
+ }
+
+ LogRequestDuration(httpContext.Request.Url, httpContext.Request.Method, responseModel.StatusCode, elapsed);
+ }
+ catch (OperationCanceledException operationCanceledException) when (cancellationToken.IsCancellationRequested)
+ {
+ LogRequestCancelled(operationCanceledException);
+ }
+ catch (Exception exception)
+ {
+ LogException(exception);
+ }
+ }
+
+ private static bool IsTextResponse(HttpResponseMessage response)
+ {
+ // When ContentType is null, assume text response for compatibility
+ // This matches the behavior of ResponseMapper.IsTextResponse
+ if (response.Content.Headers.ContentType?.MediaType is null)
+ {
+ return true;
+ }
+ var contentType = response.Content.Headers.ContentType;
+ var mediaType = contentType.MediaType;
+ var isTextContent = mediaType.StartsWith("text/", StringComparison.OrdinalIgnoreCase)
+ || mediaType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase)
+ || mediaType.StartsWith("application/xml", StringComparison.OrdinalIgnoreCase)
+ || mediaType.StartsWith("application/javascript", StringComparison.OrdinalIgnoreCase)
+ ;
+ return isTextContent;
+ }
+
+ private string GetStreamingHeaderOutput(HttpContext httpContext)
+ {
+ var responseModel = httpContext.Response;
+ var requestModel = httpContext.Request;
+ var outputFormat = OutputFormatter.GetOutputFormat(httpContext);
+ var output = new StringBuilder();
+
+ // Request headers if needed
+ if (outputFormat.HasFlag(OutputFormat.RequestHeaders))
+ {
+ var requestVersion = responseModel.HttpVersion;
+ var uri = new Uri(requestModel.Url);
+ output.AppendLine($"{requestModel.Method.Method.ToUpper()} {uri.PathAndQuery} {requestVersion.NormalizeHttpVersion()}");
+ output.AppendLine($"Host: {uri.Host}{(uri.IsDefaultPort ? "" : $":{uri.Port}")}");
+ output.AppendLine($"Schema: {uri.Scheme}");
+ output.AppendLine($"[Url]: {requestModel.Url}");
+ output.AppendLine(string.Join(Environment.NewLine,
+ requestModel.Headers.Select(h => $"{h.Key}: {h.Value}").OrderBy(h => h)));
+
+ if (outputFormat.HasFlag(OutputFormat.Properties) && requestModel.Properties.Count > 0)
+ {
+ output.AppendLine(string.Join(Environment.NewLine,
+ requestModel.Properties.Select(h => $"[{h.Key}]: {h.Value}").OrderBy(h => h)));
+ }
+ output.AppendLine();
+ }
+
+ // Response headers
+ output.AppendLine($"{responseModel.HttpVersion.NormalizeHttpVersion()} {(int)responseModel.StatusCode} {responseModel.StatusCode}");
+ output.AppendLine(string.Join(Environment.NewLine,
+ responseModel.Headers.Select(h => $"{h.Key}: {h.Value}").OrderBy(h => h)));
+
+ if (outputFormat.HasFlag(OutputFormat.Properties) && responseModel.Properties.Count > 0)
+ {
+ output.AppendLine(string.Join(Environment.NewLine,
+ responseModel.Properties.Select(h => $"[{h.Key}]: {h.Value}").OrderBy(h => h)));
+ }
+
+ output.AppendLine();
+ return output.ToString();
+ }
+
[LoggerMessage(Level = LogLevel.Debug, EventId = 0, Message = "Request should be offline, wont send request")]
private partial void RequestShouldBeOffline();
diff --git a/src/HTTPie/Middleware/RequestDataMiddleware.cs b/src/HTTPie/Middleware/RequestDataMiddleware.cs
index 85a14d3..bee0eb5 100644
--- a/src/HTTPie/Middleware/RequestDataMiddleware.cs
+++ b/src/HTTPie/Middleware/RequestDataMiddleware.cs
@@ -165,7 +165,7 @@ private static void ParseNestedJsonItem(string item, JsonNode rootNode)
if (rootArrayKey.Name == "root" || string.IsNullOrEmpty(rootArrayKey.Name))
{
// Array append operation []=
- rootArray.Add(CreateJsonValue(value, isRawValue));
+ rootArray.Add((JsonNode?)CreateJsonValue(value, isRawValue));
}
else
{
@@ -175,7 +175,7 @@ private static void ParseNestedJsonItem(string item, JsonNode rootNode)
// Extend array if necessary
while (rootArray.Count <= index)
{
- rootArray.Add(JsonValue.Create((string?)null));
+ rootArray.Add((JsonNode?)null);
}
rootArray[index] = CreateJsonValue(value, isRawValue);
}
@@ -199,14 +199,14 @@ private static void ParseNestedJsonItem(string item, JsonNode rootNode)
if (key.Name == "root" || string.IsNullOrEmpty(key.Name))
{
// Array append operation - add new object to continue navigation
- currentArray.Add(new JsonObject());
+ currentArray.Add((JsonNode?)new JsonObject());
currentNode = currentArray[^1]!;
}
else if (int.TryParse(key.Name, out int index))
{
while (currentArray.Count <= index)
{
- currentArray.Add(new JsonObject());
+ currentArray.Add((JsonNode?)new JsonObject());
}
currentNode = currentArray[index]!;
}
@@ -249,7 +249,7 @@ private static void ParseNestedJsonItem(string item, JsonNode rootNode)
if (currentNode is JsonArray currentArray)
{
// Direct array access
- currentArray.Add(CreateJsonValue(value, isRawValue));
+ currentArray.Add((JsonNode?)CreateJsonValue(value, isRawValue));
}
else
{
@@ -259,7 +259,7 @@ private static void ParseNestedJsonItem(string item, JsonNode rootNode)
objectNode[finalKey.Name] = new JsonArray();
}
var array = objectNode[finalKey.Name]!.AsArray();
- array.Add(CreateJsonValue(value, isRawValue));
+ array.Add((JsonNode?)CreateJsonValue(value, isRawValue));
}
}
else
diff --git a/src/HTTPie/Models/HttpResponseModel.cs b/src/HTTPie/Models/HttpResponseModel.cs
index 06a84ff..1b39096 100644
--- a/src/HTTPie/Models/HttpResponseModel.cs
+++ b/src/HTTPie/Models/HttpResponseModel.cs
@@ -17,7 +17,7 @@ public sealed class HttpResponseModel
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
- public byte[] Bytes { get; init; } = [];
+ public byte[] Bytes { get; set; } = [];
public string Body { get; set; } = string.Empty;
public DateTimeOffset Timestamp { get; set; }
public TimeSpan Elapsed { get; set; }
diff --git a/src/HTTPie/Utilities/Constants.cs b/src/HTTPie/Utilities/Constants.cs
index 16c2cc7..7d91731 100644
--- a/src/HTTPie/Utilities/Constants.cs
+++ b/src/HTTPie/Utilities/Constants.cs
@@ -34,5 +34,7 @@ public static class FlagNames
{
public const string IsFormContentType = "IsFormContentType";
public const string IsLoadTest = "IsLoadTest";
+ public const string IsStreamingMode = "IsStreamingMode";
+ public const string StreamingCompleted = "StreamingCompleted";
}
}
diff --git a/src/HTTPie/Utilities/Helpers.cs b/src/HTTPie/Utilities/Helpers.cs
index db24d15..d9b032b 100644
--- a/src/HTTPie/Utilities/Helpers.cs
+++ b/src/HTTPie/Utilities/Helpers.cs
@@ -241,13 +241,26 @@ private static async Task HttpCommandHandler(ParseResult parseResult, Cancellati
await serviceProvider.GetRequiredService()
.ParseAsync(requestModel);
+ // Check for streaming mode option early by checking tokens
+ // This is needed for tests that use an internal handler
+ var hasStreamOption = parseResult.Tokens.Any(t =>
+ t.Value.Equals("--stream", StringComparison.OrdinalIgnoreCase) ||
+ t.Value.Equals("-S", StringComparison.OrdinalIgnoreCase));
+ context.UpdateFlag(Constants.FlagNames.IsStreamingMode, hasStreamOption);
+
if (internalHandler is null)
{
await serviceProvider.ResolveRequiredService()
.ExecuteAsync(context);
- var output = await serviceProvider.ResolveRequiredService()
- .GetOutput(context);
- await Console.Out.WriteLineAsync(output.Trim());
+
+ // Skip output formatting if streaming actually completed (output already written)
+ var streamingCompleted = context.GetFlag(Constants.FlagNames.StreamingCompleted);
+ if (!streamingCompleted)
+ {
+ var output = await serviceProvider.ResolveRequiredService()
+ .GetOutput(context);
+ await Console.Out.WriteLineAsync(output.Trim());
+ }
}
else
{
@@ -263,8 +276,14 @@ public static bool HasOption(this ParseResult parseResult, Option option)
public static string NormalizeHttpVersion(this Version version)
{
- var versionString = version.ToString(2);
- return versionString.TrimEnd('0', '.');
+ if (version.Major < 2)
+ {
+ // http/1.1
+ return $"http/{version.Major}.{version.Minor}";
+ }
+
+ // h2, h3
+ return $"h{version.Major}";
}
public static HttpClientHandler GetHttpClientHandler()
diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props
index 2b4e85e..ef0cfc7 100644
--- a/tests/Directory.Build.props
+++ b/tests/Directory.Build.props
@@ -5,7 +5,7 @@
false
true
- true
+
true
diff --git a/tests/HTTPie.UnitTest/Utilities/HelpersTest.cs b/tests/HTTPie.UnitTest/Utilities/HelpersTest.cs
index a7367f4..10a9f6f 100644
--- a/tests/HTTPie.UnitTest/Utilities/HelpersTest.cs
+++ b/tests/HTTPie.UnitTest/Utilities/HelpersTest.cs
@@ -49,4 +49,30 @@ public void SplitTest(string commandLine)
Assert.Equal("--raw", args[0]);
Assert.Equal(@"{""Id"":1,""Name"":""Test""}", args[1]);
}
+
+ [Fact]
+ public async Task StreamingOption_IsRecognized()
+ {
+ var input = "GET reservation.weihanli.xyz/health --stream --offline";
+ var services = new ServiceCollection()
+ .AddLogging()
+ .RegisterApplicationServices()
+ .BuildServiceProvider();
+ await services.Handle(input, (_, _) => Task.CompletedTask);
+ var httpContext = services.GetRequiredService();
+ Assert.True(httpContext.GetFlag(Constants.FlagNames.IsStreamingMode));
+ }
+
+ [Fact]
+ public async Task StreamingOption_NotSetByDefault()
+ {
+ var input = "GET reservation.weihanli.xyz/health --offline";
+ var services = new ServiceCollection()
+ .AddLogging()
+ .RegisterApplicationServices()
+ .BuildServiceProvider();
+ await services.Handle(input, (_, _) => Task.CompletedTask);
+ var httpContext = services.GetRequiredService();
+ Assert.False(httpContext.GetFlag(Constants.FlagNames.IsStreamingMode));
+ }
}