{"id":22758643,"url":"https://github.com/mjpclab/govirtualhost","last_synced_at":"2025-04-14T18:20:49.052Z","repository":{"id":57502082,"uuid":"223610155","full_name":"mjpclab/goVirtualHost","owner":"mjpclab","description":"An easy way to setup HTTP virtual hosts","archived":false,"fork":false,"pushed_at":"2025-02-15T02:38:03.000Z","size":63,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-28T06:41:25.750Z","etag":null,"topics":["go","golang","virtual-host","virtualhost"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mjpclab.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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}},"created_at":"2019-11-23T15:26:00.000Z","updated_at":"2025-02-15T02:38:06.000Z","dependencies_parsed_at":"2024-02-08T11:26:33.462Z","dependency_job_id":"e11aa61a-6c6c-44eb-97bd-4be004e4449a","html_url":"https://github.com/mjpclab/goVirtualHost","commit_stats":{"total_commits":58,"total_committers":1,"mean_commits":58.0,"dds":0.0,"last_synced_commit":"019c3e49186c3686e99886f03ac6fe8b1fa59950"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mjpclab%2FgoVirtualHost","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mjpclab%2FgoVirtualHost/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mjpclab%2FgoVirtualHost/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mjpclab%2FgoVirtualHost/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mjpclab","download_url":"https://codeload.github.com/mjpclab/goVirtualHost/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248933348,"owners_count":21185461,"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","virtual-host","virtualhost"],"created_at":"2024-12-11T08:15:08.765Z","updated_at":"2025-04-14T18:20:49.027Z","avatar_url":"https://github.com/mjpclab.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# goVirtualHost\ngoVirtualHost: An easy way to setup HTTP virtual hosts.\n\nMinimal required Go version is 1.14.\n\n# Quick Example\nTwo virtual hosts listen on both :8080, but with different hostname, serve for different directories:\n```go\nsvc := goVirtualHost.NewService()\n\n// virtual host: localhost\nsvc.Add(\u0026goVirtualHost.HostInfo{\n    Listens:   []string{\":8080\"},\n    HostNames: []string{\"localhost\"},\n    Handler:   http.FileServer(http.Dir(\".\")),\n})\n\n// virtual host: default host\nsvc.Add(\u0026goVirtualHost.HostInfo{\n    Listens: []string{\":8080\"},\n    Handler: http.FileServer(http.Dir(\"/tmp\")),\n})\n\n// start server\nsvc.Open()\n```\n\n# NewService() *Service\n`NewService` returns a service instance that manages multiple virtual hosts.\n\n# (*Service) Add(*HostInfo) (errs, warns []error)\nAdding a new virtual host information to the `Service`.\nYou can use `errors.Is()` to test possible errors:\n\n- error `CertificateNotFound`\n\nIntent to work on TLS mode, but certificate is not provided.\n\n- error `ConflictIPAddress`\n\nOne Virtual host tries to listen on a specific IP:port,\nwhile another virtual host tries to listen on a wildcard IP of port(e.g. \":port\").\nOr one virtual host tries to listen on a specific version of wildcard IP of port(e.g. \"0.0.0.0:port\" or \"[::]:port\"),\nwhile another virtual host tries to listen on a wildcard IP of port(e.g. \":port\").\n\n- error `ConflictTLSMode`\n\nFor a specific listening endpoint(IP:port or socket),\none virtual host works on plain mode,\nwhile another virtual host works on TLS mode.\n\n- warning `DuplicatedAddressHostname`\n\nTwo virtual hosts listen on same endpoint, they use the same hostname.\n\n# HostInfo\nthe `HostInfo` is the initial virtual host information, with the properties:\n\n## Listens []string\nIP and/or port the server listens on, e.g. \":80\" or \"127.0.0.1:80\".\nif `CertKeyPaths` or `Certs` available, Serve for TLS HTTP, otherwise Serve for plain HTTP.\nIf port is not specified, use \"80\" as default for Plain HTTP mode, \"443\" for TLS mode.\nIf value contains \"/\" then treat it as a unix socket file.\n\n## ListensPlain []string\nIP and/or port the server listens on, e.g. \":80\" or \"127.0.0.1:80\".\nServe for plain HTTP.\nIf port is not specified, use \"80\" as default.\nIf value contains \"/\" then treat it as a unix socket file.\n\n## ListensTLS []string\nIP and/or port the server listens on, e.g. \":443\" or \"127.0.0.1:443\".\nServe for TLS HTTP.\nIf port is not specified, use \"443\" as default.\nIf value contains \"/\" then treat it as a unix socket file.\n\n## CertKeyPaths [][2]string\nList of TLS certificate file path with each element `[2]string{certPath, keyPath}`.\n\n## Certs []tls.Certificate\nTLS certificates supplied for TLS mode. Several helper functions can be used to load from external PEM files:\n```go\n// load certificate from cert file and key file\nfunc LoadCertificate(certFile, keyFile string) (cert *tls.Certificate, err error)\n\n// load certificates from cert file list and key file list\nfunc LoadCertificates(certFiles, keyFiles []string) (certs []*tls.Certificate, errs []error)\n\n// load certificates from a list, each element is an array that contains certificate file and key file\nfunc LoadCertificatesFromPairs(certKeyFilePairs [][2]string) (certs []*tls.Certificate, errs []error) {\n```\n\n## HostNames []string\nSpecify hostnames associated with the virtual host.\nIf hostname starts with \".\", treat it as a suffix, to match all levels of sub domains, e.g. \".example.com\".\nIf hostname ends with \".\", treat it as a prefix, to match all levels of suffix domains, e.g. \"192.168.1.\".\nIf request host name does not match any virtual host,\nserver will try to use first virtual host that has no hostname,\notherwise use the first virtual host.\n\n## Handler http.Handler\n`http.Handler` to handle requests.\nCould be an instance of `http.ServeMux`, `httputil.ReverseProxy`, or any other type that implements `http.Handler`.\n\n# (*Service) GetAccessibleURLs(includeLoopback bool) [][]string\nGet possible access URLs. For the returned type `[][]string`, the first dimension is virtual host index,\nthe second dimension is the index of URL in that virtual host.\n\n# (*Service) Open() []error\nStart listening on network ports, and serve for http requests. The method will not return until all servers are closed.\ne.g. call `Close` method on another goroutine.\n\n# (*Service) ReloadCertificates() []error\nReload TLS certificates from `CertKeyPaths`.\n\n# (*Service) Close()\nStop serving. To restart serving, a new `Service` must be created.\n\n# (*Service) Shutdown()\nSimilar to `*Service.Close()`, but close server gracefully.\nIt invokes `http.Server`'s `Shutdown()` method internally.\n\n# Architecture \u0026 Internals\n```\nService\n    |  manages\n    v\n    +---------+---------+---------+---------+\n    | handler | handler | handler | handler |\n    +---------+---------+---------+---------+\n    |  vhost  |  vhost  |  vhost  |  vhost  |\n    +---------+--+------+-----+---+---------+\n    | serveable  | serveable  |  serveable  |\n    +------------+------------+-------------+\n    | listenable | listenable | listenable  |\n    +------------+------------+-------------+\n```\n\n## listenable\n`listenable` is a wrapper for `net.Listener`, which open ports or sockets and listen.\n\n## serveable\n`serveable` is a wrapper for `http.Server`. It's `handler` does not serve for end user,\nbut dispatching requests to related virtual host according to the Host header.\n\n## vhost\n`vhost` manages related hostnames, and hold `handler` to deal with requests dispatched from `server`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmjpclab%2Fgovirtualhost","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmjpclab%2Fgovirtualhost","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmjpclab%2Fgovirtualhost/lists"}