Complete refactor to new grpc control plane and only http proxy for carts (#4)
Co-authored-by: matst80 <mats.tornberg@gmail.com> Reviewed-on: https://git.tornberg.me/mats/go-cart-actor/pulls/4 Co-authored-by: Mats Törnberg <mats@tornberg.me> Co-committed-by: Mats Törnberg <mats@tornberg.me>
This commit was merged in pull request #4.
This commit is contained in:
69
cmd/cart/openapi_embed.go
Normal file
69
cmd/cart/openapi_embed.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
_ "embed"
|
||||
"encoding/hex"
|
||||
"net/http"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// openapi_embed.go: Provides embedded OpenAPI spec and helper to mount handler.
|
||||
|
||||
//go:embed openapi.json
|
||||
var openapiJSON []byte
|
||||
|
||||
var (
|
||||
openapiOnce sync.Once
|
||||
openapiETag string
|
||||
)
|
||||
|
||||
// initOpenAPIMetadata computes immutable metadata for the embedded spec.
|
||||
func initOpenAPIMetadata() {
|
||||
sum := sha256.Sum256(openapiJSON)
|
||||
openapiETag = `W/"` + hex.EncodeToString(sum[:8]) + `"` // weak ETag with first 8 bytes
|
||||
}
|
||||
|
||||
// ServeEmbeddedOpenAPI serves the embedded OpenAPI JSON spec at /openapi.json.
|
||||
// It supports GET and HEAD and implements basic ETag caching.
|
||||
func ServeEmbeddedOpenAPI(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet && r.Method != http.MethodHead {
|
||||
w.Header().Set("Allow", "GET, HEAD")
|
||||
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
openapiOnce.Do(initOpenAPIMetadata)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
w.Header().Set("Cache-Control", "no-cache")
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
w.Header().Set("ETag", openapiETag)
|
||||
|
||||
if match := r.Header.Get("If-None-Match"); match != "" {
|
||||
if bytes.Contains([]byte(match), []byte(openapiETag)) {
|
||||
w.WriteHeader(http.StatusNotModified)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if r.Method == http.MethodHead {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, _ = w.Write(openapiJSON)
|
||||
}
|
||||
|
||||
// Optional: function to access raw spec bytes programmatically.
|
||||
func OpenAPISpecBytes() []byte {
|
||||
return openapiJSON
|
||||
}
|
||||
|
||||
// Optional: function to access current ETag.
|
||||
func OpenAPIETag() string {
|
||||
openapiOnce.Do(initOpenAPIMetadata)
|
||||
return openapiETag
|
||||
}
|
||||
Reference in New Issue
Block a user