■ ■ ■ ■ ■ ■
pkg/protocols/http/http.go
| skipped 31 lines |
32 | 32 | | MaxRedirect int32 |
33 | 33 | | DialTimeout int32 |
34 | 34 | | UserAgent string |
| 35 | + | Options *config.Options |
| 36 | + | Target string |
35 | 37 | | } |
36 | 38 | | |
37 | 39 | | func Init(options *config.Options) { |
| skipped 122 lines |
160 | 162 | | // 新增功能:HTTP请求超时,自动重连机制(3次,每次累加超时时间) |
161 | 163 | | repeatCount := 0 |
162 | 164 | | for { |
| 165 | + | fc.Options.TargetLive.AddRequestTarget(fmt.Sprintf("%s://%s%s", protoRequest.Url.Scheme, protoRequest.Url.Host, protoRequest.Url.Path), 1) |
| 166 | + | if fc.Options.TargetLive.HandleTargetLive(fc.Target, -1) == -1 { |
| 167 | + | return errors.New("target nolive") |
| 168 | + | } |
| 169 | + | // starttime := time.Now().Second() |
163 | 170 | | if rule.Request.FollowRedirects { |
164 | 171 | | maxrd := 3 // follow redirects default 3 |
165 | 172 | | if fc.MaxRedirect > 0 { |
| skipped 10 lines |
176 | 183 | | } |
177 | 184 | | err = F.DoTimeout(fastReq, fastResp, time.Second*time.Duration(dialtimeout)) |
178 | 185 | | } |
| 186 | + | fc.Options.TargetLive.AddRequestTarget(fmt.Sprintf("%s://%s%s", protoRequest.Url.Scheme, protoRequest.Url.Host, protoRequest.Url.Path), 2) |
| 187 | + | // endtime := time.Now().Second() |
| 188 | + | // if endtime-starttime > 20 { |
| 189 | + | // fmt.Println(log.LogColor.Vulner(httpRequest.URL, fastResp.StatusCode(), endtime-starttime)) |
| 190 | + | // } |
179 | 191 | | if err != nil { |
180 | 192 | | errName, known := httpConnError(err) |
181 | 193 | | if known { |
| skipped 2 lines |
184 | 196 | | log.Log().Error(fmt.Sprintf("ERR conn failure: %s %s\n", errName, err)) |
185 | 197 | | } |
186 | 198 | | if errName == "timeout" { |
187 | | - | repeatCount++ |
| 199 | + | repeatCount += 1 |
188 | 200 | | if repeatCount > 1 { |
189 | 201 | | break |
190 | 202 | | } |
| skipped 418 lines |
609 | 621 | | fastResp := fasthttp.AcquireResponse() |
610 | 622 | | defer fasthttp.ReleaseResponse(fastResp) |
611 | 623 | | |
612 | | - | // currd := 0 |
613 | | - | // for { |
614 | | - | // currd++ |
615 | | - | // err = F.DoTimeout(fastReq, fastResp, time.Second*time.Duration(6)) |
616 | | - | // statusCode := fastResp.Header.StatusCode() |
617 | | - | // if statusCode != fasthttp.StatusMovedPermanently && |
618 | | - | // statusCode != fasthttp.StatusFound && |
619 | | - | // statusCode != fasthttp.StatusSeeOther && |
620 | | - | // statusCode != fasthttp.StatusTemporaryRedirect && |
621 | | - | // statusCode != fasthttp.StatusPermanentRedirect { |
622 | | - | // break |
623 | | - | // } |
624 | | - | |
625 | | - | // location := fastResp.Header.PeekBytes(strLocation) |
626 | | - | // if len(location) == 0 { |
627 | | - | // break |
628 | | - | // } |
629 | | - | |
630 | | - | // u := fastReq.URI() |
631 | | - | // u.UpdateBytes(location) |
632 | | - | |
633 | | - | // if currd >= 3 { |
634 | | - | // break |
635 | | - | // } |
636 | | - | // } |
637 | | - | // fasthttp bug, https://github.com/valyala/fasthttp/issues/1361 |
638 | 624 | | err = F.DoRedirects(fastReq, fastResp, 3) |
639 | 625 | | |
640 | 626 | | newheader := make(map[string][]string) |
| skipped 59 lines |
700 | 686 | | } |
701 | 687 | | |
702 | 688 | | return []byte(fastReq.String()), fastResp.Body(), []byte(fastResp.Header.String()), fastResp.StatusCode(), urlType, err |
| 689 | + | } |
| 690 | + | |
| 691 | + | // 返回 -1,表示 request 请求失败(无法访问) |
| 692 | + | func CheckTargetHttps(target string) (string, int) { |
| 693 | + | if strings.HasPrefix(target, "http://") || strings.HasPrefix(target, "https://") { |
| 694 | + | statusCode, _, err := fasthttp.Get(nil, target) |
| 695 | + | if err == nil { |
| 696 | + | return target, statusCode |
| 697 | + | } |
| 698 | + | return target, -1 |
| 699 | + | } |
| 700 | + | |
| 701 | + | u, err := url.Parse("http://" + target) |
| 702 | + | if err != nil { |
| 703 | + | return target, -1 |
| 704 | + | } |
| 705 | + | |
| 706 | + | port := u.Port() |
| 707 | + | |
| 708 | + | switch { |
| 709 | + | case port == "80" || len(port) == 0: |
| 710 | + | statusCode, _, err := fasthttp.Get(nil, "http://"+target) |
| 711 | + | if err == nil { |
| 712 | + | return "http://" + target, statusCode |
| 713 | + | } |
| 714 | + | return target, -1 |
| 715 | + | |
| 716 | + | case port == "443": |
| 717 | + | statusCode, _, err := fasthttp.Get(nil, "https://"+target) |
| 718 | + | if err == nil { |
| 719 | + | return "https://" + target, statusCode |
| 720 | + | } |
| 721 | + | return target, -1 |
| 722 | + | } |
| 723 | + | |
| 724 | + | statusCode, resp, err := fasthttp.Get(nil, "http://"+target) |
| 725 | + | if err == nil { |
| 726 | + | if bytes.Contains(resp, []byte("<title>400 The plain HTTP request was sent to HTTPS port</title>")) { |
| 727 | + | return "https://" + target, statusCode |
| 728 | + | } |
| 729 | + | return "http://" + target, statusCode |
| 730 | + | } |
| 731 | + | |
| 732 | + | statusCode, _, err = fasthttp.Get(nil, "https://"+target) |
| 733 | + | if err == nil { |
| 734 | + | return "https://" + target, statusCode |
| 735 | + | } |
| 736 | + | |
| 737 | + | return target, -1 |
| 738 | + | } |
| 739 | + | |
| 740 | + | // 返回 -1,表示 request 请求失败(无法访问) |
| 741 | + | func CheckTargetHttps2(target string) (string, int) { |
| 742 | + | if strings.HasPrefix(target, "http://") || strings.HasPrefix(target, "https://") { |
| 743 | + | _, statusCode, err := GetTimeout(target, 6) |
| 744 | + | if err == nil { |
| 745 | + | return target, statusCode |
| 746 | + | } |
| 747 | + | return target, -1 |
| 748 | + | } |
| 749 | + | |
| 750 | + | u, err := url.Parse("http://" + target) |
| 751 | + | if err != nil { |
| 752 | + | return target, -1 |
| 753 | + | } |
| 754 | + | |
| 755 | + | port := u.Port() |
| 756 | + | |
| 757 | + | switch { |
| 758 | + | case port == "80" || len(port) == 0: |
| 759 | + | _, statusCode, err := GetTimeout("http://"+target, 6) |
| 760 | + | if err == nil { |
| 761 | + | return "http://" + target, statusCode |
| 762 | + | } |
| 763 | + | return target, -1 |
| 764 | + | |
| 765 | + | case port == "443": |
| 766 | + | _, statusCode, err := GetTimeout("https://"+target, 6) |
| 767 | + | if err == nil { |
| 768 | + | return "https://" + target, statusCode |
| 769 | + | } |
| 770 | + | return target, -1 |
| 771 | + | } |
| 772 | + | |
| 773 | + | resp, statusCode, err := GetTimeout("http://"+target, 6) |
| 774 | + | if err == nil { |
| 775 | + | if bytes.Contains(resp, []byte("<title>400 The plain HTTP request was sent to HTTPS port</title>")) { |
| 776 | + | return "https://" + target, statusCode |
| 777 | + | } |
| 778 | + | return "http://" + target, statusCode |
| 779 | + | } |
| 780 | + | |
| 781 | + | _, statusCode, err = GetTimeout("https://"+target, 6) |
| 782 | + | if err == nil { |
| 783 | + | return "https://" + target, statusCode |
| 784 | + | } |
| 785 | + | |
| 786 | + | return target, -1 |
703 | 787 | | } |
704 | 788 | | |
705 | 789 | | // target is not alive if return value is none http(s) else is alive. |
| skipped 225 lines |