package rewrite /* rewrite.go This script handle the rewrite logic for custom headers */ import ( "strconv" "imuslab.com/zoraxy/mod/dynamicproxy/permissionpolicy" ) // SplitInboundOutboundHeaders split user defined headers into upstream and downstream headers // return upstream header and downstream header key-value pairs // if the header is expected to be deleted, the value will be set to empty string func SplitUpDownStreamHeaders(rewriteOptions *HeaderRewriteOptions) ([][]string, [][]string) { if len(rewriteOptions.UserDefinedHeaders) == 0 && rewriteOptions.HSTSMaxAge == 0 && !rewriteOptions.EnablePermissionPolicyHeader { //Early return if there are no defined headers return [][]string{}, [][]string{} } //Use pre-allocation for faster performance //Downstream +2 for Permission Policy and HSTS upstreamHeaders := make([][]string, len(rewriteOptions.UserDefinedHeaders)) downstreamHeaders := make([][]string, len(rewriteOptions.UserDefinedHeaders)+2) upstreamHeaderCounter := 0 downstreamHeaderCounter := 0 //Sort the headers into upstream or downstream for _, customHeader := range rewriteOptions.UserDefinedHeaders { thisHeaderSet := make([]string, 2) thisHeaderSet[0] = customHeader.Key thisHeaderSet[1] = customHeader.Value if customHeader.IsRemove { //Prevent invalid config thisHeaderSet[1] = "" } //Assign to slice if customHeader.Direction == HeaderDirection_ZoraxyToUpstream { upstreamHeaders[upstreamHeaderCounter] = thisHeaderSet upstreamHeaderCounter++ } else if customHeader.Direction == HeaderDirection_ZoraxyToDownstream { downstreamHeaders[downstreamHeaderCounter] = thisHeaderSet downstreamHeaderCounter++ } } //Check if the endpoint require HSTS headers if rewriteOptions.HSTSMaxAge > 0 { if rewriteOptions.HSTSIncludeSubdomains { //Endpoint listening domain includes wildcards. downstreamHeaders[downstreamHeaderCounter] = []string{"Strict-Transport-Security", "max-age=" + strconv.Itoa(int(rewriteOptions.HSTSMaxAge)) + "; includeSubdomains"} } else { downstreamHeaders[downstreamHeaderCounter] = []string{"Strict-Transport-Security", "max-age=" + strconv.Itoa(int(rewriteOptions.HSTSMaxAge))} } downstreamHeaderCounter++ } //Check if the endpoint require Permission Policy if rewriteOptions.EnablePermissionPolicyHeader { var usingPermissionPolicy *permissionpolicy.PermissionsPolicy if rewriteOptions.PermissionPolicy != nil { //Custom permission policy usingPermissionPolicy = rewriteOptions.PermissionPolicy } else { //Permission policy is enabled but not customized. Use default usingPermissionPolicy = permissionpolicy.GetDefaultPermissionPolicy() } downstreamHeaders[downstreamHeaderCounter] = usingPermissionPolicy.ToKeyValueHeader() downstreamHeaderCounter++ } return upstreamHeaders, downstreamHeaders }