github.com/TeaOSLab/EdgeNode@v1.3.8/internal/nodes/http_request_mismatch.go (about)

     1  // Copyright 2022 Liuxiangchao iwind.liu@gmail.com. All rights reserved. Official site: https://goedge.cn .
     2  
     3  package nodes
     4  
     5  import (
     6  	"github.com/TeaOSLab/EdgeCommon/pkg/nodeutils"
     7  	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs"
     8  	"github.com/TeaOSLab/EdgeCommon/pkg/serverconfigs/firewallconfigs"
     9  	"github.com/TeaOSLab/EdgeNode/internal/ttlcache"
    10  	"github.com/TeaOSLab/EdgeNode/internal/utils"
    11  	"github.com/TeaOSLab/EdgeNode/internal/waf"
    12  	"github.com/iwind/TeaGo/types"
    13  	"net/http"
    14  	"time"
    15  )
    16  
    17  // 域名无匹配情况处理
    18  func (this *HTTPRequest) doMismatch() {
    19  	// 是否为健康检查
    20  	var healthCheckKey = this.RawReq.Header.Get(serverconfigs.HealthCheckHeaderName)
    21  	if len(healthCheckKey) > 0 {
    22  		_, err := nodeutils.Base64DecodeMap(healthCheckKey)
    23  		if err == nil {
    24  			this.writer.WriteHeader(http.StatusOK)
    25  			return
    26  		}
    27  	}
    28  
    29  	// 是否已经在黑名单
    30  	var remoteIP = this.RemoteAddr()
    31  	if waf.SharedIPBlackList.Contains(waf.IPTypeAll, firewallconfigs.FirewallScopeGlobal, 0, remoteIP) {
    32  		this.Close()
    33  		return
    34  	}
    35  
    36  	// 根据配置进行相应的处理
    37  	var nodeConfig = sharedNodeConfig // copy
    38  	if nodeConfig != nil {
    39  		var globalServerConfig = nodeConfig.GlobalServerConfig
    40  		if globalServerConfig != nil && globalServerConfig.HTTPAll.MatchDomainStrictly {
    41  			var statusCode = 404
    42  			var httpAllConfig = globalServerConfig.HTTPAll
    43  			var mismatchAction = httpAllConfig.DomainMismatchAction
    44  
    45  			if mismatchAction != nil && mismatchAction.Options != nil {
    46  				var mismatchStatusCode = mismatchAction.Options.GetInt("statusCode")
    47  				if mismatchStatusCode > 0 && mismatchStatusCode >= 100 && mismatchStatusCode < 1000 {
    48  					statusCode = mismatchStatusCode
    49  				}
    50  			}
    51  
    52  			// 是否正在访问IP
    53  			if globalServerConfig.HTTPAll.NodeIPShowPage && utils.IsWildIP(this.ReqHost) {
    54  				this.writer.statusCode = statusCode
    55  				var contentHTML = this.Format(globalServerConfig.HTTPAll.NodeIPPageHTML)
    56  				this.writer.Header().Set("Content-Type", "text/html; charset=utf-8")
    57  				this.writer.Header().Set("Content-Length", types.String(len(contentHTML)))
    58  				this.writer.WriteHeader(statusCode)
    59  				_, _ = this.writer.WriteString(contentHTML)
    60  				return
    61  			}
    62  
    63  			// 检查cc
    64  			// TODO 可以在管理端配置是否开启以及最多尝试次数
    65  			// 要考虑到服务在切换集群时,域名未生效状态时,用户访问的仍然是老集群中的节点,就会产生找不到域名的情况
    66  			if len(remoteIP) > 0 {
    67  				const maxAttempts = 100
    68  				if ttlcache.SharedInt64Cache.IncreaseInt64("MISMATCH_DOMAIN:"+remoteIP, int64(1), time.Now().Unix()+60, false) > maxAttempts {
    69  					// 在加入之前再次检查黑名单
    70  					if !waf.SharedIPBlackList.Contains(waf.IPTypeAll, firewallconfigs.FirewallScopeGlobal, 0, remoteIP) {
    71  						waf.SharedIPBlackList.Add(waf.IPTypeAll, firewallconfigs.FirewallScopeGlobal, 0, remoteIP, time.Now().Unix()+3600)
    72  					}
    73  				}
    74  			}
    75  
    76  			// 处理当前连接
    77  			if mismatchAction != nil {
    78  				if mismatchAction.Code == serverconfigs.DomainMismatchActionPage {
    79  					if mismatchAction.Options != nil {
    80  						this.writer.statusCode = statusCode
    81  						var contentHTML = this.Format(mismatchAction.Options.GetString("contentHTML"))
    82  						this.writer.Header().Set("Content-Type", "text/html; charset=utf-8")
    83  						this.writer.Header().Set("Content-Length", types.String(len(contentHTML)))
    84  						this.writer.WriteHeader(statusCode)
    85  						_, _ = this.writer.Write([]byte(contentHTML))
    86  					} else {
    87  						http.Error(this.writer, "404 page not found: '"+this.URL()+"'", http.StatusNotFound)
    88  					}
    89  					return
    90  				}
    91  
    92  				if mismatchAction.Code == serverconfigs.DomainMismatchActionRedirect {
    93  					var url = this.Format(mismatchAction.Options.GetString("url"))
    94  					if len(url) > 0 {
    95  						httpRedirect(this.writer, this.RawReq, url, http.StatusTemporaryRedirect)
    96  					} else {
    97  						http.Error(this.writer, "404 page not found: '"+this.URL()+"'", http.StatusNotFound)
    98  					}
    99  					return
   100  				}
   101  
   102  				if mismatchAction.Code == serverconfigs.DomainMismatchActionClose {
   103  					http.Error(this.writer, "404 page not found: '"+this.URL()+"'", http.StatusNotFound)
   104  					this.Close()
   105  					return
   106  				}
   107  			}
   108  
   109  			http.Error(this.writer, "404 page not found: '"+this.URL()+"'", http.StatusNotFound)
   110  			this.Close()
   111  			return
   112  		}
   113  	}
   114  
   115  	http.Error(this.writer, "404 page not found: '"+this.URL()+"'", http.StatusNotFound)
   116  }