github.com/jincm/wesharechain@v0.0.0-20210122032815-1537409ce26a/chain/swarm/storage/mock/explorer/headers_test.go (about) 1 // Copyright 2019 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package explorer 18 19 import ( 20 "fmt" 21 "net/http" 22 "net/http/httptest" 23 "testing" 24 25 "github.com/ethereum/go-ethereum/swarm/storage/mock/mem" 26 ) 27 28 // TestHandler_CORSOrigin validates that the correct Access-Control-Allow-Origin 29 // header is served with various allowed origin settings. 30 func TestHandler_CORSOrigin(t *testing.T) { 31 notAllowedOrigin := "http://not-allowed-origin.com/" 32 33 for _, tc := range []struct { 34 name string 35 origins []string 36 }{ 37 { 38 name: "no origin", 39 origins: nil, 40 }, 41 { 42 name: "single origin", 43 origins: []string{"http://localhost/"}, 44 }, 45 { 46 name: "multiple origins", 47 origins: []string{"http://localhost/", "http://ethereum.org/"}, 48 }, 49 } { 50 t.Run(tc.name, func(t *testing.T) { 51 handler := NewHandler(mem.NewGlobalStore(), tc.origins) 52 53 origins := tc.origins 54 if origins == nil { 55 // handle the "no origin" test case 56 origins = []string{""} 57 } 58 59 for _, origin := range origins { 60 t.Run(fmt.Sprintf("get %q", origin), newTestCORSOrigin(handler, origin, origin)) 61 t.Run(fmt.Sprintf("preflight %q", origin), newTestCORSPreflight(handler, origin, origin)) 62 } 63 64 t.Run(fmt.Sprintf("get %q", notAllowedOrigin), newTestCORSOrigin(handler, notAllowedOrigin, "")) 65 t.Run(fmt.Sprintf("preflight %q", notAllowedOrigin), newTestCORSPreflight(handler, notAllowedOrigin, "")) 66 }) 67 } 68 69 t.Run("wildcard", func(t *testing.T) { 70 handler := NewHandler(mem.NewGlobalStore(), []string{"*"}) 71 72 for _, origin := range []string{ 73 "http://example.com/", 74 "http://ethereum.org", 75 "http://localhost", 76 } { 77 t.Run(fmt.Sprintf("get %q", origin), newTestCORSOrigin(handler, origin, origin)) 78 t.Run(fmt.Sprintf("preflight %q", origin), newTestCORSPreflight(handler, origin, origin)) 79 } 80 }) 81 } 82 83 // newTestCORSOrigin returns a test function that validates if wantOrigin CORS header is 84 // served by the handler for a GET request. 85 func newTestCORSOrigin(handler http.Handler, origin, wantOrigin string) func(t *testing.T) { 86 return func(t *testing.T) { 87 req, err := http.NewRequest(http.MethodGet, "/", nil) 88 if err != nil { 89 t.Fatal(err) 90 } 91 req.Header.Set("Origin", origin) 92 93 w := httptest.NewRecorder() 94 handler.ServeHTTP(w, req) 95 resp := w.Result() 96 97 header := resp.Header.Get("Access-Control-Allow-Origin") 98 if header != wantOrigin { 99 t.Errorf("got Access-Control-Allow-Origin header %q, want %q", header, wantOrigin) 100 } 101 } 102 } 103 104 // newTestCORSPreflight returns a test function that validates if wantOrigin CORS header is 105 // served by the handler for an OPTIONS CORS preflight request. 106 func newTestCORSPreflight(handler http.Handler, origin, wantOrigin string) func(t *testing.T) { 107 return func(t *testing.T) { 108 req, err := http.NewRequest(http.MethodOptions, "/", nil) 109 if err != nil { 110 t.Fatal(err) 111 } 112 req.Header.Set("Origin", origin) 113 req.Header.Set("Access-Control-Request-Method", "GET") 114 115 w := httptest.NewRecorder() 116 handler.ServeHTTP(w, req) 117 resp := w.Result() 118 119 header := resp.Header.Get("Access-Control-Allow-Origin") 120 if header != wantOrigin { 121 t.Errorf("got Access-Control-Allow-Origin header %q, want %q", header, wantOrigin) 122 } 123 } 124 } 125 126 // TestHandler_noCacheHeaders validates that no cache headers are server. 127 func TestHandler_noCacheHeaders(t *testing.T) { 128 handler := NewHandler(mem.NewGlobalStore(), nil) 129 130 for _, tc := range []struct { 131 url string 132 }{ 133 { 134 url: "/", 135 }, 136 { 137 url: "/api/nodes", 138 }, 139 { 140 url: "/api/keys", 141 }, 142 } { 143 req, err := http.NewRequest(http.MethodGet, tc.url, nil) 144 if err != nil { 145 t.Fatal(err) 146 } 147 148 w := httptest.NewRecorder() 149 handler.ServeHTTP(w, req) 150 resp := w.Result() 151 152 for header, want := range map[string]string{ 153 "Cache-Control": "no-cache, no-store, must-revalidate", 154 "Pragma": "no-cache", 155 "Expires": "0", 156 } { 157 got := resp.Header.Get(header) 158 if got != want { 159 t.Errorf("got %q header %q for url %q, want %q", header, tc.url, got, want) 160 } 161 } 162 } 163 }