Support plain-HTTP self-hosted forges - #147
Open
andrew wants to merge 1 commit into
Open
Conversation
--host and FORGE_HOST now accept a full http://host:port URL, and a scheme = http key is accepted under [domain] in config (settable via forge auth login --scheme). The API base URL is built from that scheme instead of hardcoding https, so a local Forgejo/Gitea on a private IP without TLS is reachable. DetectForgeType and Client.RegisterDomain accept an optional scheme prefix on the domain argument for the same reason; the bare host is still used as the registry key.
There was a problem hiding this comment.
Pull request overview
This PR adds first-class support for self-hosted forges served over plain HTTP by allowing the scheme to be specified via CLI/env/config and by teaching the library’s detection/registration APIs to accept http:///https://-prefixed inputs while keeping registry/config keys as bare host[:port].
Changes:
- Accept full URLs in
--host/FORGE_HOST, preserve scheme for API base URL construction, and default tohttpsotherwise. - Add per-domain
scheme = http|httpsconfig support (includingforge auth login --scheme ...) with tests. - Update library APIs (
DetectForgeType,Client.RegisterDomain) to accept optional URL scheme prefixes and add tests.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Documents scheme = http and using full URL for --host/FORGE_HOST. |
| internal/resolve/resolve.go | Adds scheme-aware host handling and baseURLFor() scheme precedence logic. |
| internal/resolve/resolve_test.go | Adds tests for scheme-aware host/env/config behavior and API base URL. |
| internal/config/config.go | Introduces DomainSection.Scheme, parses scheme from config, extends SetDomain. |
| internal/config/config_test.go | Adds tests for scheme persistence/validation. |
| internal/cli/root.go | Updates --host help text to mention full URLs. |
| internal/cli/auth.go | Adds --scheme flag to persist scheme into config. |
| forges_test.go | Adds tests ensuring detection/registration preserve http:// URLs. |
| forge.go | Adds normalizeBaseURL() and updates RegisterDomain() to accept scheme-prefixed inputs. |
| detect.go | Updates detection to use normalizeBaseURL() so callers can pass http:// URLs. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+134
to
+145
| // normalizeBaseURL accepts either a bare host[:port] or a full http(s) URL and | ||
| // returns (baseURL, host). A bare host is assumed https. | ||
| func normalizeBaseURL(s string) (baseURL, host string) { | ||
| s = strings.TrimRight(s, "/") | ||
| if h, ok := strings.CutPrefix(s, "http://"); ok { | ||
| return s, h | ||
| } | ||
| if h, ok := strings.CutPrefix(s, "https://"); ok { | ||
| return s, h | ||
| } | ||
| return "https://" + s, s | ||
| } |
Comment on lines
+64
to
74
| // splitScheme splits a leading http:// or https:// off s and returns | ||
| // (scheme, host). If s has no scheme, scheme is "". | ||
| func splitScheme(s string) (scheme, host string) { | ||
| if h, ok := strings.CutPrefix(s, "http://"); ok { | ||
| return "http", strings.TrimRight(h, "/") | ||
| } | ||
| if h, ok := strings.CutPrefix(s, "https://"); ok { | ||
| return "https", strings.TrimRight(h, "/") | ||
| } | ||
| return "", strings.TrimRight(s, "/") | ||
| } |
Comment on lines
+73
to
+75
| if scheme != "" && scheme != "http" && scheme != "https" { | ||
| return fmt.Errorf("invalid --scheme %q: must be http or https", scheme) | ||
| } |
Comment on lines
+373
to
+375
| if scheme != "" { | ||
| sections[domain]["scheme"] = scheme | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Self-hosted Gitea/Forgejo instances on private networks are often served over plain HTTP (e.g.
http://172.30.0.10:3000inside a docker network). Every code path that turns a domain into an API base URL currently hardcodeshttps://, so there is no way to pointforgeat such an instance — even with the domain configured and a token stored, requests fail on TLS handshake.This adds three ways to specify the scheme:
--hostandFORGE_HOSTaccept a full URL (--host http://forgejo.local:3000). The scheme is used for the API base; the barehost:portis still what config lookups and the forge registry key on.scheme = httpunder a[domain]section in config, settable viaforge auth login --scheme http.DetectForgeTypeandClient.RegisterDomainaccept an optionalhttp:///https://prefix on their domain argument, so library callers and the CLI's probing fallback can pass the scheme through. Bare domains still default to https so existing callers are unaffected.Precedence for the base URL scheme is
--host→FORGE_HOST→ config[domain] scheme→https, matching the existing host-resolution order.