Make connection limit configurable

master
Harshavardhana 10 years ago
parent 6263b99e5a
commit 8b43655d9f
  1. 6
      main.go
  2. 35
      pkg/api/api_router.go
  3. 60
      pkg/api/api_test.go
  4. 1
      pkg/server/httpserver/httpserver.go
  5. 12
      pkg/server/server.go

@ -45,6 +45,11 @@ var flags = []cli.Flag{
Usage: "ADDRESS:PORT for management console access", Usage: "ADDRESS:PORT for management console access",
}, },
*/ */
cli.IntFlag{
Name: "conn-limit",
Value: 16,
Usage: "Set per IP connection limit quota for server: [DEFAULT: 16]",
},
cli.StringFlag{ cli.StringFlag{
Name: "cert", Name: "cert",
Hide: true, Hide: true,
@ -83,6 +88,7 @@ func getAPIServerConfig(c *cli.Context) httpserver.Config {
TLS: tls, TLS: tls,
CertFile: certFile, CertFile: certFile,
KeyFile: keyFile, KeyFile: keyFile,
ConnectionLimit: c.GlobalInt("conn-limit"),
} }
} }

@ -25,16 +25,31 @@ import (
"github.com/minio/minio/pkg/storage/drivers" "github.com/minio/minio/pkg/storage/drivers"
) )
// private use
type minioAPI struct { type minioAPI struct {
driver drivers.Driver driver drivers.Driver
} }
// Config api configurable parameters
type Config struct {
ConnectionLimit int
driver drivers.Driver
}
// GetDriver - get a an existing set driver
func (c Config) GetDriver() drivers.Driver {
return c.driver
}
// SetDriver - set a new driver
func (c *Config) SetDriver(driver drivers.Driver) {
c.driver = driver
}
// HTTPHandler - http wrapper handler // HTTPHandler - http wrapper handler
func HTTPHandler(driver drivers.Driver) http.Handler { func HTTPHandler(config Config) http.Handler {
var mux *router.Router var mux *router.Router
var api = minioAPI{} var api = minioAPI{}
api.driver = driver api.driver = config.GetDriver()
mux = router.NewRouter() mux = router.NewRouter()
mux.HandleFunc("/", api.listBucketsHandler).Methods("GET") mux.HandleFunc("/", api.listBucketsHandler).Methods("GET")
@ -50,15 +65,15 @@ func HTTPHandler(driver drivers.Driver) http.Handler {
mux.HandleFunc("/{bucket}/{object:.*}", api.getObjectHandler).Methods("GET") mux.HandleFunc("/{bucket}/{object:.*}", api.getObjectHandler).Methods("GET")
mux.HandleFunc("/{bucket}/{object:.*}", api.putObjectHandler).Methods("PUT") mux.HandleFunc("/{bucket}/{object:.*}", api.putObjectHandler).Methods("PUT")
h := validContentTypeHandler(mux) handler := validContentTypeHandler(mux)
h = timeValidityHandler(h) handler = timeValidityHandler(handler)
h = ignoreResourcesHandler(h) handler = ignoreResourcesHandler(handler)
h = validateAuthHeaderHandler(h) handler = validateAuthHeaderHandler(handler)
// h = quota.BandwidthCap(h, 25*1024*1024, time.Duration(30*time.Minute)) // h = quota.BandwidthCap(h, 25*1024*1024, time.Duration(30*time.Minute))
// h = quota.BandwidthCap(h, 100*1024*1024, time.Duration(24*time.Hour)) // h = quota.BandwidthCap(h, 100*1024*1024, time.Duration(24*time.Hour))
// h = quota.RequestLimit(h, 100, time.Duration(30*time.Minute)) // h = quota.RequestLimit(h, 100, time.Duration(30*time.Minute))
// h = quota.RequestLimit(h, 1000, time.Duration(24*time.Hour)) // h = quota.RequestLimit(h, 1000, time.Duration(24*time.Hour))
h = quota.ConnectionLimit(h, 4) handler = quota.ConnectionLimit(handler, config.ConnectionLimit)
h = logging.LogHandler(h) handler = logging.LogHandler(handler)
return h return handler
} }

@ -123,6 +123,12 @@ func setDummyAuthHeader(req *http.Request) {
req.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat)) req.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat))
} }
func setConfig(driver drivers.Driver) Config {
conf := Config{ConnectionLimit: 16}
conf.SetDriver(driver)
return conf
}
func (s *MySuite) TestNonExistantBucket(c *C) { func (s *MySuite) TestNonExistantBucket(c *C) {
switch driver := s.Driver.(type) { switch driver := s.Driver.(type) {
case *mocks.Driver: case *mocks.Driver:
@ -131,7 +137,7 @@ func (s *MySuite) TestNonExistantBucket(c *C) {
} }
} }
driver := s.Driver driver := s.Driver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
@ -169,7 +175,7 @@ func (s *MySuite) TestEmptyObject(c *C) {
typedDriver.On("GetObjectMetadata", "bucket", "object").Return(metadata, nil).Once() typedDriver.On("GetObjectMetadata", "bucket", "object").Return(metadata, nil).Once()
typedDriver.On("GetObject", mock.Anything, "bucket", "object").Return(int64(0), nil).Once() typedDriver.On("GetObject", mock.Anything, "bucket", "object").Return(int64(0), nil).Once()
typedDriver.On("GetObjectMetadata", "bucket", "object").Return(metadata, nil).Once() typedDriver.On("GetObjectMetadata", "bucket", "object").Return(metadata, nil).Once()
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
@ -212,7 +218,7 @@ func (s *MySuite) TestBucket(c *C) {
typedDriver.On("CreateBucket", "bucket", "private").Return(nil).Once() typedDriver.On("CreateBucket", "bucket", "private").Return(nil).Once()
typedDriver.On("GetBucketMetadata", "bucket").Return(metadata, nil).Once() typedDriver.On("GetBucketMetadata", "bucket").Return(metadata, nil).Once()
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
@ -252,7 +258,7 @@ func (s *MySuite) TestObject(c *C) {
typedDriver.SetGetObjectWriter("bucket", "object", []byte("hello world")) typedDriver.SetGetObjectWriter("bucket", "object", []byte("hello world"))
typedDriver.On("GetObject", mock.Anything, "bucket", "object").Return(int64(0), nil).Once() typedDriver.On("GetObject", mock.Anything, "bucket", "object").Return(int64(0), nil).Once()
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
@ -311,7 +317,7 @@ func (s *MySuite) TestMultipleObjects(c *C) {
Md5: "4e74ad3b92e2843e208a13ae1cf0d52c", Md5: "4e74ad3b92e2843e208a13ae1cf0d52c",
Size: 11, Size: 11,
} }
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
@ -441,7 +447,7 @@ func (s *MySuite) TestNotImplemented(c *C) {
} }
} }
driver := s.Driver driver := s.Driver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
@ -466,7 +472,7 @@ func (s *MySuite) TestHeader(c *C) {
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
typedDriver.AssertExpectations(c) typedDriver.AssertExpectations(c)
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
@ -535,7 +541,7 @@ func (s *MySuite) TestPutBucket(c *C) {
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
@ -572,7 +578,7 @@ func (s *MySuite) TestPutObject(c *C) {
} }
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
@ -661,7 +667,7 @@ func (s *MySuite) TestListBuckets(c *C) {
} }
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
@ -754,7 +760,7 @@ func (s *MySuite) TestNotBeAbleToCreateObjectInNonexistantBucket(c *C) {
} }
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
@ -788,7 +794,7 @@ func (s *MySuite) TestHeadOnObject(c *C) {
} }
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
@ -842,7 +848,7 @@ func (s *MySuite) TestHeadOnBucket(c *C) {
} }
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
@ -876,7 +882,7 @@ func (s *MySuite) TestDateFormat(c *C) {
} }
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
@ -924,7 +930,7 @@ func (s *MySuite) TestXMLNameNotInBucketListJson(c *C) {
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
@ -957,7 +963,7 @@ func (s *MySuite) TestXMLNameNotInObjectListJson(c *C) {
} }
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
@ -1002,7 +1008,7 @@ func (s *MySuite) TestContentTypePersists(c *C) {
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
@ -1117,7 +1123,7 @@ func (s *MySuite) TestPartialContent(c *C) {
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
@ -1175,7 +1181,7 @@ func (s *MySuite) TestListObjectsHandlerErrors(c *C) {
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
client := http.Client{} client := http.Client{}
@ -1242,7 +1248,7 @@ func (s *MySuite) TestListBucketsErrors(c *C) {
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
client := http.Client{} client := http.Client{}
@ -1279,7 +1285,7 @@ func (s *MySuite) TestPutBucketErrors(c *C) {
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
client := http.Client{} client := http.Client{}
@ -1339,7 +1345,7 @@ func (s *MySuite) TestGetObjectErrors(c *C) {
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
client := http.Client{} client := http.Client{}
@ -1412,7 +1418,7 @@ func (s *MySuite) TestGetObjectRangeErrors(c *C) {
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
client := http.Client{} client := http.Client{}
@ -1456,7 +1462,7 @@ func (s *MySuite) TestObjectMultipartAbort(c *C) {
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
client := http.Client{} client := http.Client{}
@ -1539,7 +1545,7 @@ func (s *MySuite) TestBucketMultipartList(c *C) {
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
client := http.Client{} client := http.Client{}
@ -1628,7 +1634,7 @@ func (s *MySuite) TestObjectMultipartList(c *C) {
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
client := http.Client{} client := http.Client{}
@ -1712,7 +1718,7 @@ func (s *MySuite) TestObjectMultipart(c *C) {
driver := s.Driver driver := s.Driver
typedDriver := s.MockDriver typedDriver := s.MockDriver
httpHandler := HTTPHandler(driver) httpHandler := HTTPHandler(setConfig(driver))
testServer := httptest.NewServer(httpHandler) testServer := httptest.NewServer(httpHandler)
defer testServer.Close() defer testServer.Close()
client := http.Client{} client := http.Client{}

@ -29,6 +29,7 @@ type Config struct {
TLS bool TLS bool
CertFile string CertFile string
KeyFile string KeyFile string
ConnectionLimit int
} }
// Server - http server related // Server - http server related

@ -43,7 +43,9 @@ type MemoryFactory struct {
func (f MemoryFactory) GetStartServerFunc() StartServerFunc { func (f MemoryFactory) GetStartServerFunc() StartServerFunc {
return func() (chan<- string, <-chan error) { return func() (chan<- string, <-chan error) {
_, _, driver := memory.Start(f.MaxMemory, f.Expiration) _, _, driver := memory.Start(f.MaxMemory, f.Expiration)
ctrl, status, _ := httpserver.Start(api.HTTPHandler(driver), f.Config) conf := api.Config{ConnectionLimit: f.ConnectionLimit}
conf.SetDriver(driver)
ctrl, status, _ := httpserver.Start(api.HTTPHandler(conf), f.Config)
return ctrl, status return ctrl, status
} }
} }
@ -58,7 +60,9 @@ type FilesystemFactory struct {
func (f FilesystemFactory) GetStartServerFunc() StartServerFunc { func (f FilesystemFactory) GetStartServerFunc() StartServerFunc {
return func() (chan<- string, <-chan error) { return func() (chan<- string, <-chan error) {
_, _, driver := fs.Start(f.Path) _, _, driver := fs.Start(f.Path)
ctrl, status, _ := httpserver.Start(api.HTTPHandler(driver), f.Config) conf := api.Config{ConnectionLimit: f.ConnectionLimit}
conf.SetDriver(driver)
ctrl, status, _ := httpserver.Start(api.HTTPHandler(conf), f.Config)
return ctrl, status return ctrl, status
} }
} }
@ -86,7 +90,9 @@ type DonutFactory struct {
func (f DonutFactory) GetStartServerFunc() StartServerFunc { func (f DonutFactory) GetStartServerFunc() StartServerFunc {
return func() (chan<- string, <-chan error) { return func() (chan<- string, <-chan error) {
_, _, driver := donut.Start(f.Paths) _, _, driver := donut.Start(f.Paths)
ctrl, status, _ := httpserver.Start(api.HTTPHandler(driver), f.Config) conf := api.Config{ConnectionLimit: f.ConnectionLimit}
conf.SetDriver(driver)
ctrl, status, _ := httpserver.Start(api.HTTPHandler(conf), f.Config)
return ctrl, status return ctrl, status
} }
} }

Loading…
Cancel
Save