Skip to content

lfreleng-actions/go-httpbin-action

Repository files navigation

Go-httpbin GitHub Action

A GitHub Action that sets up a local go-httpbin service with HTTPS support.

go-httpbin-action

Features

  • 🔒 HTTPS Support: Automatically generates valid SSL certificates using mkcert
  • 🐳 Docker-based: Runs go-httpbin in a Docker container for isolation
  • 🔧 Highly Configurable: Supports configuration options for different use cases
  • 🚀 Fast Setup: Optimized for CI/CD pipelines with built-in readiness checking
  • 🌐 Network Flexibility: Supports both host networking and standard port mapping
  • 📊 Debug Support: Optional verbose logging for troubleshooting
  • Reliable Readiness: Uses lfreleng-actions/http-api-tool-docker for robust service verification

Usage

Basic Usage

steps: # Start the go-httpbin container with built-in readiness check - name: Setup go-httpbin uses: lfreleng/setup-go-httpbin@v1 id: httpbin # Testing (the action includes built-in readiness check) - name: Test go-httpbin endpoint uses: lfreleng-actions/http-api-tool-docker@v0.1.0 with: url: "${{ steps.httpbin.outputs.service-url }}/get" service_name: "go-httpbin GET endpoint" verify_ssl: false expected_http_code: 200 regex: '"url"' debug: true

Advanced Usage

steps: - name: Setup go-httpbin with custom configuration uses: lfreleng/setup-go-httpbin@v1 id: httpbin with: container-name: 'my-httpbin' port: '9090' use-host-network: 'true' debug: 'true' wait-timeout: '120' certificate-domains: 'myservice.local,api.test' docker-run-args: '--cpus=0.5 --memory=256m' - name: Test with proper SSL verification uses: lfreleng-actions/http-api-tool-docker@main with: url: "${{ steps.httpbin.outputs.service-url }}/get" service_name: "go-httpbin SSL verified endpoint" verify_ssl: true ca_bundle_path: "${{ steps.httpbin.outputs.ca-cert-path }}" expected_http_code: 200 regex: '"url"' debug: true

HTTP Mode (No SSL)

steps: - name: Setup go-httpbin without SSL uses: lfreleng/setup-go-httpbin@v1 id: httpbin with: skip-certificate: 'true' - name: Test HTTP endpoint uses: lfreleng-actions/http-api-tool-docker@main with: url: "${{ steps.httpbin.outputs.service-url }}/get" service_name: "go-httpbin HTTP endpoint" verify_ssl: false expected_http_code: 200 regex: '"url"' debug: true

Skip Built-in Readiness Check

steps: - name: Setup go-httpbin without readiness check uses: lfreleng/setup-go-httpbin@v1 id: httpbin with: skip-readiness-check: 'true' # Handle readiness checking manually - name: Custom readiness check uses: lfreleng-actions/http-api-tool-docker@main with: url: "${{ steps.httpbin.outputs.service-url }}/get" service_name: "Custom readiness check" verify_ssl: false expected_http_code: 200 retries: 30 initial_sleep_time: 2

Inputs

Input Description Required Default
container-name Name for the Docker container No go-httpbin
port Port to expose the service on No 8080
image Docker image to use No ghcr.io/mccutchen/go-httpbin
image-tag Tag of the Docker image No latest
use-host-network Use host networking (true/false) No false
wait-timeout Wait time for service ready (retries) No 60
debug Enable debug output (true/false) No false
cert-file-path SSL certificate file path No <secure>/cert.pem
key-file-path SSL private key file path No <secure>/key.pem
certificate-domains Extra domains for SSL certificate No ``
skip-certificate Skip SSL certificate generation No false
docker-run-args Extra Docker run arguments No ``
install-deps Whether to install dependencies No true
go-version Go version for building mkcert (if unavailable) No 1.24
skip-readiness-check Skip the built-in readiness check No false

Outputs

Output Description
container-name Name of the created container
service-url Base URL for accessing the service
host-gateway-ip Docker host gateway IP for container communication
ca-cert-path Path to the mkcert CA certificate (relative to workspace)
cert-file Path to the SSL certificate file
key-file Path to the SSL private key file
protocol Protocol used (http or https)

Environment Variables

The action also sets the following environment variables for convenience:

  • HOST_GATEWAY: Docker host gateway IP
  • PROTOCOL: Protocol in use (http or https)
  • MKCERT_CA_PATH: Path to the mkcert CA certificate (when using HTTPS)
  • GO_HTTPBIN_URL: Base URL of the running service

Network Modes

Standard Mode (default)

Uses Docker port mapping to expose the service on the specified port:

- uses: lfreleng/setup-go-httpbin@v1 with: port: '8080'

The service URL is automatically set to the Docker host gateway IP (typically 172.17.0.1) with the specified port for container-to-container communication.

From the host (your local machine): Access the service at https://localhost:${{ inputs.port }} (e.g., https://localhost:8080).

From containers (like http-api-tool-docker): Use the service-url output, which points to https://$HOST_GATEWAY:${{ inputs.port }} for proper container-to-container networking.

Host Network Mode

Uses Docker host networking for direct access:

- uses: lfreleng/setup-go-httpbin@v1 with: use-host-network: 'true'

Access the service at: https://localhost:8080.

Note: In host network mode, the container uses port 8080 directly on the host network namespace. The port input has no effect in this mode.

SSL Certificate Handling

The action automatically:

  1. Installs mkcert and creates a local CA
  2. Generates SSL certificates for localhost and any extra domains
  3. Installs the CA certificate in the system trust store
  4. Provides paths to certificates for manual SSL verification

Security Note: The action stores certificates in secure temporary directories with restricted permissions (700) rather than world-readable /tmp directories. The secure directories receive automatic cleanup when the action completes.

Using with SSL Verification

# With proper SSL verification using http-api-tool-docker - uses: lfreleng-actions/http-api-tool-docker@main with: url: "${{ steps.httpbin.outputs.service-url }}/get" service_name: "API Test" verify_ssl: true ca_bundle_path: "${{ steps.httpbin.outputs.ca-cert-path }}" expected_http_code: 200 # Without SSL verification (for testing) - uses: lfreleng-actions/http-api-tool-docker@main with: url: "${{ steps.httpbin.outputs.service-url }}/get" service_name: "API Test" verify_ssl: false expected_http_code: 200

Common Use Cases

Comprehensive API Testing

jobs: test-api: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup go-httpbin uses: lfreleng/setup-go-httpbin@v1 id: httpbin - name: Test GET endpoint uses: lfreleng-actions/http-api-tool-docker@main with: url: "${{ steps.httpbin.outputs.service-url }}/get" service_name: "GET endpoint test" verify_ssl: true ca_bundle_path: "${{ steps.httpbin.outputs.ca-cert-path }}" expected_http_code: 200 regex: '"url"' debug: true - name: Test POST endpoint uses: lfreleng-actions/http-api-tool-docker@main with: url: "${{ steps.httpbin.outputs.service-url }}/post" service_name: "POST endpoint test" http_method: "POST" request_body: '{"test": "data"}' content_type: "application/json" verify_ssl: false expected_http_code: 200 regex: '"json"' - name: Test authentication uses: lfreleng-actions/http-api-tool-docker@main with: url: "${{ steps.httpbin.outputs.service-url }}/basic-auth/user/pass" service_name: "Auth endpoint test" auth_string: "user:pass" verify_ssl: false expected_http_code: 200 regex: '"authenticated"'

Testing Custom HTTP Tools

jobs: test-api-tool: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup go-httpbin uses: lfreleng/setup-go-httpbin@v1 id: httpbin - name: Test custom API tool run: |  ./my-api-tool test \  --url "${{ steps.httpbin.outputs.service-url }}/get" \  --ca-bundle "${{ steps.httpbin.outputs.ca-cert-path }}"

Error Handling and Edge Cases

jobs: test-error-cases: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup go-httpbin uses: lfreleng/setup-go-httpbin@v1 id: httpbin - name: Test 404 handling uses: lfreleng-actions/http-api-tool-docker@main with: url: "${{ steps.httpbin.outputs.service-url }}/status/404" service_name: "404 endpoint test" verify_ssl: false expected_http_code: 404 debug: true - name: Test timeout handling uses: lfreleng-actions/http-api-tool-docker@main with: url: "${{ steps.httpbin.outputs.service-url }}/delay/3" service_name: "Timeout test" verify_ssl: false curl_timeout: 5 max_response_time: 4 fail_on_timeout: false debug: true - name: Test large response uses: lfreleng-actions/http-api-tool-docker@main with: url: "${{ steps.httpbin.outputs.service-url }}/bytes/2048" service_name: "Large response test" verify_ssl: false expected_http_code: 200 include_response_body: true

Testing Docker Containers

jobs: test-docker: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup go-httpbin uses: lfreleng/setup-go-httpbin@v1 id: httpbin with: use-host-network: 'true' # Better for container-to-container communication - name: Test containerized application run: |  docker run --rm --network=host my-app:test \  test-endpoint "${{ steps.httpbin.outputs.service-url }}/post"  ### Performance and Load Testing ```yaml jobs:  performance-test:  runs-on: ubuntu-latest  steps:  - uses: actions/checkout@v4   - name: Setup go-httpbin  uses: lfreleng/setup-go-httpbin@v1  id: httpbin  with:  debug: 'false' # Reduce noise during performance tests  wait-timeout: '120' # Allow more time for heavy load  docker-run-args: '--cpus=1.0 --memory=512m' # Resource limits   - name: Test response time limits  uses: lfreleng-actions/http-api-tool-docker@main  with:  url: "${{ steps.httpbin.outputs.service-url }}/delay/1"  service_name: "Performance test"  verify_ssl: false  max_response_time: 2  fail_on_timeout: true  retries: 3  debug: true

Troubleshooting

Enable Debug Mode

- uses: lfreleng/setup-go-httpbin@v1 with: debug: 'true'

This will provide verbose output including:

  • Certificate generation details
  • Container startup logs
  • Network connectivity tests
  • Final service verification

Common Issues

  1. Service not ready timeout: Increase wait-timeout value
  2. SSL certificate issues: Check ca-cert-path output and use it explicitly
  3. Network connectivity: Try use-host-network: 'true' for container-to-container communication
  4. Port conflicts: Change the port input to an available port

Manual Debugging

- name: Debug go-httpbin setup run: |  # Check container status  docker ps -a -f name="${{ steps.httpbin.outputs.container-name }}"   # Check container logs  docker logs "${{ steps.httpbin.outputs.container-name }}"  - name: Test connectivity with http-api-tool-docker uses: lfreleng-actions/http-api-tool-docker@main with: url: "${{ steps.httpbin.outputs.service-url }}/" service_name: "Debug connectivity test" verify_ssl: false debug: true retries: 1 continue-on-error: true - name: Check certificates run: |  # Check certificates  ls -la /tmp/localhost*pem  openssl x509 -in "${{ steps.httpbin.outputs.cert-file }}" -text \  -noout | head -10

Testing and Development

This project uses a comprehensive testing approach with both local testing capabilities and CI/CD integration.

Local Testing

Run the input validation test suite locally:

# Run all security validation tests ./tests/test-input-validation.sh # Run with verbose output for debugging ./tests/test-input-validation.sh -v # Keep containers after tests for inspection ./tests/test-input-validation.sh --no-cleanup # Show help and options ./tests/test-input-validation.sh --help

Test Suite Overview

Input Validation Tests (tests/test-input-validation.sh)

A comprehensive shell script that validates the action's security measures and input handling:

Security Tests (Should Fail):

  • Command Injection: --memory=512m; curl evil.com
  • Variable Expansion: --env=${HOME}/malicious, --env=$PATH
  • Code Execution: --memory=$(curl evil.com), --memory=\curl evil.com``
  • Shell Redirection: --memory < /etc/passwd, --memory > /tmp/evil
  • Invalid Formats: --mem@ry=512m

Valid Input Tests (Should Succeed):

  • Resource Limits: --memory=512m --cpu-shares=512
  • Network Config: --network=bridge --publish=8080:8080
  • Combined Args: --memory=512m --cpu-shares=512 --restart=unless-stopped
  • Short Flags: -m 512m
  • Empty Args: ""

Test Features:

  • Local Execution: Run the same tests locally and in CI
  • No Parameter Escaping: Direct string testing without GitHub Actions template expansion issues
  • Comprehensive Coverage: 16 different security and functionality scenarios
  • Colored Output: Clear pass/fail indicators with detailed logging
  • Cleanup Management: Automatic container cleanup with optional retention

CI/CD Integration

The test suite integrates with GitHub Actions workflow:

# .github/workflows/input-validation.yaml - name: 'Run Input Validation Tests' run: ./tests/test-input-validation.sh --verbose

Workflow Benefits:

  • Simplified Configuration: Single script call instead of 25+ individual test steps
  • Better Maintainability: Easy to add new tests without complex YAML
  • Consistent Environment: Same validation logic runs locally and in CI
  • Enhanced Security: No GitHub Actions template expansion interference
  • Clear Reporting: Detailed test results with artifact generation

Adding New Tests

To add a new security test:

  1. Create Test Function:
test_new_security_scenario() { run_action_test \ "Description of security test" \ "container-name" \ "port" \ "malicious-docker-args" \ "true" # Should fail }
  1. Add to Main Function:
# In main() function test_new_security_scenario
  1. Test Locally:
./tests/test-input-validation.sh -v

Validation Logic

The test suite uses the same security validation logic as the action:

# Command injection patterns [[ "$arg" == *";"* ]] || [[ "$arg" == *"&"* ]] || [[ "$arg" == *"|"* ]] # Code execution patterns [[ "$arg" == *'$('* ]] || [[ "$arg" == *'`'* ]] # Variable expansion patterns [[ "$arg" == *'${'* ]] || [[ "$arg" =~ \$[A-Za-z_] ]] # Shell redirection [[ "$arg" == *"<"* ]] || [[ "$arg" == *">"* ]] # Docker argument format [[ "$arg" =~ ^--?[a-zA-Z0-9-]+(=.*)?$ ]]

Prerequisites for Local Testing

  • Bash 4.0+ for the test script
  • Docker (for container cleanup validation)
  • Git (for repository operations)

Troubleshooting Tests

Test Script Issues:

# Make script executable chmod +x tests/test-input-validation.sh # Check script syntax bash -n tests/test-input-validation.sh # Run with debug output ./tests/test-input-validation.sh -v

Common Problems:

  • Permission Denied: Ensure script is executable
  • Docker Access: Verify Docker daemon is running
  • Path Issues: Run from repository root directory

Debug Commands:

# Check test environment docker --version bash --version # Verify action structure ls -la action.yaml # Test single validation echo '--env=$PATH' | grep '\$[A-Za-z_]'

Requirements

  • Linux or macOS runner (Windows is not supported)
  • Docker (available by default in GitHub Actions runners)
  • Go 1.18+ (will be automatically installed if not available or too old)
  • Internet connectivity (for downloading dependencies and building mkcert from source)

Security and Cross-Platform Support

This action installs mkcert from source for enhanced security and cross-platform compatibility:

  • Source Verification: Pins to a specific Git commit (2a46726cebac0ff4e1f133d90b4e4c42f1edf44a) for mkcert v1.4.4
  • Cross-Platform: Works on Linux and macOS runners (Windows is not supported)
  • Go Version Management: Automatically installs Go if not available or if version is too old
  • Platform-Specific Dependencies: Installs appropriate NSS tools for each supported platform

License

This action uses the Apache License 2.0. See the LICENSE file for details.

About

Creates a go-httpbin service within GitHub to act as a local testing endpoint

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages