Add redirection support on failure
This commit is contained in:
parent
59101110a4
commit
85fddd144a
|
@ -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.")
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue