Merge pull request #641 from ipfs/tests/update-sharness-configs
Sharness: update configuration files used in sharness
This commit is contained in:
commit
935d9840b4
|
@ -6,10 +6,12 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ipfs/ipfs-cluster/config"
|
"github.com/ipfs/ipfs-cluster/config"
|
||||||
|
"github.com/rs/cors"
|
||||||
|
|
||||||
"github.com/kelseyhightower/envconfig"
|
"github.com/kelseyhightower/envconfig"
|
||||||
|
|
||||||
|
@ -32,11 +34,26 @@ const (
|
||||||
|
|
||||||
// These are the default values for Config.
|
// These are the default values for Config.
|
||||||
var (
|
var (
|
||||||
DefaultHeaders = map[string][]string{
|
DefaultHeaders = map[string][]string{}
|
||||||
"Access-Control-Allow-Headers": []string{"X-Requested-With", "Range"},
|
)
|
||||||
"Access-Control-Allow-Methods": []string{"GET"},
|
|
||||||
"Access-Control-Allow-Origin": []string{"*"},
|
// CORS defaults
|
||||||
|
var (
|
||||||
|
DefaultCORSAllowedOrigins = []string{"*"}
|
||||||
|
DefaultCORSAllowedMethods = []string{
|
||||||
|
http.MethodGet,
|
||||||
}
|
}
|
||||||
|
// rs/cors this will set sensible defaults when empty:
|
||||||
|
// {"Origin", "Accept", "Content-Type", "X-Requested-With"}
|
||||||
|
DefaultCORSAllowedHeaders = []string{}
|
||||||
|
DefaultCORSExposedHeaders = []string{
|
||||||
|
"Content-Type",
|
||||||
|
"X-Stream-Output",
|
||||||
|
"X-Chunked-Output",
|
||||||
|
"X-Content-Length",
|
||||||
|
}
|
||||||
|
DefaultCORSAllowCredentials = true
|
||||||
|
DefaultCORSMaxAge time.Duration // 0. Means always.
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config is used to intialize the API object and allows to
|
// Config is used to intialize the API object and allows to
|
||||||
|
@ -85,8 +102,16 @@ type Config struct {
|
||||||
BasicAuthCreds map[string]string
|
BasicAuthCreds map[string]string
|
||||||
|
|
||||||
// Headers provides customization for the headers returned
|
// Headers provides customization for the headers returned
|
||||||
// by the API. By default it sets a CORS policy.
|
// by the API on existing routes.
|
||||||
Headers map[string][]string
|
Headers map[string][]string
|
||||||
|
|
||||||
|
// CORS header management
|
||||||
|
CORSAllowedOrigins []string
|
||||||
|
CORSAllowedMethods []string
|
||||||
|
CORSAllowedHeaders []string
|
||||||
|
CORSExposedHeaders []string
|
||||||
|
CORSAllowCredentials bool
|
||||||
|
CORSMaxAge time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
type jsonConfig struct {
|
type jsonConfig struct {
|
||||||
|
@ -105,6 +130,13 @@ type jsonConfig struct {
|
||||||
|
|
||||||
BasicAuthCreds map[string]string `json:"basic_auth_credentials"`
|
BasicAuthCreds map[string]string `json:"basic_auth_credentials"`
|
||||||
Headers map[string][]string `json:"headers"`
|
Headers map[string][]string `json:"headers"`
|
||||||
|
|
||||||
|
CORSAllowedOrigins []string `json:"cors_allowed_origins"`
|
||||||
|
CORSAllowedMethods []string `json:"cors_allowed_methods"`
|
||||||
|
CORSAllowedHeaders []string `json:"cors_allowed_headers"`
|
||||||
|
CORSExposedHeaders []string `json:"cors_exposed_headers"`
|
||||||
|
CORSAllowCredentials bool `json:"cors_allow_credentials"`
|
||||||
|
CORSMaxAge string `json:"cors_max_age"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigKey returns a human-friendly identifier for this type of
|
// ConfigKey returns a human-friendly identifier for this type of
|
||||||
|
@ -136,6 +168,13 @@ func (cfg *Config) Default() error {
|
||||||
// Headers
|
// Headers
|
||||||
cfg.Headers = DefaultHeaders
|
cfg.Headers = DefaultHeaders
|
||||||
|
|
||||||
|
cfg.CORSAllowedOrigins = DefaultCORSAllowedOrigins
|
||||||
|
cfg.CORSAllowedMethods = DefaultCORSAllowedMethods
|
||||||
|
cfg.CORSAllowedHeaders = DefaultCORSAllowedHeaders
|
||||||
|
cfg.CORSExposedHeaders = DefaultCORSExposedHeaders
|
||||||
|
cfg.CORSAllowCredentials = DefaultCORSAllowCredentials
|
||||||
|
cfg.CORSMaxAge = DefaultCORSMaxAge
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,7 +193,9 @@ func (cfg *Config) Validate() error {
|
||||||
case cfg.BasicAuthCreds != nil && len(cfg.BasicAuthCreds) == 0:
|
case cfg.BasicAuthCreds != nil && len(cfg.BasicAuthCreds) == 0:
|
||||||
return errors.New("restapi.basic_auth_creds should be null or have at least one entry")
|
return errors.New("restapi.basic_auth_creds should be null or have at least one entry")
|
||||||
case (cfg.pathSSLCertFile != "" || cfg.pathSSLKeyFile != "") && cfg.TLS == nil:
|
case (cfg.pathSSLCertFile != "" || cfg.pathSSLKeyFile != "") && cfg.TLS == nil:
|
||||||
return errors.New("missing TLS configuration")
|
return errors.New("restapi: missing TLS configuration")
|
||||||
|
case (cfg.CORSMaxAge < 0):
|
||||||
|
return errors.New("restapi.cors_max_age is invalid")
|
||||||
}
|
}
|
||||||
|
|
||||||
return cfg.validateLibp2p()
|
return cfg.validateLibp2p()
|
||||||
|
@ -232,12 +273,23 @@ func (cfg *Config) loadHTTPOptions(jcfg *jsonConfig) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CORS
|
||||||
|
cfg.CORSAllowedOrigins = jcfg.CORSAllowedOrigins
|
||||||
|
cfg.CORSAllowedMethods = jcfg.CORSAllowedMethods
|
||||||
|
cfg.CORSAllowedHeaders = jcfg.CORSAllowedHeaders
|
||||||
|
cfg.CORSExposedHeaders = jcfg.CORSExposedHeaders
|
||||||
|
cfg.CORSAllowCredentials = jcfg.CORSAllowCredentials
|
||||||
|
if jcfg.CORSMaxAge == "" { // compatibility
|
||||||
|
jcfg.CORSMaxAge = "0s"
|
||||||
|
}
|
||||||
|
|
||||||
return config.ParseDurations(
|
return config.ParseDurations(
|
||||||
"restapi",
|
"restapi",
|
||||||
&config.DurationOpt{Duration: jcfg.ReadTimeout, Dst: &cfg.ReadTimeout, Name: "read_timeout"},
|
&config.DurationOpt{Duration: jcfg.ReadTimeout, Dst: &cfg.ReadTimeout, Name: "read_timeout"},
|
||||||
&config.DurationOpt{Duration: jcfg.ReadHeaderTimeout, Dst: &cfg.ReadHeaderTimeout, Name: "read_header_timeout"},
|
&config.DurationOpt{Duration: jcfg.ReadHeaderTimeout, Dst: &cfg.ReadHeaderTimeout, Name: "read_header_timeout"},
|
||||||
&config.DurationOpt{Duration: jcfg.WriteTimeout, Dst: &cfg.WriteTimeout, Name: "write_timeout"},
|
&config.DurationOpt{Duration: jcfg.WriteTimeout, Dst: &cfg.WriteTimeout, Name: "write_timeout"},
|
||||||
&config.DurationOpt{Duration: jcfg.IdleTimeout, Dst: &cfg.IdleTimeout, Name: "idle_timeout"},
|
&config.DurationOpt{Duration: jcfg.IdleTimeout, Dst: &cfg.IdleTimeout, Name: "idle_timeout"},
|
||||||
|
&config.DurationOpt{Duration: jcfg.CORSMaxAge, Dst: &cfg.CORSMaxAge, Name: "cors_max_age"},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,6 +375,12 @@ func (cfg *Config) ToJSON() (raw []byte, err error) {
|
||||||
IdleTimeout: cfg.IdleTimeout.String(),
|
IdleTimeout: cfg.IdleTimeout.String(),
|
||||||
BasicAuthCreds: cfg.BasicAuthCreds,
|
BasicAuthCreds: cfg.BasicAuthCreds,
|
||||||
Headers: cfg.Headers,
|
Headers: cfg.Headers,
|
||||||
|
CORSAllowedOrigins: cfg.CORSAllowedOrigins,
|
||||||
|
CORSAllowedMethods: cfg.CORSAllowedMethods,
|
||||||
|
CORSAllowedHeaders: cfg.CORSAllowedHeaders,
|
||||||
|
CORSExposedHeaders: cfg.CORSExposedHeaders,
|
||||||
|
CORSAllowCredentials: cfg.CORSAllowCredentials,
|
||||||
|
CORSMaxAge: cfg.CORSMaxAge.String(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.ID != "" {
|
if cfg.ID != "" {
|
||||||
|
@ -343,6 +401,20 @@ func (cfg *Config) ToJSON() (raw []byte, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cfg *Config) corsOptions() *cors.Options {
|
||||||
|
maxAgeSeconds := int(cfg.CORSMaxAge / time.Second)
|
||||||
|
|
||||||
|
return &cors.Options{
|
||||||
|
AllowedOrigins: cfg.CORSAllowedOrigins,
|
||||||
|
AllowedMethods: cfg.CORSAllowedMethods,
|
||||||
|
AllowedHeaders: cfg.CORSAllowedHeaders,
|
||||||
|
ExposedHeaders: cfg.CORSExposedHeaders,
|
||||||
|
AllowCredentials: cfg.CORSAllowCredentials,
|
||||||
|
MaxAge: maxAgeSeconds,
|
||||||
|
Debug: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func newTLSConfig(certFile, keyFile string) (*tls.Config, error) {
|
func newTLSConfig(certFile, keyFile string) (*tls.Config, error) {
|
||||||
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
|
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -13,14 +13,20 @@ import (
|
||||||
|
|
||||||
var cfgJSON = []byte(`
|
var cfgJSON = []byte(`
|
||||||
{
|
{
|
||||||
"listen_multiaddress": "/ip4/127.0.0.1/tcp/9094",
|
"listen_multiaddress": "/ip4/127.0.0.1/tcp/12122",
|
||||||
"ssl_cert_file": "test/server.crt",
|
"ssl_cert_file": "test/server.crt",
|
||||||
"ssl_key_file": "test/server.key",
|
"ssl_key_file": "test/server.key",
|
||||||
"read_timeout": "30s",
|
"read_timeout": "30s",
|
||||||
"read_header_timeout": "5s",
|
"read_header_timeout": "5s",
|
||||||
"write_timeout": "1m0s",
|
"write_timeout": "1m0s",
|
||||||
"idle_timeout": "2m0s",
|
"idle_timeout": "2m0s",
|
||||||
"basic_auth_credentials": null
|
"basic_auth_credentials": null,
|
||||||
|
"cors_allowed_origins": ["myorigin"],
|
||||||
|
"cors_allowed_methods": ["GET"],
|
||||||
|
"cors_allowed_headers": ["X-Custom"],
|
||||||
|
"cors_exposed_headers": ["X-Chunked-Output"],
|
||||||
|
"cors_allow_credentials": false,
|
||||||
|
"cors_max_age": "1s"
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,8 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/rs/cors"
|
||||||
|
|
||||||
"github.com/ipfs/ipfs-cluster/adder/adderutils"
|
"github.com/ipfs/ipfs-cluster/adder/adderutils"
|
||||||
types "github.com/ipfs/ipfs-cluster/api"
|
types "github.com/ipfs/ipfs-cluster/api"
|
||||||
|
|
||||||
|
@ -108,13 +110,20 @@ func NewAPIWithHost(cfg *Config, h host.Host) (*API, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Our handler is a gorilla router,
|
||||||
|
// wrapped with the cors handler,
|
||||||
|
// wrapped with the basic auth handler.
|
||||||
router := mux.NewRouter().StrictSlash(true)
|
router := mux.NewRouter().StrictSlash(true)
|
||||||
|
handler := basicAuthHandler(
|
||||||
|
cfg.BasicAuthCreds,
|
||||||
|
cors.New(*cfg.corsOptions()).Handler(router),
|
||||||
|
)
|
||||||
s := &http.Server{
|
s := &http.Server{
|
||||||
ReadTimeout: cfg.ReadTimeout,
|
ReadTimeout: cfg.ReadTimeout,
|
||||||
ReadHeaderTimeout: cfg.ReadHeaderTimeout,
|
ReadHeaderTimeout: cfg.ReadHeaderTimeout,
|
||||||
WriteTimeout: cfg.WriteTimeout,
|
WriteTimeout: cfg.WriteTimeout,
|
||||||
IdleTimeout: cfg.IdleTimeout,
|
IdleTimeout: cfg.IdleTimeout,
|
||||||
Handler: router,
|
Handler: handler,
|
||||||
}
|
}
|
||||||
|
|
||||||
// See: https://github.com/ipfs/go-ipfs/issues/5168
|
// See: https://github.com/ipfs/go-ipfs/issues/5168
|
||||||
|
@ -225,9 +234,6 @@ func (api *API) Host() host.Host {
|
||||||
|
|
||||||
func (api *API) addRoutes(router *mux.Router) {
|
func (api *API) addRoutes(router *mux.Router) {
|
||||||
for _, route := range api.routes() {
|
for _, route := range api.routes() {
|
||||||
if api.config.BasicAuthCreds != nil {
|
|
||||||
route.HandlerFunc = basicAuth(route.HandlerFunc, api.config.BasicAuthCreds)
|
|
||||||
}
|
|
||||||
router.
|
router.
|
||||||
Methods(route.Method).
|
Methods(route.Method).
|
||||||
Path(route.Pattern).
|
Path(route.Pattern).
|
||||||
|
@ -237,8 +243,13 @@ func (api *API) addRoutes(router *mux.Router) {
|
||||||
api.router = router
|
api.router = router
|
||||||
}
|
}
|
||||||
|
|
||||||
func basicAuth(h http.HandlerFunc, credentials map[string]string) http.HandlerFunc {
|
// basicAuth wraps a given handler with basic authentication
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
func basicAuthHandler(credentials map[string]string, h http.Handler) http.Handler {
|
||||||
|
if credentials == nil {
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
wrap := func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
w.Header().Set("WWW-Authenticate", `Basic realm="Restricted"`)
|
||||||
username, password, ok := r.BasicAuth()
|
username, password, ok := r.BasicAuth()
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -268,6 +279,7 @@ func basicAuth(h http.HandlerFunc, credentials map[string]string) http.HandlerFu
|
||||||
}
|
}
|
||||||
h.ServeHTTP(w, r)
|
h.ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
|
return http.HandlerFunc(wrap)
|
||||||
}
|
}
|
||||||
|
|
||||||
func unauthorizedResp() (string, error) {
|
func unauthorizedResp() (string, error) {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ipfs/ipfs-cluster/api"
|
"github.com/ipfs/ipfs-cluster/api"
|
||||||
"github.com/ipfs/ipfs-cluster/test"
|
"github.com/ipfs/ipfs-cluster/test"
|
||||||
|
@ -27,6 +28,7 @@ import (
|
||||||
const (
|
const (
|
||||||
SSLCertFile = "test/server.crt"
|
SSLCertFile = "test/server.crt"
|
||||||
SSLKeyFile = "test/server.key"
|
SSLKeyFile = "test/server.key"
|
||||||
|
clientOrigin = "myorigin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func testAPI(t *testing.T) *API {
|
func testAPI(t *testing.T) *API {
|
||||||
|
@ -39,6 +41,10 @@ func testAPI(t *testing.T) *API {
|
||||||
cfg := &Config{}
|
cfg := &Config{}
|
||||||
cfg.Default()
|
cfg.Default()
|
||||||
cfg.HTTPListenAddr = apiMAddr
|
cfg.HTTPListenAddr = apiMAddr
|
||||||
|
cfg.CORSAllowedOrigins = []string{clientOrigin}
|
||||||
|
cfg.CORSAllowedMethods = []string{"GET", "POST", "DELETE"}
|
||||||
|
//cfg.CORSAllowedHeaders = []string{"Content-Type"}
|
||||||
|
cfg.CORSMaxAge = 10 * time.Minute
|
||||||
|
|
||||||
rest, err := NewAPIWithHost(cfg, h)
|
rest, err := NewAPIWithHost(cfg, h)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -133,6 +139,10 @@ func checkHeaders(t *testing.T, rest *API, url string, headers http.Header) {
|
||||||
if headers.Get("Content-Type") != "application/json" {
|
if headers.Get("Content-Type") != "application/json" {
|
||||||
t.Errorf("%s is not application/json", url)
|
t.Errorf("%s is not application/json", url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if eh := headers.Get("Access-Control-Expose-Headers"); eh == "" {
|
||||||
|
t.Error("AC-Expose-Headers not set")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// makes a libp2p host that knows how to talk to the rest API host.
|
// makes a libp2p host that knows how to talk to the rest API host.
|
||||||
|
@ -194,7 +204,9 @@ func makeGet(t *testing.T, rest *API, url string, resp interface{}) {
|
||||||
h := makeHost(t, rest)
|
h := makeHost(t, rest)
|
||||||
defer h.Close()
|
defer h.Close()
|
||||||
c := httpClient(t, h, isHTTPS(url))
|
c := httpClient(t, h, isHTTPS(url))
|
||||||
httpResp, err := c.Get(url)
|
req, _ := http.NewRequest(http.MethodGet, url, nil)
|
||||||
|
req.Header.Set("Origin", clientOrigin)
|
||||||
|
httpResp, err := c.Do(req)
|
||||||
processResp(t, httpResp, err, resp)
|
processResp(t, httpResp, err, resp)
|
||||||
checkHeaders(t, rest, url, httpResp.Header)
|
checkHeaders(t, rest, url, httpResp.Header)
|
||||||
}
|
}
|
||||||
|
@ -207,7 +219,10 @@ func makePostWithContentType(t *testing.T, rest *API, url string, body []byte, c
|
||||||
h := makeHost(t, rest)
|
h := makeHost(t, rest)
|
||||||
defer h.Close()
|
defer h.Close()
|
||||||
c := httpClient(t, h, isHTTPS(url))
|
c := httpClient(t, h, isHTTPS(url))
|
||||||
httpResp, err := c.Post(url, contentType, bytes.NewReader(body))
|
req, _ := http.NewRequest(http.MethodPost, url, bytes.NewReader(body))
|
||||||
|
req.Header.Set("Content-Type", contentType)
|
||||||
|
req.Header.Set("Origin", clientOrigin)
|
||||||
|
httpResp, err := c.Do(req)
|
||||||
processResp(t, httpResp, err, resp)
|
processResp(t, httpResp, err, resp)
|
||||||
checkHeaders(t, rest, url, httpResp.Header)
|
checkHeaders(t, rest, url, httpResp.Header)
|
||||||
}
|
}
|
||||||
|
@ -216,17 +231,32 @@ func makeDelete(t *testing.T, rest *API, url string, resp interface{}) {
|
||||||
h := makeHost(t, rest)
|
h := makeHost(t, rest)
|
||||||
defer h.Close()
|
defer h.Close()
|
||||||
c := httpClient(t, h, isHTTPS(url))
|
c := httpClient(t, h, isHTTPS(url))
|
||||||
req, _ := http.NewRequest("DELETE", url, bytes.NewReader([]byte{}))
|
req, _ := http.NewRequest(http.MethodDelete, url, bytes.NewReader([]byte{}))
|
||||||
|
req.Header.Set("Origin", clientOrigin)
|
||||||
httpResp, err := c.Do(req)
|
httpResp, err := c.Do(req)
|
||||||
processResp(t, httpResp, err, resp)
|
processResp(t, httpResp, err, resp)
|
||||||
checkHeaders(t, rest, url, httpResp.Header)
|
checkHeaders(t, rest, url, httpResp.Header)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeOptions(t *testing.T, rest *API, url string, reqHeaders http.Header) http.Header {
|
||||||
|
h := makeHost(t, rest)
|
||||||
|
defer h.Close()
|
||||||
|
c := httpClient(t, h, isHTTPS(url))
|
||||||
|
req, _ := http.NewRequest(http.MethodOptions, url, nil)
|
||||||
|
req.Header = reqHeaders
|
||||||
|
httpResp, err := c.Do(req)
|
||||||
|
processResp(t, httpResp, err, nil)
|
||||||
|
return httpResp.Header
|
||||||
|
}
|
||||||
|
|
||||||
func makeStreamingPost(t *testing.T, rest *API, url string, body io.Reader, contentType string, resp interface{}) {
|
func makeStreamingPost(t *testing.T, rest *API, url string, body io.Reader, contentType string, resp interface{}) {
|
||||||
h := makeHost(t, rest)
|
h := makeHost(t, rest)
|
||||||
defer h.Close()
|
defer h.Close()
|
||||||
c := httpClient(t, h, isHTTPS(url))
|
c := httpClient(t, h, isHTTPS(url))
|
||||||
httpResp, err := c.Post(url, contentType, body)
|
req, _ := http.NewRequest(http.MethodPost, url, body)
|
||||||
|
req.Header.Set("Content-Type", contentType)
|
||||||
|
req.Header.Set("Origin", clientOrigin)
|
||||||
|
httpResp, err := c.Do(req)
|
||||||
processStreamingResp(t, httpResp, err, resp)
|
processStreamingResp(t, httpResp, err, resp)
|
||||||
checkHeaders(t, rest, url, httpResp.Header)
|
checkHeaders(t, rest, url, httpResp.Header)
|
||||||
}
|
}
|
||||||
|
@ -825,3 +855,55 @@ func TestAPIRecoverAllEndpoint(t *testing.T) {
|
||||||
|
|
||||||
testBothEndpoints(t, tf)
|
testBothEndpoints(t, tf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCORS(t *testing.T) {
|
||||||
|
rest := testAPI(t)
|
||||||
|
defer rest.Shutdown()
|
||||||
|
|
||||||
|
type testcase struct {
|
||||||
|
method string
|
||||||
|
path string
|
||||||
|
}
|
||||||
|
|
||||||
|
tf := func(t *testing.T, url urlF) {
|
||||||
|
reqHeaders := make(http.Header)
|
||||||
|
reqHeaders.Set("Origin", "myorigin")
|
||||||
|
reqHeaders.Set("Access-Control-Request-Headers", "Content-Type")
|
||||||
|
|
||||||
|
for _, tc := range []testcase{
|
||||||
|
testcase{"GET", "/pins"},
|
||||||
|
// testcase{},
|
||||||
|
} {
|
||||||
|
reqHeaders.Set("Access-Control-Request-Method", tc.method)
|
||||||
|
headers := makeOptions(t, rest, url(rest)+tc.path, reqHeaders)
|
||||||
|
aorigin := headers.Get("Access-Control-Allow-Origin")
|
||||||
|
amethods := headers.Get("Access-Control-Allow-Methods")
|
||||||
|
aheaders := headers.Get("Access-Control-Allow-Headers")
|
||||||
|
acreds := headers.Get("Access-Control-Allow-Credentials")
|
||||||
|
maxage := headers.Get("Access-Control-Max-Age")
|
||||||
|
|
||||||
|
if aorigin != "myorigin" {
|
||||||
|
t.Error("Bad ACA-Origin:", aorigin)
|
||||||
|
}
|
||||||
|
|
||||||
|
if amethods != tc.method {
|
||||||
|
t.Error("Bad ACA-Methods:", amethods)
|
||||||
|
}
|
||||||
|
|
||||||
|
if aheaders != "Content-Type" {
|
||||||
|
t.Error("Bad ACA-Headers:", aheaders)
|
||||||
|
}
|
||||||
|
|
||||||
|
if acreds != "true" {
|
||||||
|
t.Error("Bad ACA-Credentials:", acreds)
|
||||||
|
}
|
||||||
|
|
||||||
|
if maxage != "600" {
|
||||||
|
t.Error("Bad AC-Max-Age:", maxage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
testBothEndpoints(t, tf)
|
||||||
|
}
|
||||||
|
|
|
@ -155,6 +155,12 @@
|
||||||
"hash": "QmeP7Gybon3hs9KhoxSFvzqAHQS6xgyKYvsnjqktaXX3QN",
|
"hash": "QmeP7Gybon3hs9KhoxSFvzqAHQS6xgyKYvsnjqktaXX3QN",
|
||||||
"name": "go-libp2p-pubsub",
|
"name": "go-libp2p-pubsub",
|
||||||
"version": "100.11.9"
|
"version": "100.11.9"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"author": "hsanjuan",
|
||||||
|
"hash": "QmNNk4iczWp8Q4R1mXQ2mrrjQvWisYqMqbW1an8qGbJZsM",
|
||||||
|
"name": "cors",
|
||||||
|
"version": "1.6.0"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"gxVersion": "0.11.0",
|
"gxVersion": "0.11.0",
|
||||||
|
|
|
@ -24,10 +24,18 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"api": {
|
"api": {
|
||||||
|
"ipfsproxy": {
|
||||||
|
"listen_multiaddress": "/ip4/127.0.0.1/tcp/9095",
|
||||||
|
"node_multiaddress": "/ip4/127.0.0.1/tcp/5001",
|
||||||
|
"read_timeout": "10m0s",
|
||||||
|
"read_header_timeout": "5s",
|
||||||
|
"write_timeout": "10m0s",
|
||||||
|
"idle_timeout": "1m0s"
|
||||||
|
},
|
||||||
"restapi": {
|
"restapi": {
|
||||||
"ssl_cert_file": "",
|
"ssl_cert_file": "",
|
||||||
"ssl_key_file": "",
|
"ssl_key_file": "",
|
||||||
"listen_multiaddress": "/ip4/127.0.0.1/tcp/9094",
|
"http_listen_multiaddress": "/ip4/127.0.0.1/tcp/9094",
|
||||||
"read_timeout": "30s",
|
"read_timeout": "30s",
|
||||||
"read_header_timeout": "5s",
|
"read_header_timeout": "5s",
|
||||||
"write_timeout": "1m0s",
|
"write_timeout": "1m0s",
|
||||||
|
@ -35,23 +43,50 @@
|
||||||
"basic_auth_credentials": {
|
"basic_auth_credentials": {
|
||||||
"testuser": "testpass",
|
"testuser": "testpass",
|
||||||
"userwithoutpass": ""
|
"userwithoutpass": ""
|
||||||
}
|
},
|
||||||
|
"cors_allowed_origins": [
|
||||||
|
"*"
|
||||||
|
],
|
||||||
|
"cors_allowed_methods": [
|
||||||
|
"GET"
|
||||||
|
],
|
||||||
|
"cors_allowed_headers": [],
|
||||||
|
"cors_exposed_headers": [
|
||||||
|
"Content-Type",
|
||||||
|
"X-Stream-Output",
|
||||||
|
"X-Chunked-Output",
|
||||||
|
"X-Content-Length"
|
||||||
|
],
|
||||||
|
"cors_allow_credentials": true,
|
||||||
|
"cors_max_age": "0s"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ipfs_connector": {
|
"ipfs_connector": {
|
||||||
"ipfshttp": {
|
"ipfshttp": {
|
||||||
"proxy_listen_multiaddress": "/ip4/127.0.0.1/tcp/9095",
|
|
||||||
"node_multiaddress": "/ip4/127.0.0.1/tcp/5001",
|
"node_multiaddress": "/ip4/127.0.0.1/tcp/5001",
|
||||||
"connect_swarms_delay": "7s",
|
"connect_swarms_delay": "30s",
|
||||||
"proxy_read_timeout": "10m0s",
|
"pin_method": "refs",
|
||||||
"proxy_read_header_timeout": "5s",
|
"ipfs_request_timeout": "5m0s",
|
||||||
"proxy_write_timeout": "10m0s",
|
"pin_timeout": "24h0m0s",
|
||||||
"proxy_idle_timeout": "1m0s"
|
"unpin_timeout": "3h0m0s"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pin_tracker": {
|
||||||
|
"maptracker": {
|
||||||
|
"max_pin_queue_size": 50000,
|
||||||
|
"concurrent_pins": 10
|
||||||
|
},
|
||||||
|
"stateless": {
|
||||||
|
"max_pin_queue_size": 50000,
|
||||||
|
"concurrent_pins": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"monitor": {
|
"monitor": {
|
||||||
"monbasic": {
|
"monbasic": {
|
||||||
"check_interval": "15s"
|
"check_interval": "15s"
|
||||||
|
},
|
||||||
|
"pubsubmon": {
|
||||||
|
"check_interval": "15s"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"informer": {
|
"informer": {
|
||||||
|
|
|
@ -24,10 +24,18 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"api": {
|
"api": {
|
||||||
|
"ipfsproxy": {
|
||||||
|
"listen_multiaddress": "/ip4/127.0.0.1/tcp/9095",
|
||||||
|
"node_multiaddress": "/ip4/127.0.0.1/tcp/5001",
|
||||||
|
"read_timeout": "10m0s",
|
||||||
|
"read_header_timeout": "5s",
|
||||||
|
"write_timeout": "10m0s",
|
||||||
|
"idle_timeout": "1m0s"
|
||||||
|
},
|
||||||
"restapi": {
|
"restapi": {
|
||||||
"ssl_cert_file": "server.crt",
|
"ssl_cert_file": "server.crt",
|
||||||
"ssl_key_file": "server.key",
|
"ssl_key_file": "server.key",
|
||||||
"listen_multiaddress": "/ip4/127.0.0.1/tcp/9094",
|
"http_listen_multiaddress": "/ip4/127.0.0.1/tcp/9094",
|
||||||
"read_timeout": "30s",
|
"read_timeout": "30s",
|
||||||
"read_header_timeout": "5s",
|
"read_header_timeout": "5s",
|
||||||
"write_timeout": "1m0s",
|
"write_timeout": "1m0s",
|
||||||
|
@ -35,23 +43,50 @@
|
||||||
"basic_auth_credentials": {
|
"basic_auth_credentials": {
|
||||||
"testuser": "testpass",
|
"testuser": "testpass",
|
||||||
"userwithoutpass": ""
|
"userwithoutpass": ""
|
||||||
}
|
},
|
||||||
|
"cors_allowed_origins": [
|
||||||
|
"*"
|
||||||
|
],
|
||||||
|
"cors_allowed_methods": [
|
||||||
|
"GET"
|
||||||
|
],
|
||||||
|
"cors_allowed_headers": [],
|
||||||
|
"cors_exposed_headers": [
|
||||||
|
"Content-Type",
|
||||||
|
"X-Stream-Output",
|
||||||
|
"X-Chunked-Output",
|
||||||
|
"X-Content-Length"
|
||||||
|
],
|
||||||
|
"cors_allow_credentials": true,
|
||||||
|
"cors_max_age": "0s"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ipfs_connector": {
|
"ipfs_connector": {
|
||||||
"ipfshttp": {
|
"ipfshttp": {
|
||||||
"proxy_listen_multiaddress": "/ip4/127.0.0.1/tcp/9095",
|
|
||||||
"node_multiaddress": "/ip4/127.0.0.1/tcp/5001",
|
"node_multiaddress": "/ip4/127.0.0.1/tcp/5001",
|
||||||
"connect_swarms_delay": "7s",
|
"connect_swarms_delay": "30s",
|
||||||
"proxy_read_timeout": "10m0s",
|
"pin_method": "refs",
|
||||||
"proxy_read_header_timeout": "5s",
|
"ipfs_request_timeout": "5m0s",
|
||||||
"proxy_write_timeout": "10m0s",
|
"pin_timeout": "24h0m0s",
|
||||||
"proxy_idle_timeout": "1m0s"
|
"unpin_timeout": "3h0m0s"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pin_tracker": {
|
||||||
|
"maptracker": {
|
||||||
|
"max_pin_queue_size": 50000,
|
||||||
|
"concurrent_pins": 10
|
||||||
|
},
|
||||||
|
"stateless": {
|
||||||
|
"max_pin_queue_size": 50000,
|
||||||
|
"concurrent_pins": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"monitor": {
|
"monitor": {
|
||||||
"monbasic": {
|
"monbasic": {
|
||||||
"check_interval": "15s"
|
"check_interval": "15s"
|
||||||
|
},
|
||||||
|
"pubsubmon": {
|
||||||
|
"check_interval": "15s"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"informer": {
|
"informer": {
|
||||||
|
|
|
@ -24,30 +24,66 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"api": {
|
"api": {
|
||||||
|
"ipfsproxy": {
|
||||||
|
"listen_multiaddress": "/ip4/127.0.0.1/tcp/9095",
|
||||||
|
"node_multiaddress": "/ip4/127.0.0.1/tcp/5001",
|
||||||
|
"read_timeout": "10m0s",
|
||||||
|
"read_header_timeout": "5s",
|
||||||
|
"write_timeout": "10m0s",
|
||||||
|
"idle_timeout": "1m0s"
|
||||||
|
},
|
||||||
"restapi": {
|
"restapi": {
|
||||||
"ssl_cert_file": "server.crt",
|
"ssl_cert_file": "server.crt",
|
||||||
"ssl_key_file": "server.key",
|
"ssl_key_file": "server.key",
|
||||||
"listen_multiaddress": "/ip4/127.0.0.1/tcp/9094",
|
"http_listen_multiaddress": "/ip4/127.0.0.1/tcp/9094",
|
||||||
"read_timeout": "30s",
|
"read_timeout": "30s",
|
||||||
"read_header_timeout": "5s",
|
"read_header_timeout": "5s",
|
||||||
"write_timeout": "1m0s",
|
"write_timeout": "1m0s",
|
||||||
"idle_timeout": "2m0s"
|
"idle_timeout": "2m0s",
|
||||||
|
"basic_auth_credentials": null,
|
||||||
|
"cors_allowed_origins": [
|
||||||
|
"*"
|
||||||
|
],
|
||||||
|
"cors_allowed_methods": [
|
||||||
|
"GET"
|
||||||
|
],
|
||||||
|
"cors_allowed_headers": [],
|
||||||
|
"cors_exposed_headers": [
|
||||||
|
"Content-Type",
|
||||||
|
"X-Stream-Output",
|
||||||
|
"X-Chunked-Output",
|
||||||
|
"X-Content-Length"
|
||||||
|
],
|
||||||
|
"cors_allow_credentials": true,
|
||||||
|
"cors_max_age": "0s"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ipfs_connector": {
|
"ipfs_connector": {
|
||||||
"ipfshttp": {
|
"ipfshttp": {
|
||||||
"proxy_listen_multiaddress": "/ip4/127.0.0.1/tcp/9095",
|
|
||||||
"node_multiaddress": "/ip4/127.0.0.1/tcp/5001",
|
"node_multiaddress": "/ip4/127.0.0.1/tcp/5001",
|
||||||
"connect_swarms_delay": "7s",
|
"connect_swarms_delay": "30s",
|
||||||
"proxy_read_timeout": "10m0s",
|
"pin_method": "refs",
|
||||||
"proxy_read_header_timeout": "5s",
|
"ipfs_request_timeout": "5m0s",
|
||||||
"proxy_write_timeout": "10m0s",
|
"pin_timeout": "24h0m0s",
|
||||||
"proxy_idle_timeout": "1m0s"
|
"unpin_timeout": "3h0m0s"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pin_tracker": {
|
||||||
|
"maptracker": {
|
||||||
|
"max_pin_queue_size": 50000,
|
||||||
|
"concurrent_pins": 10
|
||||||
|
},
|
||||||
|
"stateless": {
|
||||||
|
"max_pin_queue_size": 50000,
|
||||||
|
"concurrent_pins": 10
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"monitor": {
|
"monitor": {
|
||||||
"monbasic": {
|
"monbasic": {
|
||||||
"check_interval": "15s"
|
"check_interval": "15s"
|
||||||
|
},
|
||||||
|
"pubsubmon": {
|
||||||
|
"check_interval": "15s"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"informer": {
|
"informer": {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user