@@ -1090,60 +1090,175 @@ func TestContext_Request(t *testing.T) {
10901090}
10911091
10921092func TestContext_Scheme (t * testing.T ) {
1093- tests := []struct {
1094- c * Context
1095- s string
1093+ var testCases = []struct {
1094+ name string
1095+ givenIsTLS bool
1096+ givenHeaders http.Header
1097+ expect string
10961098 }{
10971099 {
1098- & Context {
1099- request : & http.Request {
1100- TLS : & tls.ConnectionState {},
1101- },
1100+ name : "defaults to http without TLS or headers" ,
1101+ givenIsTLS : false ,
1102+ givenHeaders : nil ,
1103+ expect : "http" ,
1104+ },
1105+ {
1106+ name : "returns https when TLS is enabled" ,
1107+ givenIsTLS : true ,
1108+ givenHeaders : nil ,
1109+ expect : "https" ,
1110+ },
1111+ {
1112+ name : "TLS takes precedence over forwarded proto" ,
1113+ givenIsTLS : true ,
1114+ givenHeaders : http.Header {
1115+ HeaderXForwardedProto : []string {"http" },
11021116 },
1103- "https" ,
1117+ expect : "https" ,
11041118 },
11051119 {
1106- & Context {
1107- request : & http. Request {
1108- Header : http.Header {HeaderXForwardedProto : [] string { "https" }},
1109- },
1120+ name : "uses X-Forwarded-Proto http" ,
1121+ givenIsTLS : false ,
1122+ givenHeaders : http.Header {
1123+ HeaderXForwardedProto : [] string { "http" },
11101124 },
1111- "https " ,
1125+ expect : "http " ,
11121126 },
11131127 {
1114- & Context {
1115- request : & http. Request {
1116- Header : http.Header {HeaderXForwardedProtocol : [] string { "http" }},
1117- },
1128+ name : "uses X-Forwarded-Proto https" ,
1129+ givenIsTLS : false ,
1130+ givenHeaders : http.Header {
1131+ HeaderXForwardedProto : [] string { "https" },
11181132 },
1119- "http " ,
1133+ expect : "https " ,
11201134 },
11211135 {
1122- & Context {
1123- request : & http. Request {
1124- Header : http.Header {HeaderXForwardedSsl : [] string { "on" }},
1125- },
1136+ name : "X-Forwarded-Proto is case insensitive" ,
1137+ givenIsTLS : false ,
1138+ givenHeaders : http.Header {
1139+ HeaderXForwardedProto : [] string { "HTTPS" },
11261140 },
1127- "https " ,
1141+ expect : "HTTPS " ,
11281142 },
11291143 {
1130- & Context {
1131- request : & http. Request {
1132- Header : http.Header {HeaderXUrlScheme : [] string { "https" }},
1133- },
1144+ name : "uses X-Forwarded-Proto ws" ,
1145+ givenIsTLS : false ,
1146+ givenHeaders : http.Header {
1147+ HeaderXForwardedProto : [] string { "ws" },
11341148 },
1135- "https " ,
1149+ expect : "ws " ,
11361150 },
11371151 {
1138- & Context {
1139- request : & http.Request {},
1152+ name : "uses X-Forwarded-Proto wss" ,
1153+ givenIsTLS : false ,
1154+ givenHeaders : http.Header {
1155+ HeaderXForwardedProto : []string {"wss" },
11401156 },
1141- "http" ,
1157+ expect : "wss" ,
1158+ },
1159+ {
1160+ name : "ignores invalid X-Forwarded-Proto and uses X-Forwarded-Protocol" ,
1161+ givenIsTLS : false ,
1162+ givenHeaders : http.Header {
1163+ HeaderXForwardedProto : []string {"ftp" },
1164+ HeaderXForwardedProtocol : []string {"https" },
1165+ },
1166+ expect : "https" ,
1167+ },
1168+ {
1169+ name : "uses X-Forwarded-Protocol" ,
1170+ givenIsTLS : false ,
1171+ givenHeaders : http.Header {
1172+ HeaderXForwardedProtocol : []string {"https" },
1173+ },
1174+ expect : "https" ,
1175+ },
1176+ {
1177+ name : "X-Forwarded-Proto takes precedence over X-Forwarded-Protocol" ,
1178+ givenIsTLS : false ,
1179+ givenHeaders : http.Header {
1180+ HeaderXForwardedProto : []string {"http" },
1181+ HeaderXForwardedProtocol : []string {"https" },
1182+ },
1183+ expect : "http" ,
1184+ },
1185+ {
1186+ name : "uses X-Forwarded-Ssl on" ,
1187+ givenIsTLS : false ,
1188+ givenHeaders : http.Header {
1189+ HeaderXForwardedSsl : []string {"on" },
1190+ },
1191+ expect : "https" ,
1192+ },
1193+ {
1194+ name : "X-Forwarded-Ssl on is case sensitive" ,
1195+ givenIsTLS : false ,
1196+ givenHeaders : http.Header {
1197+ HeaderXForwardedSsl : []string {"ON" },
1198+ },
1199+ expect : "http" ,
1200+ },
1201+ {
1202+ name : "X-Forwarded-Protocol takes precedence over X-Forwarded-Ssl" ,
1203+ givenIsTLS : false ,
1204+ givenHeaders : http.Header {
1205+ HeaderXForwardedProtocol : []string {"http" },
1206+ HeaderXForwardedSsl : []string {"on" },
1207+ },
1208+ expect : "http" ,
1209+ },
1210+ {
1211+ name : "uses X-Url-Scheme" ,
1212+ givenIsTLS : false ,
1213+ givenHeaders : http.Header {
1214+ HeaderXUrlScheme : []string {"https" },
1215+ },
1216+ expect : "https" ,
1217+ },
1218+ {
1219+ name : "X-Forwarded-Ssl takes precedence over X-Url-Scheme" ,
1220+ givenIsTLS : false ,
1221+ givenHeaders : http.Header {
1222+ HeaderXForwardedSsl : []string {"on" },
1223+ HeaderXUrlScheme : []string {"http" },
1224+ },
1225+ expect : "https" ,
1226+ },
1227+ {
1228+ name : "ignores invalid forwarded headers and falls back to http" ,
1229+ givenIsTLS : false ,
1230+ givenHeaders : http.Header {
1231+ HeaderXForwardedProto : []string {"ftp" },
1232+ HeaderXForwardedProtocol : []string {"smtp" },
1233+ HeaderXForwardedSsl : []string {"off" },
1234+ HeaderXUrlScheme : []string {"file" },
1235+ },
1236+ expect : "http" ,
1237+ },
1238+ {
1239+ name : "ignores empty forwarded proto and uses X-Url-Scheme" ,
1240+ givenIsTLS : false ,
1241+ givenHeaders : http.Header {
1242+ HeaderXForwardedProto : []string {"" },
1243+ HeaderXUrlScheme : []string {"https" },
1244+ },
1245+ expect : "https" ,
11421246 },
11431247 }
11441248
1145- for _ , tt := range tests {
1146- assert .Equal (t , tt .s , tt .c .Scheme ())
1249+ for _ , tc := range testCases {
1250+ t .Run (tc .name , func (t * testing.T ) {
1251+ req := httptest .NewRequest (http .MethodGet , "/" , nil )
1252+ if tc .givenHeaders != nil {
1253+ req .Header = tc .givenHeaders
1254+ }
1255+ c := NewContext (req , nil )
1256+ if tc .givenIsTLS {
1257+ c .request .TLS = & tls.ConnectionState {}
1258+ }
1259+
1260+ assert .Equal (t , tc .expect , c .Scheme ())
1261+ })
11471262 }
11481263}
11491264
0 commit comments