Skip to content

Commit

Permalink
Merge pull request jamestelfer#24 from jamestelfer/http-limits
Browse files Browse the repository at this point in the history
  • Loading branch information
jamestelfer authored May 8, 2024
2 parents b2edd57 + 4585e69 commit c6e246b
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 3 deletions.
6 changes: 6 additions & 0 deletions handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ func handlePostGitCredentials(tokenVendor vendor.PipelineTokenVendor) http.Handl
})
}

func maxRequestSize(limit int64) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.MaxBytesHandler(next, limit)
}
}

func requestError(w http.ResponseWriter, statusCode int) {
http.Error(w, http.StatusText(statusCode), statusCode)
}
Expand Down
39 changes: 39 additions & 0 deletions handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"encoding/json"
"errors"
"io"
"net/http"
"net/http/httptest"
"testing"
Expand Down Expand Up @@ -199,3 +200,41 @@ func tvFails(err error) vendor.PipelineTokenVendor {
return nil, err
})
}

func TestMaxRequestSizeMiddleware(t *testing.T) {

mw := maxRequestSize(10)

var readError error
var readBytes int64

innerHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
readBytes, readError = io.CopyN(io.Discard, r.Body, 5*1024*1024)

status := http.StatusOK
if readError != nil {
status = http.StatusBadRequest
}

w.WriteHeader(status)
})

handler := mw(innerHandler)

body := bytes.NewBufferString("0123456789n123456789")
req, err := http.NewRequest("POST", "/git-credentials", body)
require.NoError(t, err)

rr := httptest.NewRecorder()

// act
handler.ServeHTTP(rr, req)

// assert
assert.Equal(t, http.StatusBadRequest, rr.Code)
assert.ErrorContains(t, readError, "http: request body too large")
assert.Equal(t, int64(10), readBytes)

respBody := rr.Body.String()
assert.Equal(t, "", respBody)
}
11 changes: 8 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ func configureServerRoutes(cfg config.Config) (http.Handler, error) {
return nil, fmt.Errorf("authorizer configuration failed: %w", err)
}

authorized := alice.New(authorizer)
// The request body size is fairly limited to prevent accidental or
// deliberate abuse. Given the current API shape, this is not configurable.
requestLimitBytes := int64(20 << 10) // 20 KB

authorized := alice.New(maxRequestSize(requestLimitBytes), authorizer)

// setup token handler and dependencies
bk := buildkite.New(cfg.Buildkite)
Expand Down Expand Up @@ -79,8 +83,9 @@ func launchServer() error {
}

server := &http.Server{
Addr: fmt.Sprintf(":%d", cfg.Server.Port),
Handler: handler,
Addr: fmt.Sprintf(":%d", cfg.Server.Port),
Handler: handler,
MaxHeaderBytes: 20 << 10, // 20 KB
}

shutdownTelemetry, err := observe.Configure(ctx, cfg.Observe)
Expand Down

0 comments on commit c6e246b

Please sign in to comment.