Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type Server struct {
Cors Cors
TrustedProxies []string
SecureCookie bool
MaxBodyBytes int
}

type Database struct {
Expand Down Expand Up @@ -111,6 +112,7 @@ func Get() (*Configuration, []FutureLog) {
Stream: Stream{
PingPeriodSeconds: 45,
},
MaxBodyBytes: 10 * 1024 * 1024,
},
Database: Database{
Dialect: "sqlite3",
Expand Down Expand Up @@ -174,6 +176,7 @@ func Get() (*Configuration, []FutureLog) {

add(parseList(&c.Server.TrustedProxies, EnvServerTrustedProxies))
add(parseBool(&c.Server.SecureCookie, EnvServerSecureCookie))
add(parseInt(&c.Server.MaxBodyBytes, EnvServerMaxBodyBytes))

add(parseString(&c.Database.Dialect, EnvDatabaseDialect))
add(parseString(&c.Database.Connection, EnvDatabaseConnection))
Expand Down
1 change: 1 addition & 0 deletions config/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const (
EnvServerCorsAllowHeaders = "GOTIFY_SERVER_CORS_ALLOWHEADERS"
EnvServerTrustedProxies = "GOTIFY_SERVER_TRUSTEDPROXIES"
EnvServerSecureCookie = "GOTIFY_SERVER_SECURECOOKIE"
EnvServerMaxBodyBytes = "GOTIFY_SERVER_MAX_BODY_BYTES"
EnvDatabaseDialect = "GOTIFY_DATABASE_DIALECT"
EnvDatabaseConnection = "GOTIFY_DATABASE_CONNECTION"
EnvDefaultUserName = "GOTIFY_DEFAULTUSER_NAME"
Expand Down
6 changes: 6 additions & 0 deletions gotify-server.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@
# Type: boolean
# GOTIFY_SERVER_SECURECOOKIE=false

# Maximum size in bytes of a request body. Requests with a larger body are
# rejected. Set to 0 to disable the limit.
#
# Type: number
# GOTIFY_SERVER_MAX_BODY_BYTES=10485760

# Allowed origins (regex) for cross-origin requests. Setting any CORS_* value
# enables CORS handling.
#
Expand Down
6 changes: 6 additions & 0 deletions router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ func Create(db *database.GormDatabase, vInfo *model.VersionInfo, conf *config.Co
g.Use(accessLogger(), gin.Recovery(), gerror.Handler(), location.Default())
g.NoRoute(gerror.NotFound())

if conf.Server.MaxBodyBytes > 0 {
g.Use(func(ctx *gin.Context) {
ctx.Request.Body = http.MaxBytesReader(ctx.Writer, ctx.Request.Body, int64(conf.Server.MaxBodyBytes))
})
}

if conf.Server.SSL.Enabled && conf.Server.SSL.RedirectToHTTPS {
g.Use(func(ctx *gin.Context) {
if ctx.Request.TLS != nil {
Expand Down
17 changes: 17 additions & 0 deletions router/router_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func (s *IntegrationSuite) BeforeTest(string, string) {
s.db.GormDatabase,
&model.VersionInfo{Version: "1.0.0", BuildDate: "2018-02-20-17:30:47", Commit: "asdasds"},
&config.Configuration{
Server: config.Server{MaxBodyBytes: 1024},
PassStrength: 5,
LocalAuthEnabled: true,
OIDC: config.OIDC{IDPName: "Company XYZ SSO"},
Expand Down Expand Up @@ -361,6 +362,22 @@ func (s *IntegrationSuite) TestSendMessage() {
assert.Equal(s.T(), token.ID, msg.ApplicationID)
}

func (s *IntegrationSuite) TestMaxBodyBytes() {
s.db.User(2).AppWithToken(1, "Aapp")

// 1024 bytes, exactly the configured limit.
req := s.newRequest("POST", "message", `{"message":"`+strings.Repeat("a", 1010)+`"}`)
req.Header.Add("X-Gotify-Key", "Aapp")
res, err := client.Do(req)
assert.Nil(s.T(), err)
assert.Equal(s.T(), 200, res.StatusCode)

// 1025 bytes, one byte over the limit.
req = s.newRequest("POST", "message", `{"message":"`+strings.Repeat("a", 1011)+`"}`)
req.Header.Add("X-Gotify-Key", "Aapp")
doRequestAndExpect(s.T(), req, 413, `{"error":"Request Entity Too Large", "errorCode":413, "errorDescription":"http: request body too large"}`)
}

func (s *IntegrationSuite) TestPluginLoadFail_expectPanic() {
db := testdb.NewDBWithDefaultUser(s.T())
defer db.Close()
Expand Down
Loading