Skip to content
Snippets Groups Projects
Commit 42347087 authored by Will McCutchen's avatar Will McCutchen
Browse files

Simplify configuration

parent d5ff1777
No related branches found
No related tags found
No related merge requests found
......@@ -457,7 +457,7 @@ func (h *HTTPBin) Delay(w http.ResponseWriter, r *http.Request) {
return
}
delay, err := parseBoundedDuration(parts[2], 0, h.options.MaxResponseTime)
delay, err := parseBoundedDuration(parts[2], 0, h.options.MaxDuration)
if err != nil {
http.Error(w, "Invalid duration", http.StatusBadRequest)
return
......@@ -481,7 +481,7 @@ func (h *HTTPBin) Drip(w http.ResponseWriter, r *http.Request) {
userDuration := q.Get("duration")
if userDuration != "" {
duration, err = parseBoundedDuration(userDuration, 0, h.options.MaxResponseTime)
duration, err = parseBoundedDuration(userDuration, 0, h.options.MaxDuration)
if err != nil {
http.Error(w, "Invalid duration", http.StatusBadRequest)
return
......@@ -490,7 +490,7 @@ func (h *HTTPBin) Drip(w http.ResponseWriter, r *http.Request) {
userDelay := q.Get("delay")
if userDelay != "" {
delay, err = parseBoundedDuration(userDelay, 0, h.options.MaxResponseTime)
delay, err = parseBoundedDuration(userDelay, 0, h.options.MaxDuration)
if err != nil {
http.Error(w, "Invalid delay", http.StatusBadRequest)
return
......@@ -500,7 +500,7 @@ func (h *HTTPBin) Drip(w http.ResponseWriter, r *http.Request) {
userNumBytes := q.Get("numbytes")
if userNumBytes != "" {
numbytes, err = strconv.ParseInt(userNumBytes, 10, 64)
if err != nil || numbytes <= 0 || numbytes > h.options.MaxResponseSize {
if err != nil || numbytes <= 0 || numbytes > h.options.MaxMemory {
http.Error(w, "Invalid numbytes", http.StatusBadRequest)
return
}
......@@ -515,7 +515,7 @@ func (h *HTTPBin) Drip(w http.ResponseWriter, r *http.Request) {
}
}
if duration+delay > h.options.MaxResponseTime {
if duration+delay > h.options.MaxDuration {
http.Error(w, "Too much time", http.StatusBadRequest)
return
}
......
......@@ -20,13 +20,11 @@ import (
)
const maxMemory int64 = 1024 * 1024
const maxResponseSize = 1024
const maxResponseTime time.Duration = 1 * time.Second
const maxDuration time.Duration = 1 * time.Second
var app = NewHTTPBin(&Options{
MaxMemory: maxMemory,
MaxResponseSize: maxResponseSize,
MaxResponseTime: maxResponseTime,
var app = NewHTTPBinWithOptions(&Options{
MaxMemory: maxMemory,
MaxDuration: maxDuration,
})
var handler = app.Handler()
......@@ -60,13 +58,6 @@ func assertBodyEquals(t *testing.T, w *httptest.ResponseRecorder, want string) {
}
}
func TestNewHTTPBin__NilOptions(t *testing.T) {
h := NewHTTPBin(nil)
if h.options.MaxMemory != 0 {
t.Fatalf("expected default MaxMemory == 0, got %#v", h.options.MaxMemory)
}
}
func TestIndex(t *testing.T) {
r, _ := http.NewRequest("GET", "/", nil)
w := httptest.NewRecorder()
......@@ -1341,7 +1332,7 @@ func TestDelay(t *testing.T) {
// as are floating point seconds
{"/delay/0", 0},
{"/delay/0.5", 500 * time.Millisecond},
{"/delay/1", maxResponseTime},
{"/delay/1", maxDuration},
}
for _, test := range okTests {
t.Run("ok"+test.url, func(t *testing.T) {
......@@ -1418,7 +1409,7 @@ func TestDrip(t *testing.T) {
{&url.Values{"numbytes": {"1"}}, 0, 1, http.StatusOK},
{&url.Values{"numbytes": {"101"}}, 0, 101, http.StatusOK},
{&url.Values{"numbytes": {fmt.Sprintf("%d", maxResponseSize)}}, 0, maxResponseSize, http.StatusOK},
{&url.Values{"numbytes": {fmt.Sprintf("%d", maxMemory)}}, 0, int(maxMemory), http.StatusOK},
{&url.Values{"code": {"100"}}, 0, 10, 100},
{&url.Values{"code": {"404"}}, 0, 10, 404},
......@@ -1472,7 +1463,7 @@ func TestDrip(t *testing.T) {
{&url.Values{"numbytes": {"0"}}, http.StatusBadRequest},
{&url.Values{"numbytes": {"-1"}}, http.StatusBadRequest},
{&url.Values{"numbytes": {"0xff"}}, http.StatusBadRequest},
{&url.Values{"numbytes": {fmt.Sprintf("%d", maxResponseSize+1)}}, http.StatusBadRequest},
{&url.Values{"numbytes": {fmt.Sprintf("%d", maxMemory+1)}}, http.StatusBadRequest},
{&url.Values{"code": {"foo"}}, http.StatusBadRequest},
{&url.Values{"code": {"-1"}}, http.StatusBadRequest},
......
......@@ -6,6 +6,12 @@ import (
"time"
)
// Default configuration values
const (
DefaultMaxMemory int64 = 1024 * 1024
DefaultMaxDuration = 10 * time.Second
)
const jsonContentType = "application/json; encoding=utf-8"
const htmlContentType = "text/html; charset=utf-8"
......@@ -72,9 +78,13 @@ type streamResponse struct {
// Options are used to configure HTTPBin
type Options struct {
MaxMemory int64
MaxResponseSize int64
MaxResponseTime time.Duration
// How much memory a request is allowed to consume in bytes, as a limit on
// the size of incoming request bodies and on responses generated
MaxMemory int64
// Maximum duration of a request, for those requests that allow user
// control over timing (e.g. /delay)
MaxDuration time.Duration
}
// HTTPBin contains the business logic
......@@ -166,11 +176,18 @@ func (h *HTTPBin) Handler() http.Handler {
return handler
}
// NewHTTPBin creates a new HTTPBin
func NewHTTPBin(options *Options) *HTTPBin {
if options == nil {
options = &Options{}
// NewHTTPBin creates a new HTTPBin instance with default options
func NewHTTPBin() *HTTPBin {
return &HTTPBin{
options: &Options{
MaxMemory: DefaultMaxMemory,
MaxDuration: DefaultMaxDuration,
},
}
}
// NewHTTPBinWithOptions creates a new HTTPBin instance with the given options
func NewHTTPBinWithOptions(options *Options) *HTTPBin {
return &HTTPBin{
options: options,
}
......
package httpbin
import (
"testing"
"time"
)
func TestNewHTTPBin__Defaults(t *testing.T) {
h := NewHTTPBin()
if h.options.MaxMemory != DefaultMaxMemory {
t.Fatalf("expected default MaxMemory == %d, got %#v", DefaultMaxMemory, h.options.MaxMemory)
}
if h.options.MaxDuration != DefaultMaxDuration {
t.Fatalf("expected default MaxDuration == %s, got %#v", DefaultMaxDuration, h.options.MaxDuration)
}
}
func TestNewHTTPBinWithOptions__Defaults(t *testing.T) {
o := &Options{
MaxDuration: 1 * time.Second,
MaxMemory: 1024,
}
h := NewHTTPBinWithOptions(o)
if h.options.MaxMemory != o.MaxMemory {
t.Fatalf("expected MaxMemory == %d, got %#v", o.MaxMemory, h.options.MaxMemory)
}
if h.options.MaxDuration != o.MaxDuration {
t.Fatalf("expected MaxDuration == %s, got %#v", o.MaxDuration, h.options.MaxDuration)
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment