-
Notifications
You must be signed in to change notification settings - Fork 114
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added the
-cache-limit
option to limit cache sizes.
- Loading branch information
Homme Zwaagstra
committed
Feb 27, 2015
1 parent
e7ad5c8
commit 55ada7d
Showing
6 changed files
with
233 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package main | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
"github.com/geo-data/cesium-terrain-server/handlers" | ||
"strconv" | ||
) | ||
|
||
// Adapted from <https://golang.org/doc/effective_go.html#constants>. | ||
type ByteSize float64 | ||
|
||
const ( | ||
_ = iota // ignore first value by assigning to blank identifier | ||
KB ByteSize = 1 << (10 * iota) | ||
MB | ||
GB | ||
TB | ||
) | ||
|
||
func (b ByteSize) String() string { | ||
switch { | ||
case b >= TB: | ||
return fmt.Sprintf("%.2fTB", b/TB) | ||
case b >= GB: | ||
return fmt.Sprintf("%.2fGB", b/GB) | ||
case b >= MB: | ||
return fmt.Sprintf("%.2fMB", b/MB) | ||
case b >= KB: | ||
return fmt.Sprintf("%.2fkB", b/KB) | ||
} | ||
return fmt.Sprintf("%.2fB", b) | ||
} | ||
|
||
func ParseByteSize(size string) (bytes ByteSize, err error) { | ||
defer func() { | ||
if bytes < 0 { | ||
err = errors.New("size cannot be negative") | ||
} | ||
}() | ||
|
||
val, err := strconv.ParseFloat(size, 64) | ||
if err == nil { | ||
bytes = ByteSize(val) | ||
return | ||
} | ||
|
||
if len(size) < 3 { | ||
err = errors.New("the size must be specified as a suffix e.g 5MB") | ||
return | ||
} | ||
|
||
val, err = strconv.ParseFloat(size[:len(size)-2], 64) | ||
if err != nil { | ||
return | ||
} | ||
bytes = ByteSize(val) | ||
|
||
suffix := size[len(size)-2:] | ||
switch suffix { | ||
case "TB": | ||
bytes *= TB | ||
case "GB": | ||
bytes *= GB | ||
case "MB": | ||
bytes *= MB | ||
case "KB": | ||
bytes *= KB | ||
default: | ||
err = errors.New("bad size suffix: " + suffix) | ||
} | ||
return | ||
} | ||
|
||
type LimitOpt struct { | ||
Value handlers.Bytes | ||
} | ||
|
||
func NewLimitOpt() *LimitOpt { | ||
return &LimitOpt{} | ||
} | ||
|
||
func (this *LimitOpt) String() string { | ||
return ByteSize(this.Value).String() | ||
} | ||
|
||
func (this *LimitOpt) Set(size string) error { | ||
byteSize, err := ParseByteSize(size) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
this.Value = handlers.Bytes(byteSize) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
package main | ||
|
||
import ( | ||
"errors" | ||
"github.com/geo-data/cesium-terrain-server/log" | ||
) | ||
|
||
type LogOpt struct { | ||
Priority log.Priority | ||
} | ||
|
||
func NewLogOpt() *LogOpt { | ||
return &LogOpt{ | ||
Priority: log.LOG_NOTICE, | ||
} | ||
} | ||
|
||
func (this *LogOpt) String() string { | ||
switch this.Priority { | ||
case log.LOG_CRIT: | ||
return "crit" | ||
case log.LOG_ERR: | ||
return "err" | ||
case log.LOG_NOTICE: | ||
return "notice" | ||
default: | ||
return "debug" | ||
} | ||
} | ||
|
||
func (this *LogOpt) Set(level string) error { | ||
switch level { | ||
case "crit": | ||
this.Priority = log.LOG_CRIT | ||
case "err": | ||
this.Priority = log.LOG_ERR | ||
case "notice": | ||
this.Priority = log.LOG_NOTICE | ||
case "debug": | ||
this.Priority = log.LOG_DEBUG | ||
default: | ||
return errors.New("choose one of crit, err, notice, debug") | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package handlers | ||
|
||
import ( | ||
"net/http" | ||
) | ||
|
||
// ResponseLimiter is an implementation of ResponseLimiter that wraps a | ||
// http.ResponseWriter and limits how much is written to it. If an attempt is | ||
// made to write more bytes than the limit it silently fails. | ||
type LimitResponse struct { | ||
Writer http.ResponseWriter | ||
Limit Bytes // the maximum number of bytes that can be written to Writer | ||
written Bytes // the number of bytes already sent to Writer | ||
exceeded bool // has the limit been exceeded? | ||
} | ||
|
||
// NewRecorder returns an initialized LimitResponse. This implements the | ||
// LimiterFactory function type. | ||
func NewLimit(writer http.ResponseWriter, limit Bytes) ResponseLimiter { | ||
return &LimitResponse{ | ||
Writer: writer, | ||
Limit: limit, | ||
} | ||
} | ||
|
||
func (this *LimitResponse) LimitExceeded() bool { | ||
return this.exceeded | ||
} | ||
|
||
// Header returns the response headers. | ||
func (this *LimitResponse) Header() http.Header { | ||
return this.Writer.Header() | ||
} | ||
|
||
// Write always succeeds and writes to this.Body, if not nil. | ||
func (this *LimitResponse) Write(buf []byte) (bytes int, err error) { | ||
if this.exceeded { | ||
return | ||
} | ||
|
||
if (Bytes(len(buf)) + this.written) > this.Limit { | ||
this.exceeded = true | ||
return | ||
} | ||
|
||
bytes, err = this.Writer.Write(buf) | ||
this.written += Bytes(bytes) | ||
return | ||
} | ||
|
||
// WriteHeader sets this.Code. | ||
func (this *LimitResponse) WriteHeader(code int) { | ||
this.Writer.WriteHeader(code) | ||
} |