diff --git a/OrbitalBeat.go b/OrbitalBeat.go index fe3f6e8..0f2651f 100644 --- a/OrbitalBeat.go +++ b/OrbitalBeat.go @@ -12,6 +12,7 @@ import ( "database/sql" "encoding/base32" "encoding/binary" + "encoding/hex" "encoding/pem" "flag" "fmt" @@ -85,8 +86,6 @@ func isSNIAllowed(sni string) bool { } func getFirstValidContentEntry(entries *[]ContentEntry) *ContentEntry { - log.Printf("Entered getFirstValidContentEntry") - defer log.Printf("Exited getFirstValidContentEntry") for _, entry := range *entries { stat, err := os.Stat(entry.Path) if err == nil /*&& uint64(stat.Size()) == entry.Size*/ { //TODO: update Size if not found @@ -99,9 +98,7 @@ func getFirstValidContentEntry(entries *[]ContentEntry) *ContentEntry { return nil } -func handleQueryRequest(w http.ResponseWriter, r *http.Request, identifier cid.Cid) { - log.Printf("Entered handleQueryRequest") - defer log.Printf("Exited handleQueryRequest") +func handleQueryRequest(w http.ResponseWriter, r *http.Request, identifier cid.Cid, extraArguments []string) { var cacheEntry = tryGetCacheEntryForIdentifier(identifier) @@ -116,6 +113,28 @@ func handleQueryRequest(w http.ResponseWriter, r *http.Request, identifier cid.C } if cacheEntry == nil { + var origin string + + if r.Header.Get("Referer") != "" { + origin = r.Header.Get("Referer") + } else if r.Header.Get("Origin") != "" { + origin = r.Header.Get("Origin") + } + + //Try to redirect back to origin + if len(extraArguments) > 0 && origin != "" { + mh, _ := multihash.Decode(identifier.Hash()) + var kind string + if mh.Code == multihash.SHA2_256 { + kind = "sha256" + } else if mh.Code == multihash.MD5 { + kind = "md5" + } + if kind != "" { + http.Redirect(w, r, fmt.Sprintf("%s/%s/%s/%s", origin, kind, hex.EncodeToString(mh.Digest), strings.Join(extraArguments, "/")), http.StatusFound) + return + } + } w.WriteHeader(http.StatusNotFound) return } @@ -146,6 +165,7 @@ func isASCII(s string) bool { func setOtherHeaders(w http.ResponseWriter) { w.Header().Set("Server", "OrbitalBeat") w.Header().Set("Vary", "Content-Encoding") + w.Header().Set("X-Content-Type-Options", "nosniff") } func setCORSHeaders(w http.ResponseWriter) { w.Header().Set("Access-Control-Allow-Credentials", "true") @@ -154,11 +174,14 @@ func setCORSHeaders(w http.ResponseWriter) { w.Header().Set("Access-Control-Allow-Headers", "DNT,ETag,Origin,Accept,Accept-Language,X-Requested-With,Range") w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Expose-Headers", "*") + + //CORP, COEP, COOP + w.Header().Set("Cross-Origin-Embedder-Policy", "require-corp") + w.Header().Set("Cross-Origin-Resource-Policy", "cross-origin") + w.Header().Set("Cross-Origin-Opener-Policy", "unsafe-none") } func getCacheEntryForContentEntry(entry *ContentEntry) *ContentCacheEntry { - log.Printf("Entered getCacheEntryForContentEntry") - defer log.Printf("Exited getCacheEntryForContentEntry") cacheEntry := tryGetCacheEntryForIdentifier(entry.Identifier) @@ -199,8 +222,6 @@ func getCacheEntryForContentEntry(entry *ContentEntry) *ContentCacheEntry { } func tryGetCacheEntryForIdentifier(identifier cid.Cid) *ContentCacheEntry { - log.Printf("Entered tryGetCacheEntryForIdentifier") - defer log.Printf("Exited tryGetCacheEntryForIdentifier") objectCacheMutex.RLock() defer objectCacheMutex.RUnlock() @@ -236,39 +257,34 @@ func handle(w http.ResponseWriter, r *http.Request) { setCORSHeaders(w) pathElements := strings.Split(r.URL.Path, "/") if len(pathElements) < 2 { - log.Printf("1") w.WriteHeader(http.StatusBadRequest) return } messageBytes, err := base32Encoding.DecodeString(pathElements[1]) if err != nil { - log.Printf("2") w.WriteHeader(http.StatusBadRequest) return } message := DecodeContentMessage(messageBytes) if message == nil { - log.Printf("3") w.WriteHeader(http.StatusBadRequest) return } if !IsTrustedPublicKey(message.PublicKey) { - log.Printf("4") w.WriteHeader(http.StatusForbidden) return } if !message.verify() { - log.Printf("5") w.WriteHeader(http.StatusForbidden) return } log.Printf("Valid %s %s", r.URL.Path, message.Identifier.String()) - handleQueryRequest(w, r, message.Identifier) + handleQueryRequest(w, r, message.Identifier, pathElements[2:]) } else if r.Method == "OPTIONS" { setOtherHeaders(w) setCORSHeaders(w) @@ -473,8 +489,6 @@ func handleQuery(rows *sql.Rows, err error) []ContentEntry { } func getEntriesForCID(identifier cid.Cid) []ContentEntry { - log.Printf("Entered getEntriesForCID") - defer log.Printf("Exited getEntriesForCID") mh, _ := multihash.Decode(identifier.Hash()) if mh.Code == multihash.SHA2_256 { @@ -525,6 +539,7 @@ func createSelfSignedCertificate() ([]byte, []byte) { } func main() { + //TODO: OCSP certificatePath := flag.String("certificate", "ssl.crt", "Path to SSL certificate file.") keypairPath := flag.String("keypair", "ssl.key", "Path to SSL key file.")