├── hosts ├── README.md └── main.go /hosts: -------------------------------------------------------------------------------- 1 | # GitHub Start 2 | 140.82.112.4 github.com 3 | 140.82.114.3 gist.github.com 4 | 185.199.110.153 assets-cdn.github.com 5 | 185.199.111.133 raw.githubusercontent.com 6 | 185.199.109.133 gist.githubusercontent.com 7 | 185.199.111.133 cloud.githubusercontent.com 8 | 185.199.111.133 camo.githubusercontent.com 9 | 185.199.111.133 avatars.githubusercontent.com 10 | 185.199.108.133 avatars0.githubusercontent.com 11 | 185.199.108.133 avatars1.githubusercontent.com 12 | 185.199.111.133 avatars2.githubusercontent.com 13 | 185.199.110.133 avatars3.githubusercontent.com 14 | 185.199.111.133 avatars4.githubusercontent.com 15 | 185.199.108.133 avatars5.githubusercontent.com 16 | 185.199.109.133 avatars6.githubusercontent.com 17 | 185.199.111.133 avatars7.githubusercontent.com 18 | 185.199.111.133 avatars8.githubusercontent.com 19 | 185.199.110.154 github.githubassets.com 20 | # GitHub End 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## github 域名国内加速 2 | 3 | ```bash 4 | # updated by 20210301 5 | # GitHub Start 6 | 140.82.112.4 github.com 7 | 140.82.114.4 gist.github.com 8 | 185.199.111.153 assets-cdn.github.com 9 | 185.199.111.133 raw.githubusercontent.com 10 | 185.199.109.133 gist.githubusercontent.com 11 | 185.199.111.133 cloud.githubusercontent.com 12 | 185.199.111.133 camo.githubusercontent.com 13 | 185.199.108.133 avatars.githubusercontent.com 14 | 185.199.111.133 avatars0.githubusercontent.com 15 | 185.199.111.133 avatars1.githubusercontent.com 16 | 185.199.111.133 avatars2.githubusercontent.com 17 | 185.199.111.133 avatars3.githubusercontent.com 18 | 185.199.110.133 avatars4.githubusercontent.com 19 | 185.199.110.133 avatars5.githubusercontent.com 20 | 185.199.111.133 avatars6.githubusercontent.com 21 | 185.199.111.133 avatars7.githubusercontent.com 22 | 185.199.109.133 avatars8.githubusercontent.com 23 | 185.199.110.154 github.githubassets.com 24 | # GitHub End 25 | 26 | ``` 27 | 28 | 如何使用: 29 | ```bash 30 | go run main.go 31 | 32 | # 可以选择 3 种方式保存 33 | #1. Create the host file to current directory (default)") 34 | #2. Append the host to system host file in linux (/etc/hosts)") 35 | #3. Append the host to system host file in windows (/mnt/c/Windows/System32/drivers/etc/hosts)") 36 | ``` 37 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "errors" 6 | "fmt" 7 | "io" 8 | "io/ioutil" 9 | "net/http" 10 | "os" 11 | "strings" 12 | ) 13 | 14 | var domains = []string{ 15 | "github.com", 16 | "gist.github.com", 17 | "assets-cdn.github.com", 18 | "raw.githubusercontent.com", 19 | "gist.githubusercontent.com", 20 | "cloud.githubusercontent.com", 21 | "camo.githubusercontent.com", 22 | "avatars.githubusercontent.com", 23 | "avatars0.githubusercontent.com", 24 | "avatars1.githubusercontent.com", 25 | "avatars2.githubusercontent.com", 26 | "avatars3.githubusercontent.com", 27 | "avatars4.githubusercontent.com", 28 | "avatars5.githubusercontent.com", 29 | "avatars6.githubusercontent.com", 30 | "avatars7.githubusercontent.com", 31 | "avatars8.githubusercontent.com", 32 | "github.githubassets.com", 33 | } 34 | 35 | var startTag = "# GitHub Start\r\n" 36 | var endTag = "# GitHub End\r\n" 37 | 38 | func main() { 39 | var mode int 40 | fmt.Println("1. Create the host file to current directory (default)") 41 | fmt.Println("2. Append the host to system host file in linux (/etc/hosts)") 42 | fmt.Println("3. Append the host to system host file in windows (/mnt/c/Windows/System32/drivers/etc/hosts)") 43 | for { 44 | fmt.Print("Choose the mode [1-3]: ") 45 | fmt.Scanln(&mode) 46 | if mode >= 0 && mode <= 3 { 47 | break 48 | } 49 | } 50 | filePath := "" 51 | if mode == 1 || mode == 0 { 52 | filePath = "hosts" 53 | WriteHostToFile("", filePath) 54 | return 55 | } else if mode == 2 { 56 | filePath = "/etc/hosts" 57 | } else { 58 | filePath = "/mnt/c/Windows/System32/drivers/etc/hosts" 59 | } 60 | filePathBak := filePath + "_bak" 61 | 62 | // backup 63 | Copy(filePathBak, filePath) 64 | 65 | // read content 66 | in, err := os.Open(filePath) 67 | if err != nil { 68 | fmt.Println("open file fail:", err) 69 | os.Exit(-1) 70 | } 71 | defer in.Close() 72 | reader := bufio.NewReader(in) 73 | var strSlice []string 74 | line := 0 75 | startLine := 0 76 | endLine := 0 77 | for { 78 | line = line + 1 79 | str, err := reader.ReadString('\n') 80 | if err == io.EOF { 81 | break 82 | } 83 | strSlice = append(strSlice, str) 84 | if str == startTag { 85 | startLine = line 86 | } else if str == endTag { 87 | endLine = line 88 | } 89 | } 90 | if startLine > 0 && endLine > 0 { 91 | strSlice = append(strSlice[:startLine-1], strSlice[endLine:]...) 92 | } 93 | str := strings.Join(strSlice, "") 94 | 95 | // write content 96 | WriteHostToFile(str, filePath) 97 | } 98 | 99 | type HostChan struct { 100 | Domain string 101 | Ip string 102 | Err error 103 | } 104 | 105 | func WriteHostToFile(str string, filePath string) { 106 | str += startTag 107 | ch := make(chan *HostChan) 108 | for _, v := range domains { 109 | go httpPostForm(v, ch) 110 | } 111 | fmt.Println("================\nstart get host:\n================") 112 | hostMap := make(map[string]string) 113 | for range domains { 114 | chRec := <-ch 115 | if chRec.Err != nil { 116 | fmt.Println(chRec.Err.Error() + " " + chRec.Domain) 117 | return 118 | } 119 | hostMap[chRec.Domain] = chRec.Ip 120 | fmt.Println(chRec.Ip + " " + chRec.Domain) 121 | } 122 | for _, v := range domains { 123 | str += hostMap[v] + " " + v + "\r\n" 124 | } 125 | 126 | str += endTag 127 | out, err := os.OpenFile(filePath, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0666) 128 | if err != nil { 129 | fmt.Println("open file fail:", err) 130 | return 131 | } 132 | defer out.Close() 133 | writer := bufio.NewWriter(out) 134 | writer.WriteString(str) 135 | writer.Flush() 136 | fmt.Println("================\ndone\n================") 137 | } 138 | 139 | func Copy(dstName, srcName string) (written int64, err error) { 140 | src, err := os.Open(srcName) 141 | if err != nil { 142 | return 143 | } 144 | defer src.Close() 145 | dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, 0644) 146 | if err != nil { 147 | return 148 | } 149 | defer dst.Close() 150 | return io.Copy(dst, src) 151 | } 152 | 153 | func httpPostForm(domain string, ch chan<- *HostChan) { 154 | client := &http.Client{} 155 | req, err := http.NewRequest("POST", "https://www.ipaddress.com/ip-lookup", strings.NewReader("host="+domain)) 156 | req.Header.Set("Content-Type", "application/x-www-form-urlencoded") 157 | req.Header.Set("UserAgent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36") 158 | resp, err := client.Do(req) 159 | if err != nil { 160 | ch <- &HostChan{Domain: domain, Err: err} 161 | return 162 | } 163 | defer resp.Body.Close() 164 | body, err := ioutil.ReadAll(resp.Body) 165 | if err != nil { 166 | ch <- &HostChan{Domain: domain, Err: err} 167 | return 168 | } 169 | shortStr := string(body)[12000:30000] 170 | index := strings.Index(shortStr, " ("+domain+")") 171 | var res string 172 | if index > 0 { 173 | strStart := "IP Lookup : " 174 | indexStart := strings.Index(shortStr, strStart) 175 | res = shortStr[indexStart+len(strStart) : index] 176 | } else { 177 | strStart := " 0 { 181 | res = shortStr[indexStart+len(strStart) : indexStart+len(strStart)+indexEnd] 182 | } else { 183 | ch <- &HostChan{Domain: domain, Err: errors.New("get indexEnd error")} 184 | } 185 | } 186 | if res == "" { 187 | ch <- &HostChan{Domain: domain, Err: errors.New("empty host")} 188 | return 189 | } 190 | ch <- &HostChan{Domain: domain, Ip: res, Err: nil} 191 | return 192 | } 193 | --------------------------------------------------------------------------------