srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/internal/proxy/intrude_test.go
blob: 5df80e6a53cb31917ca7741997d8b9290cb194b6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package proxy

import (
	"reflect"
	"testing"
)

func TestParseMarkers(t *testing.T) {
	tests := []struct {
		name     string
		template string
		wantPos  []IntrudePosition
		wantOut  string
		wantErr  bool
	}{
		{
			name:     "single position",
			template: "GET /users/§123§ HTTP/1.1",
			wantPos:  []IntrudePosition{{Index: 0, Base: "123"}},
			wantOut:  "GET /users/123 HTTP/1.1",
		},
		{
			name:     "two positions",
			template: "GET /a/§1§/b/§2§ HTTP/1.1",
			wantPos:  []IntrudePosition{{Index: 0, Base: "1"}, {Index: 1, Base: "2"}},
			wantOut:  "GET /a/1/b/2 HTTP/1.1",
		},
		{
			name:     "no markers",
			template: "GET / HTTP/1.1",
			wantPos:  nil,
			wantOut:  "GET / HTTP/1.1",
		},
		{
			name:     "empty marker",
			template: "GET /§§ HTTP/1.1",
			wantPos:  []IntrudePosition{{Index: 0, Base: ""}},
			wantOut:  "GET / HTTP/1.1",
		},
		{
			name:     "unterminated marker",
			template: "GET /§broken HTTP/1.1",
			wantErr:  true,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			pos, out, err := ParseMarkers([]byte(tt.template))
			if tt.wantErr {
				if err == nil {
					t.Fatalf("expected error, got nil")
				}
				return
			}
			if err != nil {
				t.Fatalf("unexpected error: %v", err)
			}
			if !reflect.DeepEqual(pos, tt.wantPos) {
				t.Errorf("positions = %+v, want %+v", pos, tt.wantPos)
			}
			if string(out) != tt.wantOut {
				t.Errorf("stripped = %q, want %q", out, tt.wantOut)
			}
		})
	}
}

func TestBuildRequest(t *testing.T) {
	template := "GET /a/§1§/b/§2§/c/§3§ HTTP/1.1"

	tests := []struct {
		active  int
		payload string
		want    string
	}{
		{0, "PAYLOAD", "GET /a/PAYLOAD/b/2/c/3 HTTP/1.1"},
		{1, "PAYLOAD", "GET /a/1/b/PAYLOAD/c/3 HTTP/1.1"},
		{2, "PAYLOAD", "GET /a/1/b/2/c/PAYLOAD HTTP/1.1"},
	}

	for _, tt := range tests {
		got, err := buildRequest([]byte(template), tt.active, tt.payload)
		if err != nil {
			t.Fatalf("active=%d: unexpected error: %v", tt.active, err)
		}
		if string(got) != tt.want {
			t.Errorf("active=%d: got %q, want %q", tt.active, got, tt.want)
		}
	}
}

func TestBuildRequestPayloadContainingMarkerChar(t *testing.T) {
	// A payload that itself contains the marker character must not be
	// reinterpreted as a marker on a later buildRequest call - each call
	// re-splits the ORIGINAL template, not the previously built request.
	template := "GET /§1§/§2§ HTTP/1.1"
	got, err := buildRequest([]byte(template), 0, "§injected§")
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}
	want := "GET /§injected§/2 HTTP/1.1"
	if string(got) != want {
		t.Errorf("got %q, want %q", got, want)
	}
}

func TestIntrudeRequestCount(t *testing.T) {
	positions, _, err := ParseMarkers([]byte("GET /§a§/§b§ HTTP/1.1"))
	if err != nil {
		t.Fatal(err)
	}
	if len(positions) != 2 {
		t.Fatalf("expected 2 positions, got %d", len(positions))
	}
}