add replacement strings support, reuse variables with loops (less allocs)

Signed-off-by: kim (grufwub) <grufwub@gmail.com>
master
kim (grufwub) 4 years ago
parent 13b361f5fd
commit 90b18905ce

@ -67,9 +67,15 @@ func (c *conn) ReadLine() ([]byte, Error) {
// return slice // return slice
b := make([]byte, 0) b := make([]byte, 0)
// Declare variables
var line []byte
var isPrefix bool
var err error
// Read!
for len(b) < connReadMax { for len(b) < connReadMax {
// read the line // read the line
line, isPrefix, err := c.buf.ReadLine() line, isPrefix, err = c.buf.ReadLine()
if err != nil { if err != nil {
return nil, WrapError(ConnReadErr, err) return nil, WrapError(ConnReadErr, err)
} }

@ -65,7 +65,7 @@ func (fs *FileSystemObject) checkCacheFreshness() {
// Check file still exists on disk // Check file still exists on disk
stat, err := os.Stat(path) stat, err := os.Stat(path)
if err != nil { if err != nil {
SystemLog.Error("Failed to stat file in cache: %s\n", path) SystemLog.Error(cacheFileStatErrStr, path)
fs.cache.Remove(path) fs.cache.Remove(path)
return return
} }
@ -107,9 +107,13 @@ func (fs *FileSystemObject) ReadFile(fd *os.File) ([]byte, Error) {
// Read buffer // Read buffer
buf := make([]byte, fileReadBufSize) buf := make([]byte, fileReadBufSize)
// Declare variables
var count int
var err error
// Read through file until null bytes / error // Read through file until null bytes / error
for { for {
count, err := fd.Read(buf) count, err = fd.Read(buf)
if err != nil { if err != nil {
if err == io.EOF { if err == io.EOF {
break break
@ -132,17 +136,24 @@ func (fs *FileSystemObject) ScanFile(fd *os.File, iterator func(string) bool) Er
// Buffered reader // Buffered reader
rdr := bufio.NewReaderSize(fd, fileReadBufSize) rdr := bufio.NewReaderSize(fd, fileReadBufSize)
// Declare variables
var b, line []byte
var err error
var isPrefix, done bool
// Iterate through file! // Iterate through file!
for { for {
// Line buffer // Line buffer
b := make([]byte, 0) b = make([]byte, 0)
// Read until line-end, or file end! // Read until line-end, or file end!
done = false
for { for {
// Read a line // Read a line
line, isPrefix, err := rdr.ReadLine() line, isPrefix, err = rdr.ReadLine()
if err != nil { if err != nil {
if err == io.EOF { if err == io.EOF {
done = true
break break
} }
return WrapError(FileReadErr, err) return WrapError(FileReadErr, err)
@ -158,9 +169,12 @@ func (fs *FileSystemObject) ScanFile(fd *os.File, iterator func(string) bool) Er
} }
// Run scan iterator on this line, break-out if requested // Run scan iterator on this line, break-out if requested
if !iterator(string(b)) { if !iterator(string(b)) || done {
break break
} }
// Empty the slice!
b = nil
} }
return nil return nil
@ -176,10 +190,13 @@ func (fs *FileSystemObject) ScanDirectory(fd *os.File, p *Path, iterator func(os
// Sort by name // Sort by name
sort.Sort(byName(dirList)) sort.Sort(byName(dirList))
// Declare variables
var fp *Path
// Walk through the directory list using supplied iterator function // Walk through the directory list using supplied iterator function
for _, info := range dirList { for _, info := range dirList {
// Make new Path object // Make new Path object
fp := p.JoinPath(info.Name()) fp = p.JoinPath(info.Name())
// Skip restricted files // Skip restricted files
if IsRestrictedPath(fp) || WithinCGIDir(fp) { if IsRestrictedPath(fp) || WithinCGIDir(fp) {
@ -337,7 +354,7 @@ func (fs *FileSystemObject) FetchFile(client *Client, fd *os.File, stat os.FileI
} }
} }
// Defer file unlock, write to client // Defer file read unlock, write to client
defer f.RUnlock() defer f.RUnlock()
return f.WriteToClient(client, p) return f.WriteToClient(client, p)
} }

@ -89,6 +89,7 @@ const (
listeningOnStr = "Listening on %s://%s:%s (%s:%s)" listeningOnStr = "Listening on %s://%s:%s (%s:%s)"
cacheMonitorStartStr = "Starting cache monitor with freq: %s" cacheMonitorStartStr = "Starting cache monitor with freq: %s"
cacheFileStatErrStr = "Failed to stat file in cache: %s"
pathRestrictionsEnabledStr = "Path restrictions enabled" pathRestrictionsEnabledStr = "Path restrictions enabled"
pathRestrictionsDisabledStr = "Path restrictions disabled" pathRestrictionsDisabledStr = "Path restrictions disabled"

@ -12,8 +12,12 @@ type gophermapContents struct {
// WriteToClient renders each cached section of the gophermap, and writes them to the client // WriteToClient renders each cached section of the gophermap, and writes them to the client
func (gc *gophermapContents) WriteToClient(client *core.Client, path *core.Path) core.Error { func (gc *gophermapContents) WriteToClient(client *core.Client, path *core.Path) core.Error {
// Declare variables
var err core.Error
// Render + write the sections!
for _, section := range gc.sections { for _, section := range gc.sections {
err := section.RenderAndWrite(client) err = section.RenderAndWrite(client)
if err != nil { if err != nil {
return err return err
} }

@ -43,6 +43,22 @@ func formatHostPort(host, port string) string {
return host + "\t" + port return host + "\t" + port
} }
// replacePlacementStrs replaces any placement strings found in the line (e.g $hostname, $port)
func replacePlacementStrs(line string) string {
split := strings.Split(line, "\t")
// Either invalid line, or information line without host + port
if len(split) != 4 {
return line
}
// Return recombined (and replaced! string)
return split[0] + "\t" +
split[1] + "\t" +
strings.Replace(split[2], "$hostname", core.Hostname, 1) + "\t" +
strings.Replace(split[3], "$port", core.FwdPort, 1)
}
// buildLine builds a gopher line string // buildLine builds a gopher line string
func buildLine(t ItemType, name, selector, host, port string) []byte { func buildLine(t ItemType, name, selector, host, port string) []byte {
return []byte(string(t) + formatName(name) + formatSelector(selector) + formatHostPort(host, port) + "\r\n") return []byte(string(t) + formatName(name) + formatSelector(selector) + formatHostPort(host, port) + "\r\n")

@ -25,11 +25,11 @@ func readGophermap(fd *os.File, p *core.Path) ([]gophermapSection, core.Error) {
p.Relative(): true, p.Relative(): true,
} }
// Error setting within nested function below // Declare variables
var returnErr core.Error var returnErr core.Error
titleAlready := false
// Perform scan of gophermap FD // Perform scan of gophermap FD
titleAlready := false
scanErr := core.FileSystem.ScanFile( scanErr := core.FileSystem.ScanFile(
fd, fd,
func(line string) bool { func(line string) bool {
@ -120,8 +120,8 @@ func readGophermap(fd *os.File, p *core.Path) ([]gophermapSection, core.Error) {
return false return false
default: default:
// Default is appending to sections slice as TextSection // Default is appending line with replaced strings to sections slice as TextSection
sections = append(sections, &TextSection{[]byte(line + "\r\n")}) sections = append(sections, &TextSection{[]byte(replacePlacementStrs(line) + "\r\n")})
return true return true
} }
}, },

@ -50,6 +50,7 @@ func serve(client *core.Client) {
if err == nil { if err == nil {
stat, osErr := fd2.Stat() stat, osErr := fd2.Stat()
if osErr == nil { if osErr == nil {
core.SystemLog.Info("Returning fetched gophermap")
return fs.FetchFile(client, fd2, stat, gophermap, newFileContents) return fs.FetchFile(client, fd2, stat, gophermap, newFileContents)
} }

Loading…
Cancel
Save