mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-11-04 03:27:23 -05:00 
			
		
		
		
	I am not a lawyer, but according to the appendix of the license, these boilerplate notices should be included with every source file.
		
			
				
	
	
		
			239 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			239 lines
		
	
	
		
			6.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright 2015 Light Code Labs, LLC
 | 
						|
//
 | 
						|
// Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
// you may not use this file except in compliance with the License.
 | 
						|
// You may obtain a copy of the License at
 | 
						|
//
 | 
						|
//     http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
//
 | 
						|
// Unless required by applicable law or agreed to in writing, software
 | 
						|
// distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
// See the License for the specific language governing permissions and
 | 
						|
// limitations under the License.
 | 
						|
 | 
						|
package limits
 | 
						|
 | 
						|
import (
 | 
						|
	"reflect"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"github.com/mholt/caddy"
 | 
						|
	"github.com/mholt/caddy/caddyhttp/httpserver"
 | 
						|
)
 | 
						|
 | 
						|
const (
 | 
						|
	KB = 1024
 | 
						|
	MB = 1024 * 1024
 | 
						|
	GB = 1024 * 1024 * 1024
 | 
						|
)
 | 
						|
 | 
						|
func TestParseLimits(t *testing.T) {
 | 
						|
	for name, c := range map[string]struct {
 | 
						|
		input     string
 | 
						|
		shouldErr bool
 | 
						|
		expect    httpserver.Limits
 | 
						|
	}{
 | 
						|
		"catchAll": {
 | 
						|
			input: `limits 2kb`,
 | 
						|
			expect: httpserver.Limits{
 | 
						|
				MaxRequestHeaderSize: 2 * KB,
 | 
						|
				MaxRequestBodySizes:  []httpserver.PathLimit{{Path: "/", Limit: 2 * KB}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"onlyHeader": {
 | 
						|
			input: `limits {
 | 
						|
				header 2kb
 | 
						|
			}`,
 | 
						|
			expect: httpserver.Limits{
 | 
						|
				MaxRequestHeaderSize: 2 * KB,
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"onlyBody": {
 | 
						|
			input: `limits {
 | 
						|
				body 2kb
 | 
						|
			}`,
 | 
						|
			expect: httpserver.Limits{
 | 
						|
				MaxRequestBodySizes: []httpserver.PathLimit{{Path: "/", Limit: 2 * KB}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"onlyBodyWithPath": {
 | 
						|
			input: `limits {
 | 
						|
				body /test 2kb
 | 
						|
			}`,
 | 
						|
			expect: httpserver.Limits{
 | 
						|
				MaxRequestBodySizes: []httpserver.PathLimit{{Path: "/test", Limit: 2 * KB}},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"mixture": {
 | 
						|
			input: `limits {
 | 
						|
				header 1kb
 | 
						|
				body 2kb
 | 
						|
				body /bar 3kb
 | 
						|
			}`,
 | 
						|
			expect: httpserver.Limits{
 | 
						|
				MaxRequestHeaderSize: 1 * KB,
 | 
						|
				MaxRequestBodySizes: []httpserver.PathLimit{
 | 
						|
					{Path: "/bar", Limit: 3 * KB},
 | 
						|
					{Path: "/", Limit: 2 * KB},
 | 
						|
				},
 | 
						|
			},
 | 
						|
		},
 | 
						|
		"invalidFormat": {
 | 
						|
			input:     `limits a b`,
 | 
						|
			shouldErr: true,
 | 
						|
		},
 | 
						|
		"invalidHeaderFormat": {
 | 
						|
			input: `limits {
 | 
						|
				header / 100
 | 
						|
			}`,
 | 
						|
			shouldErr: true,
 | 
						|
		},
 | 
						|
		"invalidBodyFormat": {
 | 
						|
			input: `limits {
 | 
						|
				body / 100 200
 | 
						|
			}`,
 | 
						|
			shouldErr: true,
 | 
						|
		},
 | 
						|
		"invalidKind": {
 | 
						|
			input: `limits {
 | 
						|
				head 100
 | 
						|
			}`,
 | 
						|
			shouldErr: true,
 | 
						|
		},
 | 
						|
		"invalidLimitSize": {
 | 
						|
			input:     `limits 10bk`,
 | 
						|
			shouldErr: true,
 | 
						|
		},
 | 
						|
	} {
 | 
						|
		c := c
 | 
						|
		t.Run(name, func(t *testing.T) {
 | 
						|
			controller := caddy.NewTestController("", c.input)
 | 
						|
			_, err := parseLimits(controller)
 | 
						|
			if c.shouldErr && err == nil {
 | 
						|
				t.Error("failed to get expected error")
 | 
						|
			}
 | 
						|
			if !c.shouldErr && err != nil {
 | 
						|
				t.Errorf("got unexpected error: %v", err)
 | 
						|
			}
 | 
						|
			if got := httpserver.GetConfig(controller).Limits; !reflect.DeepEqual(got, c.expect) {
 | 
						|
				t.Errorf("expect %#v, but got %#v", c.expect, got)
 | 
						|
			}
 | 
						|
		})
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestParseArguments(t *testing.T) {
 | 
						|
	cases := []struct {
 | 
						|
		arguments []pathLimitUnparsed
 | 
						|
		expected  []httpserver.PathLimit
 | 
						|
		hasError  bool
 | 
						|
	}{
 | 
						|
		// Parse errors
 | 
						|
		{arguments: []pathLimitUnparsed{{"/", "123.5"}}, expected: []httpserver.PathLimit{}, hasError: true},
 | 
						|
		{arguments: []pathLimitUnparsed{{"/", "200LB"}}, expected: []httpserver.PathLimit{}, hasError: true},
 | 
						|
		{arguments: []pathLimitUnparsed{{"/", "path:999MB"}}, expected: []httpserver.PathLimit{}, hasError: true},
 | 
						|
		{arguments: []pathLimitUnparsed{{"/", "1_234_567"}}, expected: []httpserver.PathLimit{}, hasError: true},
 | 
						|
		{arguments: []pathLimitUnparsed{{"/", "0MB"}}, expected: []httpserver.PathLimit{}, hasError: true},
 | 
						|
 | 
						|
		// Valid results
 | 
						|
		{arguments: []pathLimitUnparsed{}, expected: []httpserver.PathLimit{}, hasError: false},
 | 
						|
		{
 | 
						|
			arguments: []pathLimitUnparsed{{"/", "100"}},
 | 
						|
			expected:  []httpserver.PathLimit{{Path: "/", Limit: 100}},
 | 
						|
			hasError:  false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			arguments: []pathLimitUnparsed{{"/", "100KB"}},
 | 
						|
			expected:  []httpserver.PathLimit{{Path: "/", Limit: 100 * KB}},
 | 
						|
			hasError:  false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			arguments: []pathLimitUnparsed{{"/", "100MB"}},
 | 
						|
			expected:  []httpserver.PathLimit{{Path: "/", Limit: 100 * MB}},
 | 
						|
			hasError:  false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			arguments: []pathLimitUnparsed{{"/", "100GB"}},
 | 
						|
			expected:  []httpserver.PathLimit{{Path: "/", Limit: 100 * GB}},
 | 
						|
			hasError:  false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			arguments: []pathLimitUnparsed{{"index", "100"}},
 | 
						|
			expected:  []httpserver.PathLimit{{Path: "/index", Limit: 100}},
 | 
						|
			hasError:  false,
 | 
						|
		},
 | 
						|
		{
 | 
						|
			arguments: []pathLimitUnparsed{{"/home", "100MB"}, {"/upload/images", "500GB"}},
 | 
						|
			expected: []httpserver.PathLimit{
 | 
						|
				{Path: "/home", Limit: 100 * MB},
 | 
						|
				{Path: "/upload/images", Limit: 500 * GB},
 | 
						|
			},
 | 
						|
			hasError: false},
 | 
						|
		{
 | 
						|
			arguments: []pathLimitUnparsed{{"/", "999"}, {"/home", "12345MB"}},
 | 
						|
			expected: []httpserver.PathLimit{
 | 
						|
				{Path: "/", Limit: 999},
 | 
						|
				{Path: "/home", Limit: 12345 * MB},
 | 
						|
			},
 | 
						|
			hasError: false,
 | 
						|
		},
 | 
						|
 | 
						|
		// Duplicates
 | 
						|
		{
 | 
						|
			arguments: []pathLimitUnparsed{{"/home", "999"}, {"/home", "12345MB"}},
 | 
						|
			expected: []httpserver.PathLimit{
 | 
						|
				{Path: "/home", Limit: 12345 * MB},
 | 
						|
			},
 | 
						|
			hasError: false,
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for caseNum, c := range cases {
 | 
						|
		output, err := parseArguments(c.arguments)
 | 
						|
		if c.hasError && (err == nil) {
 | 
						|
			t.Errorf("Expecting error for case %v but none encountered", caseNum)
 | 
						|
		}
 | 
						|
		if !c.hasError && (err != nil) {
 | 
						|
			t.Errorf("Expecting no error for case %v but encountered %v", caseNum, err)
 | 
						|
		}
 | 
						|
 | 
						|
		if !reflect.DeepEqual(c.expected, output) {
 | 
						|
			t.Errorf("Case %v is expecting: %v, actual %v", caseNum, c.expected, output)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func TestSortPathLimits(t *testing.T) {
 | 
						|
	cases := []struct {
 | 
						|
		arguments []httpserver.PathLimit
 | 
						|
		expected  []httpserver.PathLimit
 | 
						|
	}{
 | 
						|
		// Parse errors
 | 
						|
		{arguments: []httpserver.PathLimit{}, expected: []httpserver.PathLimit{}},
 | 
						|
		{
 | 
						|
			arguments: []httpserver.PathLimit{{Path: "/index", Limit: 100}},
 | 
						|
			expected:  []httpserver.PathLimit{{Path: "/index", Limit: 100}},
 | 
						|
		},
 | 
						|
		{
 | 
						|
			arguments: []httpserver.PathLimit{
 | 
						|
				{Path: "/static", Limit: 1},
 | 
						|
				{Path: "/static/images", Limit: 100},
 | 
						|
				{Path: "/index", Limit: 200},
 | 
						|
			},
 | 
						|
			expected: []httpserver.PathLimit{
 | 
						|
				{Path: "/static/images", Limit: 100},
 | 
						|
				{Path: "/static", Limit: 1},
 | 
						|
				{Path: "/index", Limit: 200}},
 | 
						|
		},
 | 
						|
	}
 | 
						|
 | 
						|
	for caseNum, c := range cases {
 | 
						|
		output := append([]httpserver.PathLimit{}, c.arguments...)
 | 
						|
		SortPathLimits(output)
 | 
						|
		if !reflect.DeepEqual(c.expected, output) {
 | 
						|
			t.Errorf("Case %v is expecting: %v, actual %v", caseNum, c.expected, output)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 |