Skip to content

Instantly share code, notes, and snippets.

@jackey
Created March 5, 2017 06:32
Show Gist options
  • Save jackey/71e5864ad9f45cf3d5f7c0dbe27c1459 to your computer and use it in GitHub Desktop.
Save jackey/71e5864ad9f45cf3d5f7c0dbe27c1459 to your computer and use it in GitHub Desktop.
site clone with golang
package main
import (
"log"
"io"
"strings"
"net/http"
_ "bufio"
"net/url"
"io/ioutil"
"os"
"path/filepath"
)
type MyHandler struct {
}
var sourceDomain string = ""
var downloadFolder string = ""
func copyHeaders(dst, src http.Header) {
for k, _ := range dst {
dst.Del(k)
}
for k, vs := range src {
for _, v := range vs {
dst.Add(k, v)
}
}
}
func (handler *MyHandler) fakeIt(uri string, req *http.Request) (res *http.Response){
url := strings.Join([]string{sourceDomain, uri}, "")
method := req.Method
formData := req.PostForm
log.Printf("Fetch from %s and method %s and data %s", url, method, formData.Encode())
if method == "GET" {
client := &http.Client{}
resp, _ := client.Get(url)
return resp
} else if method == "POST" {
// TODO::
log.Printf("暂时不支持 POST")
}
return nil
}
func (handler *MyHandler) generateFileHandler(uri string, req *http.Request) (w *os.File){
domainName := strings.Replace(sourceDomain, "https://", "", 1)
log.Printf("Domain name is %s", domainName)
downloadDir := filepath.Join(downloadFolder, domainName)
err := os.MkdirAll(downloadDir, 0766)
if err != nil {
log.Fatal("创建主目录失败")
}
log.Printf("创建主目录成功")
// 根据uri 来创建目录
URLObj, _ := url.Parse(uri)
simplerURI := URLObj.RequestURI()
subDir := simplerURI[1:]
// 检查是不是 HTML 文件
dotIndex := strings.LastIndex(simplerURI, ".")
if dotIndex == -1 {
subDir = strings.Join([]string{subDir, "html"}, ".")
}
downloadFileTo := filepath.Join(downloadDir, subDir)
log.Printf("下载到: %s", downloadFileTo)
downloadFileDir := filepath.Dir(downloadFileTo)
err = os.MkdirAll(downloadFileDir, 0777)
if err != nil {
log.Printf("创建下载目录 %s 失败 %v", downloadFileDir, err)
}
var f *os.File
if _, err = os.Stat(downloadFileTo); os.IsNotExist(err) {
f, err = os.Create(downloadFileTo)
if err != nil {
log.Printf("创建 %s 文件失败 %v ", downloadFileTo, err)
}
} else {
f, _ = os.Open(downloadFileTo)
log.Printf("文件已存在 %s ", downloadFileTo)
}
return f
}
// HTTP 服务器
func (handler *MyHandler) ServeHTTP (w http.ResponseWriter, req *http.Request) {
uri := req.URL.String()
resp := handler.fakeIt(uri, req)
log.Printf("Status: %s ", resp.Status)
copyHeaders(w.Header(), resp.Header)
w.WriteHeader(resp.StatusCode)
fileHandler := handler.generateFileHandler(uri, req)
contentBodyBytes, _ := ioutil.ReadAll(resp.Body)
contentStr := string(contentBodyBytes)
if uri == "/activity" {
changeContentStr := strings.Replace(contentStr, "./build", "/activity/build", -1)
contentBodyBytes = []byte(changeContentStr)
}
fileHandler.Write(contentBodyBytes)
fileHandler.Seek(0, 0)
nr, err := io.Copy(w, fileHandler)
log.Printf("Content copied %v and error is %v (the response body content length is %d )", nr, err, resp.ContentLength)
//defer resp.Body.Close()
defer fileHandler.Close()
}
func main() {
handler := MyHandler{}
log.Printf("%s", "Server Listen on :8182")
http.ListenAndServe(":8182", &handler)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment