mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-10-31 10:37:24 -04: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)
 | |
| 		}
 | |
| 	}
 | |
| }
 |