{"id":19883122,"url":"https://github.com/dmitrymomot/clientip","last_synced_at":"2025-07-02T14:34:54.752Z","repository":{"id":222200705,"uuid":"756523937","full_name":"dmitrymomot/clientip","owner":"dmitrymomot","description":"Lookup real client IP address from request","archived":false,"fork":false,"pushed_at":"2024-10-29T20:38:16.000Z","size":18,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-11T18:29:57.636Z","etag":null,"topics":["go","golang","http-utils","middleware","real-ip"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dmitrymomot.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"custom":["https://www.buymeacoffee.com/dmomot"]}},"created_at":"2024-02-12T20:28:06.000Z","updated_at":"2024-10-29T20:37:06.000Z","dependencies_parsed_at":"2024-11-12T17:19:53.069Z","dependency_job_id":"f3a92cf8-1411-463f-b607-92222b187acc","html_url":"https://github.com/dmitrymomot/clientip","commit_stats":null,"previous_names":["dmitrymomot/clientip"],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmitrymomot%2Fclientip","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmitrymomot%2Fclientip/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmitrymomot%2Fclientip/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dmitrymomot%2Fclientip/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dmitrymomot","download_url":"https://codeload.github.com/dmitrymomot/clientip/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241311550,"owners_count":19942194,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","http-utils","middleware","real-ip"],"created_at":"2024-11-12T17:19:25.846Z","updated_at":"2025-03-01T03:24:14.247Z","avatar_url":"https://github.com/dmitrymomot.png","language":"Go","funding_links":["https://www.buymeacoffee.com/dmomot"],"categories":[],"sub_categories":[],"readme":"# Real IP Lookup Module\n\n[![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/dmitrymomot/clientip)](https://github.com/dmitrymomot/clientip)\n[![Go Reference](https://pkg.go.dev/badge/github.com/dmitrymomot/clientip.svg)](https://pkg.go.dev/github.com/dmitrymomot/clientip)\n[![License](https://img.shields.io/github/license/dmitrymomot/clientip)](https://github.com/dmitrymomot/clientip/blob/main/LICENSE)\n\n[![Tests](https://github.com/dmitrymomot/clientip/actions/workflows/tests.yml/badge.svg)](https://github.com/dmitrymomot/clientip/actions/workflows/tests.yml)\n[![CodeQL Analysis](https://github.com/dmitrymomot/clientip/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/dmitrymomot/clientip/actions/workflows/codeql-analysis.yml)\n[![GolangCI Lint](https://github.com/dmitrymomot/clientip/actions/workflows/golangci-lint.yml/badge.svg)](https://github.com/dmitrymomot/clientip/actions/workflows/golangci-lint.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/dmitrymomot/clientip)](https://goreportcard.com/report/github.com/dmitrymomot/clientip)\n\nA lightweight, production-ready Go module for accurately determining client IP addresses in HTTP applications. Particularly useful for applications behind proxies, load balancers, or CDNs like Cloudflare, DigitalOcean App Platform, and Fastly.\n\n## Features\n\n-   **Accurate IP Detection**: Intelligently extracts client IPs from various standard and vendor-specific headers\n-   **IPv4 \u0026 IPv6 Support**: Full support for both IPv4 and IPv6 addresses with proper canonicalization\n-   **Flexible Header Configuration**: Use default headers or specify custom ones for your specific setup\n-   **Multiple Integration Options**:\n    -   Direct IP lookup function for manual integration\n    -   Drop-in middleware for automatic IP detection\n    -   Context-based IP storage for thread-safe access\n-   **Production-Ready**: Used in production environments with comprehensive test coverage\n\n## Installation\n\nTo install the module, use the following command:\n\n```bash\ngo get github.com/dmitrymomot/clientip\n```\n\n## Usage\n\n### Direct IP Lookup\n\n```go\nfunc handler(w http.ResponseWriter, r *http.Request) {\n    // Use default headers\n    ip := clientip.LookupFromRequest(r)\n\n    // Or specify custom headers\n    ip = clientip.LookupFromRequest(r, \"X-Custom-IP\", \"X-Real-IP\")\n\n    fmt.Fprintf(w, \"Your IP: %s\", ip)\n}\n```\n\n### Middleware Integration\n\n```go\nfunc main() {\n    mux := http.NewServeMux()\n\n    // Basic middleware usage with default headers\n    handler := clientip.Middleware()(mux)\n\n    // Or with custom headers\n    handler = clientip.Middleware(\"X-Custom-IP\", \"CF-Connecting-IP\")(mux)\n\n    http.ListenAndServe(\":8080\", handler)\n}\n```\n\n### Context-Based IP Access\n\n```go\nfunc main() {\n    mux := http.NewServeMux()\n\n    // Chain both middlewares\n    handler := clientip.Middleware()(mux)\n    handler = clientip.IpToContext(handler) // Store IP in context, it must be called after Middleware\n\n    http.ListenAndServe(\":8080\", handler)\n}\n\nfunc handler(w http.ResponseWriter, r *http.Request) {\n    // Get IP from context anywhere in your handler chain\n    if ip := clientip.GetIPAddress(r.Context()); ip != \"\" {\n        fmt.Fprintf(w, \"Your IP from context: %s\", ip)\n    }\n}\n```\n\n### Supported Headers\n\nThe module checks the following headers by default (in order):\n\n-   `DO_Connecting-IP`, `DO-Connecting-IP` (DigitalOcean)\n-   `True-Client-IP`\n-   `X-Real-IP`\n-   `CF-Connecting-IP` (Cloudflare)\n-   `Fastly-Client-IP`\n-   `X-Cluster-Client-IP`\n-   `X-Client-IP`\n-   `X-Forwarded-For` (first IP in the chain)\n\nYou can override these by providing your own headers to the functions.\n\n## Customization\n\nBoth `LookupFromRequest` and `Middleware` functions accept an optional list of headers to consider when looking for the client IP address. By default, a predefined set of common headers used for forwarding client IPs in proxy setups are checked.\n\n## Best Practices\n\n-   **Security**: Always validate and sanitize IP addresses before using them in security-critical contexts\n-   **Header Order**: Configure headers in order of trust (most trusted first)\n-   **Performance**: Use the middleware approach for consistent IP handling across your application\n-   **Context Usage**: Prefer context-based IP access when working with complex handler chains\n\n## Troubleshooting\n\n### Common Issues\n\n1. **Empty IP Address**\n\n    - Check if your proxy/load balancer is properly configured to forward IP headers\n    - Verify the header names match your infrastructure setup\n\n2. **Incorrect IP Address**\n\n    - Ensure headers are being set in the correct order of precedence\n    - Check if intermediate proxies are modifying the headers\n\n3. **IPv6 Handling**\n    - The module automatically canonicalizes IPv6 addresses to their /64 prefix\n    - If you need the full address, use the raw header value instead\n\nFor more help, please open an issue on GitHub.\n\n## Contributing\n\nIf you wish to contribute to this project, please fork the repository and submit a pull request.\n\n## License\n\nThis project is licensed under the [Apache 2.0](LICENSE) - see the `LICENSE` file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmitrymomot%2Fclientip","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdmitrymomot%2Fclientip","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdmitrymomot%2Fclientip/lists"}