77 lines
2.1 KiB
Go
77 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"time"
|
|
|
|
omni "git.yuntuo.hk/k2safe/go-omni"
|
|
"git.yuntuo.hk/k2safe/go-omni/config"
|
|
)
|
|
|
|
type Config struct {
|
|
Server config.Config `json:"server"`
|
|
}
|
|
|
|
func (c Config) Validate() error { return config.AtField("server", c.Server.Validate()) }
|
|
|
|
func run(path string) error {
|
|
cfg, err := config.LoadProject(path, Config{Server: config.Default()})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
a := omni.New(omni.WithConfig(cfg.Server))
|
|
defer a.Close()
|
|
a.GET("/private", func(c *omni.Context) error {
|
|
if c.Header("Authorization") != "Bearer example-only" {
|
|
return omni.Unauthorized("LOGIN_REQUIRED", "login required")
|
|
}
|
|
return c.OK("authenticated")
|
|
})
|
|
server := httptest.NewServer(a)
|
|
defer server.Close()
|
|
client := &http.Client{Timeout: 3 * time.Second}
|
|
defer client.CloseIdleConnections()
|
|
for _, tc := range []struct {
|
|
method, path, auth string
|
|
status int
|
|
}{{"OPTIONS", "/private", "", 204}, {"GET", "/private", "", 401}, {"GET", "/private", "Bearer example-only", 200}, {"GET", "/missing", "", 404}} {
|
|
r, _ := http.NewRequest(tc.method, server.URL+tc.path, nil)
|
|
r.Header.Set("Origin", cfg.Server.CORS.AllowedOrigins[0])
|
|
if tc.method == "OPTIONS" {
|
|
r.Header.Set("Access-Control-Request-Method", "GET")
|
|
r.Header.Set("Access-Control-Request-Headers", "authorization")
|
|
}
|
|
if tc.auth != "" {
|
|
r.Header.Set("Authorization", tc.auth)
|
|
}
|
|
res, err := client.Do(r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, readErr := io.Copy(io.Discard, res.Body)
|
|
closeErr := res.Body.Close()
|
|
if err := errors.Join(readErr, closeErr); err != nil {
|
|
return err
|
|
}
|
|
if res.StatusCode != tc.status || res.Header.Get("Access-Control-Allow-Origin") == "" {
|
|
return fmt.Errorf("unexpected CORS response: %d", res.StatusCode)
|
|
}
|
|
fmt.Printf("%s %s -> %d, CORS allowed\n", tc.method, tc.path, res.StatusCode)
|
|
}
|
|
return nil
|
|
}
|
|
func main() {
|
|
path := flag.String("config", "examples/cors/config.yaml", "selected configuration file")
|
|
flag.Parse()
|
|
if err := run(*path); err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
}
|