[archiver][server] Move index.*
handling out of server
and into archiver
This commit is contained in:
parent
5e5830bad3
commit
d70f8e39ac
5 changed files with 82 additions and 53 deletions
|
@ -37,7 +37,7 @@ type context struct {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func archiveFile (_context *context, _pathResolved string, _pathInArchive string, _name string, _stat os.FileInfo) (error) {
|
func archiveFile (_context *context, _pathResolved string, _pathInArchive string, _name string) (error) {
|
||||||
|
|
||||||
var _file *os.File
|
var _file *os.File
|
||||||
if _file_0, _error := os.Open (_pathResolved); _error == nil {
|
if _file_0, _error := os.Open (_pathResolved); _error == nil {
|
||||||
|
@ -100,7 +100,8 @@ func archiveFolder (_context *context, _pathResolved string, _pathInArchive stri
|
||||||
}
|
}
|
||||||
|
|
||||||
type Folder struct {
|
type Folder struct {
|
||||||
Entries []Entry `json:"entries"`
|
Entries []Entry `json:"entries",omitempty`
|
||||||
|
Indices []string `json:"indices",omitempty`
|
||||||
}
|
}
|
||||||
|
|
||||||
_entries := make ([]Entry, 0, len (_names))
|
_entries := make ([]Entry, 0, len (_names))
|
||||||
|
@ -120,12 +121,42 @@ func archiveFolder (_context *context, _pathResolved string, _pathInArchive stri
|
||||||
_entries = append (_entries, _entry)
|
_entries = append (_entries, _entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_indexNames := make ([]string, 0, 4)
|
||||||
|
var _indexNameFirst string
|
||||||
|
for _, _indexName := range IndexNames {
|
||||||
|
_indexNameFound := sort.SearchStrings (_names, _indexName)
|
||||||
|
if _indexNameFound == len (_names) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _names[_indexNameFound] != _indexName {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
_stat := _stats[_indexName]
|
||||||
|
_statMode := _stat.Mode ()
|
||||||
|
if ! _statMode.IsRegular () {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _indexNameFirst == "" {
|
||||||
|
_indexNameFirst = _indexName
|
||||||
|
}
|
||||||
|
_indexNames = append (_indexNames, _indexName)
|
||||||
|
}
|
||||||
|
if _indexNameFirst != "" {
|
||||||
|
_indexPathResolved := filepath.Join (_pathResolved, _indexNameFirst)
|
||||||
|
_indexPathInArchive := _pathInArchive + "/"
|
||||||
|
if _pathInArchive == "/" {
|
||||||
|
_indexPathInArchive = "/"
|
||||||
|
}
|
||||||
|
archiveFile (_context, _indexPathResolved, _indexPathInArchive, _indexNameFirst)
|
||||||
|
}
|
||||||
|
|
||||||
_folder := Folder {
|
_folder := Folder {
|
||||||
Entries : _entries,
|
Entries : _entries,
|
||||||
|
Indices : _indexNames,
|
||||||
}
|
}
|
||||||
|
|
||||||
if _data, _error := json.Marshal (&_folder); _error == nil {
|
if _data, _error := json.Marshal (&_folder); _error == nil {
|
||||||
if _, _, _error := archiveData (_context, NamespaceFoldersEntries, _pathInArchive, "", _data, MimeTypeJson); _error != nil {
|
if _, _, _error := archiveData (_context, NamespaceFoldersContent, _pathInArchive, "", _data, MimeTypeJson); _error != nil {
|
||||||
return _error
|
return _error
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -202,8 +233,10 @@ func archiveData (_context *context, _namespace string, _pathInArchive string, _
|
||||||
_context.storedData[_fingerprint] = true
|
_context.storedData[_fingerprint] = true
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
if _context.debug {
|
||||||
log.Printf ("[ ] == %s", _fingerprint)
|
log.Printf ("[ ] == %s", _fingerprint)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if _error := archiveDataReference (_context, _namespace, _pathInArchive, _fingerprint); _error != nil {
|
if _error := archiveDataReference (_context, _namespace, _pathInArchive, _fingerprint); _error != nil {
|
||||||
return "", "", _error
|
return "", "", _error
|
||||||
|
@ -231,7 +264,7 @@ func archiveDataReference (_context *context, _namespace string, _pathInArchive
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func walkPath (_context *context, _path string, _prefix string, _name string, _recursed map[string]uint) (error) {
|
func walkPath (_context *context, _path string, _prefix string, _name string, _recursed map[string]uint) (os.FileInfo, error) {
|
||||||
|
|
||||||
if _recursed == nil {
|
if _recursed == nil {
|
||||||
_recursed = make (map[string]uint, 128)
|
_recursed = make (map[string]uint, 128)
|
||||||
|
@ -243,7 +276,7 @@ func walkPath (_context *context, _path string, _prefix string, _name string, _r
|
||||||
if _stat_0, _error := os.Lstat (_path); _error == nil {
|
if _stat_0, _error := os.Lstat (_path); _error == nil {
|
||||||
_stat = _stat_0
|
_stat = _stat_0
|
||||||
} else {
|
} else {
|
||||||
return _error
|
return nil, _error
|
||||||
}
|
}
|
||||||
|
|
||||||
_isSymlink := false
|
_isSymlink := false
|
||||||
|
@ -252,7 +285,7 @@ func walkPath (_context *context, _path string, _prefix string, _name string, _r
|
||||||
if _stat_0, _error := os.Stat (_path); _error == nil {
|
if _stat_0, _error := os.Stat (_path); _error == nil {
|
||||||
_stat = _stat_0
|
_stat = _stat_0
|
||||||
} else {
|
} else {
|
||||||
return _error
|
return nil, _error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +294,7 @@ func walkPath (_context *context, _path string, _prefix string, _name string, _r
|
||||||
if _resolved, _error := filepath.EvalSymlinks (_path); _error == nil {
|
if _resolved, _error := filepath.EvalSymlinks (_path); _error == nil {
|
||||||
_pathResolved = _resolved
|
_pathResolved = _resolved
|
||||||
} else {
|
} else {
|
||||||
return _error
|
return nil, _error
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_pathResolved = _path
|
_pathResolved = _path
|
||||||
|
@ -276,14 +309,14 @@ func walkPath (_context *context, _path string, _prefix string, _name string, _r
|
||||||
if _context.debug {
|
if _context.debug {
|
||||||
log.Printf ("[ ] ## %s\n", _pathInArchive)
|
log.Printf ("[ ] ## %s\n", _pathInArchive)
|
||||||
}
|
}
|
||||||
return archiveFile (_context, _pathResolved, _pathInArchive, _name, _stat)
|
return _stat, archiveFile (_context, _pathResolved, _pathInArchive, _name)
|
||||||
|
|
||||||
} else if _stat.Mode () .IsDir () {
|
} else if _stat.Mode () .IsDir () {
|
||||||
|
|
||||||
_wasRecursed, _ := _recursed[_pathResolved]
|
_wasRecursed, _ := _recursed[_pathResolved]
|
||||||
if _wasRecursed > 0 {
|
if _wasRecursed > 0 {
|
||||||
log.Printf ("[ww] [2e1744c9] detected directory loop for `%s` resolving to `%s`; ignoring!\n", _path, _pathResolved)
|
log.Printf ("[ww] [2e1744c9] detected directory loop for `%s` resolving to `%s`; ignoring!\n", _path, _pathResolved)
|
||||||
return nil
|
return _stat, nil
|
||||||
}
|
}
|
||||||
_recursed[_pathResolved] = _wasRecursed + 1
|
_recursed[_pathResolved] = _wasRecursed + 1
|
||||||
|
|
||||||
|
@ -303,15 +336,16 @@ func walkPath (_context *context, _path string, _prefix string, _name string, _r
|
||||||
for _, _stat := range _buffer {
|
for _, _stat := range _buffer {
|
||||||
_name := _stat.Name ()
|
_name := _stat.Name ()
|
||||||
_names = append (_names, _name)
|
_names = append (_names, _name)
|
||||||
|
if _stat, _error := walkPath (_context, filepath.Join (_path, _name), _prefix, _name, _recursed); _error == nil {
|
||||||
_stats[_name] = _stat
|
_stats[_name] = _stat
|
||||||
if _error := walkPath (_context, filepath.Join (_path, _name), _prefix, _name, _recursed); _error != nil {
|
} else {
|
||||||
return _error
|
return nil, _error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case io.EOF :
|
case io.EOF :
|
||||||
break _loop
|
break _loop
|
||||||
default :
|
default :
|
||||||
return _error
|
return nil, _error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -326,14 +360,14 @@ func walkPath (_context *context, _path string, _prefix string, _name string, _r
|
||||||
log.Printf ("[ ] <> %s\n", _pathInArchive)
|
log.Printf ("[ ] <> %s\n", _pathInArchive)
|
||||||
}
|
}
|
||||||
if _error := archiveFolder (_context, _pathResolved, _pathInArchive, _names, _stats); _error != nil {
|
if _error := archiveFolder (_context, _pathResolved, _pathInArchive, _names, _stats); _error != nil {
|
||||||
return _error
|
return nil, _error
|
||||||
}
|
}
|
||||||
|
|
||||||
_recursed[_pathResolved] = _wasRecursed
|
_recursed[_pathResolved] = _wasRecursed
|
||||||
return nil
|
return _stat, nil
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return fmt.Errorf ("[d9b836d7] unexpected file type for `%s`: `%s`!", _path, _stat.Mode ())
|
return nil, fmt.Errorf ("[d9b836d7] unexpected file type for `%s`: `%s`!", _path, _stat.Mode ())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,7 +426,7 @@ func main_0 () (error) {
|
||||||
debug : _debug,
|
debug : _debug,
|
||||||
}
|
}
|
||||||
|
|
||||||
if _error := walkPath (_context, _sourcesFolder, "/", "", nil); _error != nil {
|
if _, _error := walkPath (_context, _sourcesFolder, "/", "", nil); _error != nil {
|
||||||
AbortError (_error, "[b6a19ef4] failed walking folder!")
|
AbortError (_error, "[b6a19ef4] failed walking folder!")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,50 +88,21 @@ func (_server *server) HandleHTTP (_context *fasthttp.RequestCtx) () {
|
||||||
|
|
||||||
var _fingerprint []byte
|
var _fingerprint []byte
|
||||||
{
|
{
|
||||||
_path_0 := _path
|
_found : for _, _namespace := range []string {NamespaceFilesContent, NamespaceFoldersContent} {
|
||||||
if _pathHasSlash {
|
|
||||||
_path_0 = _path[: _pathLen - 1]
|
|
||||||
}
|
|
||||||
_found : for _, _namespace := range []string {NamespaceFilesContent, NamespaceFoldersContent, NamespaceFoldersEntries} {
|
|
||||||
_key := _keyBuffer[:0]
|
_key := _keyBuffer[:0]
|
||||||
_key = append (_key, _namespace ...)
|
_key = append (_key, _namespace ...)
|
||||||
_key = append (_key, ':')
|
_key = append (_key, ':')
|
||||||
_key = append (_key, _path_0 ...)
|
_key = append (_key, _path ...)
|
||||||
if _value, _error := _server.cdbReader.GetWithCdbHash (_key); _error == nil {
|
if _value, _error := _server.cdbReader.GetWithCdbHash (_key); _error == nil {
|
||||||
if _value != nil {
|
if _value != nil {
|
||||||
_fingerprint = _value
|
_fingerprint = _value
|
||||||
if (_namespace == NamespaceFoldersContent) || (_namespace == NamespaceFoldersEntries) {
|
if (_namespace == NamespaceFoldersContent) {
|
||||||
if !_pathIsRoot && !_pathHasSlash {
|
if !_pathIsRoot && !_pathHasSlash {
|
||||||
_path = append (_path, '/')
|
_path = append (_path, '/')
|
||||||
_server.ServeRedirect (_context, http.StatusTemporaryRedirect, _path)
|
_server.ServeRedirect (_context, http.StatusTemporaryRedirect, _path)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if _namespace == NamespaceFoldersEntries {
|
|
||||||
for _, _indexName := range []string {
|
|
||||||
"index.html", "index.htm",
|
|
||||||
"index.xhtml", "index.xht",
|
|
||||||
"index.txt",
|
|
||||||
"index.json",
|
|
||||||
"index.xml",
|
|
||||||
} {
|
|
||||||
_key := _keyBuffer[:0]
|
|
||||||
_key = append (_key, NamespaceFilesContent ...)
|
|
||||||
_key = append (_key, ':')
|
|
||||||
if !_pathIsRoot {
|
|
||||||
_key = append (_key, _path_0 ...)
|
|
||||||
}
|
|
||||||
_key = append (_key, '/')
|
|
||||||
_key = append (_key, _indexName ...)
|
|
||||||
if _value, _error := _server.cdbReader.GetWithCdbHash (_key); _error == nil {
|
|
||||||
_fingerprint = _value
|
|
||||||
break _found
|
|
||||||
} else {
|
|
||||||
_server.ServeError (_context, http.StatusInternalServerError, _error)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break _found
|
break _found
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
13
sources/lib/archiver/index.go
Normal file
13
sources/lib/archiver/index.go
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
|
||||||
|
package archiver
|
||||||
|
|
||||||
|
|
||||||
|
var IndexNames []string = []string {
|
||||||
|
"index.html", "index.htm",
|
||||||
|
"index.xhtml", "index.xht",
|
||||||
|
"index.txt",
|
||||||
|
"index.json",
|
||||||
|
"index.xml",
|
||||||
|
}
|
||||||
|
|
|
@ -6,15 +6,27 @@ package common
|
||||||
import "bytes"
|
import "bytes"
|
||||||
import "fmt"
|
import "fmt"
|
||||||
import "regexp"
|
import "regexp"
|
||||||
|
import "sort"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func MetadataEncode (_metadata map[string]string) ([]byte, error) {
|
func MetadataEncode (_metadata map[string]string) ([]byte, error) {
|
||||||
|
|
||||||
|
_metadataArray := make ([][2]string, 0, len (_metadata))
|
||||||
|
for _key, _value := range _metadata {
|
||||||
|
_metadataArray = append (_metadataArray, [2]string {_key, _value})
|
||||||
|
}
|
||||||
|
sort.Slice (_metadataArray,
|
||||||
|
func (i int, j int) (bool) {
|
||||||
|
return _metadataArray[i][0] < _metadataArray[j][0]
|
||||||
|
})
|
||||||
|
|
||||||
_buffer := & bytes.Buffer {}
|
_buffer := & bytes.Buffer {}
|
||||||
|
|
||||||
for _key, _value := range _metadata {
|
for _, _metadata := range _metadataArray {
|
||||||
|
_key := _metadata[0]
|
||||||
|
_value := _metadata[1]
|
||||||
if ! metadataKeyRegex.MatchString (_key) {
|
if ! metadataKeyRegex.MatchString (_key) {
|
||||||
return nil, fmt.Errorf ("[2f761e02] invalid metadata key: `%s`", _key)
|
return nil, fmt.Errorf ("[2f761e02] invalid metadata key: `%s`", _key)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,7 @@ package common
|
||||||
|
|
||||||
|
|
||||||
const NamespaceFilesContent = "files:content"
|
const NamespaceFilesContent = "files:content"
|
||||||
const NamespaceFoldersContent = "folders:content"
|
const NamespaceFoldersContent = "folders:entries"
|
||||||
const NamespaceFoldersEntries = "folders:entries"
|
|
||||||
|
|
||||||
const NamespaceDataContent = "data:content"
|
const NamespaceDataContent = "data:content"
|
||||||
const NamespaceDataMetadata = "data:metadata"
|
const NamespaceDataMetadata = "data:metadata"
|
||||||
|
|
Loading…
Reference in a new issue