github.com/ipfans/trojan-go@v0.11.0/url/share_link_test.go (about) 1 package url 2 3 import ( 4 crand "crypto/rand" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "testing" 9 10 "github.com/stretchr/testify/assert" 11 ) 12 13 func TestHandleTrojanPort_Default(t *testing.T) { 14 port, e := handleTrojanPort("") 15 assert.Nil(t, e, "empty port should not error") 16 assert.EqualValues(t, 443, port, "empty port should fallback to 443") 17 } 18 19 func TestHandleTrojanPort_NotNumber(t *testing.T) { 20 _, e := handleTrojanPort("fuck") 21 assert.Error(t, e, "non-numerical port should error") 22 } 23 24 func TestHandleTrojanPort_GoodNumber(t *testing.T) { 25 testCases := []string{"443", "8080", "10086", "80", "65535", "1"} 26 for _, testCase := range testCases { 27 _, e := handleTrojanPort(testCase) 28 assert.Nil(t, e, "good port %s should not error", testCase) 29 } 30 } 31 32 func TestHandleTrojanPort_InvalidNumber(t *testing.T) { 33 testCases := []string{"443.0", "443.000", "8e2", "3.5", "9.99", "-1", "-65535", "65536", "0"} 34 35 for _, testCase := range testCases { 36 _, e := handleTrojanPort(testCase) 37 assert.Error(t, e, "invalid number port %s should error", testCase) 38 } 39 } 40 41 func TestNewShareInfoFromURL_Empty(t *testing.T) { 42 _, e := NewShareInfoFromURL("") 43 assert.Error(t, e, "empty link should lead to error") 44 } 45 46 func TestNewShareInfoFromURL_RandomCrap(t *testing.T) { 47 for i := 0; i < 100; i++ { 48 randomCrap, _ := ioutil.ReadAll(io.LimitReader(crand.Reader, 10)) 49 _, e := NewShareInfoFromURL(string(randomCrap)) 50 assert.Error(t, e, "random crap %v should lead to error", randomCrap) 51 } 52 } 53 54 func TestNewShareInfoFromURL_NotTrojanGo(t *testing.T) { 55 testCases := []string{ 56 "trojan://what.ever@www.twitter.com:443?allowInsecure=1&allowInsecureHostname=1&allowInsecureCertificate=1&sessionTicket=0&tfo=1#some-trojan", 57 "ssr://d3d3LnR3aXR0ZXIuY29tOjgwOmF1dGhfc2hhMV92NDpjaGFjaGEyMDpwbGFpbjpZbkpsWVd0M1lXeHMvP29iZnNwYXJhbT0mcmVtYXJrcz02TC1INXB5ZjVwZTI2WmUwNzd5YU1qQXlNQzB3TnkweE9DQXhNam8xTlRveU1RJmdyb3VwPVEzUkRiRzkxWkNCVFUxSQ", 58 "vmess://eyJhZGQiOiJtb3RoZXIuZnVja2VyIiwiYWlkIjowLCJpZCI6IjFmYzI0NzVmLThmNDMtM2FlYi05MzUyLTU2MTFhZjg1NmQyOSIsIm5ldCI6InRjcCIsInBvcnQiOjEwMDg2LCJwcyI6Iui/h+acn+aXtumXtO+8mjIwMjAtMDYtMjMiLCJ0bHMiOiJub25lIiwidHlwZSI6Im5vbmUiLCJ2IjoyfQ==", 59 } 60 61 for _, testCase := range testCases { 62 _, e := NewShareInfoFromURL(testCase) 63 assert.Error(t, e, "non trojan-go link %s should not decode", testCase) 64 } 65 } 66 67 func TestNewShareInfoFromURL_EmptyTrojanHost(t *testing.T) { 68 _, e := NewShareInfoFromURL("trojan-go://fuckyou@:443/") 69 assert.Error(t, e, "empty host should not decode") 70 } 71 72 func TestNewShareInfoFromURL_BadPassword(t *testing.T) { 73 testCases := []string{ 74 "trojan-go://we:are:the:champion@114514.go", 75 "trojan-go://evilpassword:@1919810.me", 76 "trojan-go://evilpassword::@1919810.me", 77 "trojan-go://@password.404", 78 "trojan-go://mother.fuck#yeah", 79 } 80 81 for _, testCase := range testCases { 82 _, e := NewShareInfoFromURL(testCase) 83 assert.Error(t, e, "bad password link %s should not decode", testCase) 84 } 85 } 86 87 func TestNewShareInfoFromURL_GoodPassword(t *testing.T) { 88 testCases := []string{ 89 "trojan-go://we%3Aare%3Athe%3Achampion@114514.go", 90 "trojan-go://evilpassword%3A@1919810.me", 91 "trojan-go://passw0rd-is-a-must@password.200", 92 } 93 94 for _, testCase := range testCases { 95 _, e := NewShareInfoFromURL(testCase) 96 assert.Nil(t, e, "good password link %s should decode", testCase) 97 } 98 } 99 100 func TestNewShareInfoFromURL_BadPort(t *testing.T) { 101 testCases := []string{ 102 "trojan-go://pswd@example.com:114514", 103 "trojan-go://pswd@example.com:443.0", 104 "trojan-go://pswd@example.com:-1", 105 "trojan-go://pswd@example.com:8e2", 106 "trojan-go://pswd@example.com:65536", 107 } 108 109 for _, testCase := range testCases { 110 _, e := NewShareInfoFromURL(testCase) 111 assert.Error(t, e, "decode url %s with invalid port should error", testCase) 112 } 113 } 114 115 func TestNewShareInfoFromURL_BadQuery(t *testing.T) { 116 testCases := []string{ 117 "trojan-go://cao@ni.ma?NMSL=%CG%GE%CAONIMA", 118 "trojan-go://ni@ta.ma:13/?#%2e%fu", 119 } 120 121 for _, testCase := range testCases { 122 _, e := NewShareInfoFromURL(testCase) 123 assert.Error(t, e, "parse bad query should error") 124 } 125 } 126 127 func TestNewShareInfoFromURL_SNI_Empty(t *testing.T) { 128 _, e := NewShareInfoFromURL("trojan-go://a@b.c?sni=") 129 assert.Error(t, e, "empty SNI should not be allowed") 130 } 131 132 func TestNewShareInfoFromURL_SNI_Default(t *testing.T) { 133 info, e := NewShareInfoFromURL("trojan-go://a@b.c") 134 assert.Nil(t, e) 135 assert.Equal(t, info.TrojanHost, info.SNI, "default sni should be trojan hostname") 136 } 137 138 func TestNewShareInfoFromURL_SNI_Multiple(t *testing.T) { 139 _, e := NewShareInfoFromURL("trojan-go://a@b.c?sni=a&sni=b&sni=c") 140 assert.Error(t, e, "multiple SNIs should not be allowed") 141 } 142 143 func TestNewShareInfoFromURL_Type_Empty(t *testing.T) { 144 _, e := NewShareInfoFromURL("trojan-go://a@b.c?type=") 145 assert.Error(t, e, "empty type should not be allowed") 146 } 147 148 func TestNewShareInfoFromURL_Type_Default(t *testing.T) { 149 info, e := NewShareInfoFromURL("trojan-go://a@b.c") 150 assert.Nil(t, e) 151 assert.Equal(t, ShareInfoTypeOriginal, info.Type, "default type should be original") 152 } 153 154 func TestNewShareInfoFromURL_Type_Invalid(t *testing.T) { 155 invalidTypes := []string{"nmsl", "dio"} 156 for _, invalidType := range invalidTypes { 157 _, e := NewShareInfoFromURL(fmt.Sprintf("trojan-go://a@b.c?type=%s", invalidType)) 158 assert.Error(t, e, "%s should not be a valid type", invalidType) 159 } 160 } 161 162 func TestNewShareInfoFromURL_Type_Multiple(t *testing.T) { 163 _, e := NewShareInfoFromURL("trojan-go://a@b.c?type=a&type=b&type=c") 164 assert.Error(t, e, "multiple types should not be allowed") 165 } 166 167 func TestNewShareInfoFromURL_Host_Empty(t *testing.T) { 168 _, e := NewShareInfoFromURL("trojan-go://a@b.c?host=") 169 assert.Error(t, e, "empty host should not be allowed") 170 } 171 172 func TestNewShareInfoFromURL_Host_Default(t *testing.T) { 173 info, e := NewShareInfoFromURL("trojan-go://a@b.c") 174 assert.Nil(t, e) 175 assert.Equal(t, info.TrojanHost, info.Host, "default host should be trojan hostname") 176 } 177 178 func TestNewShareInfoFromURL_Host_Multiple(t *testing.T) { 179 _, e := NewShareInfoFromURL("trojan-go://a@b.c?host=a&host=b&host=c") 180 assert.Error(t, e, "multiple hosts should not be allowed") 181 } 182 183 func TestNewShareInfoFromURL_Type_WS_Multiple(t *testing.T) { 184 _, e := NewShareInfoFromURL("trojan-go://a@b.c?type=ws&path=a&path=b&path=c") 185 assert.Error(t, e, "multiple paths should not be allowed in wss") 186 } 187 188 func TestNewShareInfoFromURL_Path_WS_None(t *testing.T) { 189 _, e := NewShareInfoFromURL("trojan-go://a@b.c?type=ws") 190 assert.Error(t, e, "ws should require path") 191 } 192 193 func TestNewShareInfoFromURL_Path_WS_Empty(t *testing.T) { 194 _, e := NewShareInfoFromURL("trojan-go://a@b.c?type=ws&path=") 195 assert.Error(t, e, "empty path should not be allowed in ws") 196 } 197 198 func TestNewShareInfoFromURL_Path_WS_Invalid(t *testing.T) { 199 invalidPaths := []string{"../", ".+!", " "} 200 for _, invalidPath := range invalidPaths { 201 _, e := NewShareInfoFromURL(fmt.Sprintf("trojan-go://a@b.c?type=ws&path=%s", invalidPath)) 202 assert.Error(t, e, "%s should not be a valid path in ws", invalidPath) 203 } 204 } 205 206 func TestNewShareInfoFromURL_Path_Plain_Empty(t *testing.T) { 207 _, e := NewShareInfoFromURL("trojan-go://a@b.c?type=original&path=") 208 assert.Nil(t, e, "empty path should be ignored in original mode") 209 } 210 211 func TestNewShareInfoFromURL_Encryption_Empty(t *testing.T) { 212 _, e := NewShareInfoFromURL("trojan-go://a@b.c?encryption=") 213 assert.Error(t, e, "encryption should not be empty") 214 } 215 216 func TestNewShareInfoFromURL_Encryption_Unknown(t *testing.T) { 217 _, e := NewShareInfoFromURL("trojan-go://a@b.c?encryption=motherfucker") 218 assert.Error(t, e, "unknown encryption should not be supported") 219 } 220 221 func TestNewShareInfoFromURL_Encryption_None(t *testing.T) { 222 _, e := NewShareInfoFromURL("trojan-go://what@ever.me?encryption=none") 223 assert.Nil(t, e, "should support none encryption") 224 } 225 226 func TestNewShareInfoFromURL_Encryption_SS_NotSupportedMethods(t *testing.T) { 227 invalidMethods := []string{"rc4-md5", "rc4", "des-cfb", "table", "salsa20-ctr"} 228 for _, invalidMethod := range invalidMethods { 229 _, e := NewShareInfoFromURL(fmt.Sprintf("trojan-go://a@b.c?encryption=ss%%3B%s%%3Ashabi", invalidMethod)) 230 assert.Error(t, e, "encryption %s should not be supported by ss", invalidMethod) 231 } 232 } 233 234 func TestNewShareInfoFromURL_Encryption_SS_NoPassword(t *testing.T) { 235 _, e := NewShareInfoFromURL("trojan-go://a@b.c?encryption=ss%3Baes-256-gcm%3A") 236 assert.Error(t, e, "empty ss password should not be allowed") 237 } 238 239 func TestNewShareInfoFromURL_Encryption_SS_BadParams(t *testing.T) { 240 _, e := NewShareInfoFromURL("trojan-go://a@b.c?encryption=ss%3Ba") 241 assert.Error(t, e, "broken ss param should not be allowed") 242 } 243 244 func TestNewShareInfoFromURL_Encryption_Multiple(t *testing.T) { 245 _, e := NewShareInfoFromURL("trojan-go://a@b.c?encryption=a&encryption=b&encryption=c") 246 assert.Error(t, e, "multiple encryption should not be allowed") 247 } 248 249 func TestNewShareInfoFromURL_Plugin_Empty(t *testing.T) { 250 _, e := NewShareInfoFromURL("trojan-go://a@b.c?plugin=") 251 assert.Error(t, e, "plugin should not be empty") 252 } 253 254 func TestNewShareInfoFromURL_Plugin_Multiple(t *testing.T) { 255 _, e := NewShareInfoFromURL("trojan-go://a@b.c?plugin=a&plugin=b&plugin=c") 256 assert.Error(t, e, "multiple plugin should not be allowed") 257 }