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  }