Initial vibeproxy implementation
Self-contained HTTP/HTTPS/TCP/UDP reverse proxy manager written in Go, with SQLite storage, a Bootstrap 5 admin UI (Go templates, no JS framework), and a REST API under /api/v1. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QTXFrNP1imCW7jtfL5SZrw
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
package certificates
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// httpChallengeProvider implements lego's challenge.Provider for HTTP-01,
|
||||
// backed by an in-memory token map served by our own HTTP listener at
|
||||
// /.well-known/acme-challenge/. This avoids spinning up a second server on
|
||||
// port 80 — the main proxy HTTP listener delegates to ServeHTTP below.
|
||||
type httpChallengeProvider struct {
|
||||
mu sync.RWMutex
|
||||
tokens map[string]string // token -> key authorization
|
||||
}
|
||||
|
||||
func newHTTPChallengeProvider() *httpChallengeProvider {
|
||||
return &httpChallengeProvider{tokens: map[string]string{}}
|
||||
}
|
||||
|
||||
func (p *httpChallengeProvider) Present(domain, token, keyAuth string) error {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
p.tokens[token] = keyAuth
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *httpChallengeProvider) CleanUp(domain, token, keyAuth string) error {
|
||||
p.mu.Lock()
|
||||
defer p.mu.Unlock()
|
||||
delete(p.tokens, token)
|
||||
return nil
|
||||
}
|
||||
|
||||
const acmeChallengePrefix = "/.well-known/acme-challenge/"
|
||||
|
||||
// ServeHTTP handles ACME HTTP-01 challenge requests. Returns true if the
|
||||
// request was an ACME challenge (handled or not found), false if the
|
||||
// caller should continue normal routing.
|
||||
func (p *httpChallengeProvider) ServeHTTP(w http.ResponseWriter, r *http.Request) bool {
|
||||
if !strings.HasPrefix(r.URL.Path, acmeChallengePrefix) {
|
||||
return false
|
||||
}
|
||||
token := strings.TrimPrefix(r.URL.Path, acmeChallengePrefix)
|
||||
p.mu.RLock()
|
||||
keyAuth, ok := p.tokens[token]
|
||||
p.mu.RUnlock()
|
||||
if !ok {
|
||||
http.NotFound(w, r)
|
||||
return true
|
||||
}
|
||||
w.Header().Set("Content-Type", "text/plain")
|
||||
w.Write([]byte(keyAuth))
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user