Add redirection support on failure

This commit is contained in:
DataHoarder 2022-01-16 13:12:26 +01:00
parent 59101110a4
commit 85fddd144a

View file

@ -12,6 +12,7 @@ import (
"database/sql" "database/sql"
"encoding/base32" "encoding/base32"
"encoding/binary" "encoding/binary"
"encoding/hex"
"encoding/pem" "encoding/pem"
"flag" "flag"
"fmt" "fmt"
@ -85,8 +86,6 @@ func isSNIAllowed(sni string) bool {
} }
func getFirstValidContentEntry(entries *[]ContentEntry) *ContentEntry { func getFirstValidContentEntry(entries *[]ContentEntry) *ContentEntry {
log.Printf("Entered getFirstValidContentEntry")
defer log.Printf("Exited getFirstValidContentEntry")
for _, entry := range *entries { for _, entry := range *entries {
stat, err := os.Stat(entry.Path) stat, err := os.Stat(entry.Path)
if err == nil /*&& uint64(stat.Size()) == entry.Size*/ { //TODO: update Size if not found 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 return nil
} }
func handleQueryRequest(w http.ResponseWriter, r *http.Request, identifier cid.Cid) { func handleQueryRequest(w http.ResponseWriter, r *http.Request, identifier cid.Cid, extraArguments []string) {
log.Printf("Entered handleQueryRequest")
defer log.Printf("Exited handleQueryRequest")
var cacheEntry = tryGetCacheEntryForIdentifier(identifier) var cacheEntry = tryGetCacheEntryForIdentifier(identifier)
@ -116,6 +113,28 @@ func handleQueryRequest(w http.ResponseWriter, r *http.Request, identifier cid.C
} }
if cacheEntry == nil { 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) w.WriteHeader(http.StatusNotFound)
return return
} }
@ -146,6 +165,7 @@ func isASCII(s string) bool {
func setOtherHeaders(w http.ResponseWriter) { func setOtherHeaders(w http.ResponseWriter) {
w.Header().Set("Server", "OrbitalBeat") w.Header().Set("Server", "OrbitalBeat")
w.Header().Set("Vary", "Content-Encoding") w.Header().Set("Vary", "Content-Encoding")
w.Header().Set("X-Content-Type-Options", "nosniff")
} }
func setCORSHeaders(w http.ResponseWriter) { func setCORSHeaders(w http.ResponseWriter) {
w.Header().Set("Access-Control-Allow-Credentials", "true") 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-Headers", "DNT,ETag,Origin,Accept,Accept-Language,X-Requested-With,Range")
w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Expose-Headers", "*") 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 { func getCacheEntryForContentEntry(entry *ContentEntry) *ContentCacheEntry {
log.Printf("Entered getCacheEntryForContentEntry")
defer log.Printf("Exited getCacheEntryForContentEntry")
cacheEntry := tryGetCacheEntryForIdentifier(entry.Identifier) cacheEntry := tryGetCacheEntryForIdentifier(entry.Identifier)
@ -199,8 +222,6 @@ func getCacheEntryForContentEntry(entry *ContentEntry) *ContentCacheEntry {
} }
func tryGetCacheEntryForIdentifier(identifier cid.Cid) *ContentCacheEntry { func tryGetCacheEntryForIdentifier(identifier cid.Cid) *ContentCacheEntry {
log.Printf("Entered tryGetCacheEntryForIdentifier")
defer log.Printf("Exited tryGetCacheEntryForIdentifier")
objectCacheMutex.RLock() objectCacheMutex.RLock()
defer objectCacheMutex.RUnlock() defer objectCacheMutex.RUnlock()
@ -236,39 +257,34 @@ func handle(w http.ResponseWriter, r *http.Request) {
setCORSHeaders(w) setCORSHeaders(w)
pathElements := strings.Split(r.URL.Path, "/") pathElements := strings.Split(r.URL.Path, "/")
if len(pathElements) < 2 { if len(pathElements) < 2 {
log.Printf("1")
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
messageBytes, err := base32Encoding.DecodeString(pathElements[1]) messageBytes, err := base32Encoding.DecodeString(pathElements[1])
if err != nil { if err != nil {
log.Printf("2")
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
message := DecodeContentMessage(messageBytes) message := DecodeContentMessage(messageBytes)
if message == nil { if message == nil {
log.Printf("3")
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
return return
} }
if !IsTrustedPublicKey(message.PublicKey) { if !IsTrustedPublicKey(message.PublicKey) {
log.Printf("4")
w.WriteHeader(http.StatusForbidden) w.WriteHeader(http.StatusForbidden)
return return
} }
if !message.verify() { if !message.verify() {
log.Printf("5")
w.WriteHeader(http.StatusForbidden) w.WriteHeader(http.StatusForbidden)
return return
} }
log.Printf("Valid %s %s", r.URL.Path, message.Identifier.String()) 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" { } else if r.Method == "OPTIONS" {
setOtherHeaders(w) setOtherHeaders(w)
setCORSHeaders(w) setCORSHeaders(w)
@ -473,8 +489,6 @@ func handleQuery(rows *sql.Rows, err error) []ContentEntry {
} }
func getEntriesForCID(identifier cid.Cid) []ContentEntry { func getEntriesForCID(identifier cid.Cid) []ContentEntry {
log.Printf("Entered getEntriesForCID")
defer log.Printf("Exited getEntriesForCID")
mh, _ := multihash.Decode(identifier.Hash()) mh, _ := multihash.Decode(identifier.Hash())
if mh.Code == multihash.SHA2_256 { if mh.Code == multihash.SHA2_256 {
@ -525,6 +539,7 @@ func createSelfSignedCertificate() ([]byte, []byte) {
} }
func main() { func main() {
//TODO: OCSP
certificatePath := flag.String("certificate", "ssl.crt", "Path to SSL certificate file.") certificatePath := flag.String("certificate", "ssl.crt", "Path to SSL certificate file.")
keypairPath := flag.String("keypair", "ssl.key", "Path to SSL key file.") keypairPath := flag.String("keypair", "ssl.key", "Path to SSL key file.")