diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..1746c97c9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +debug \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..c23774cdd --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,17 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${fileDirname}", + "env": {}, + "args": [] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..5d3f8f78f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "go.formatTool": "goimports", + "go.useLanguageServer": true, + "go.alternateTools": { + "go-langserver": "gopls" + }, + "go.languageServerExperimentalFeatures": { + "format": false, + "autoComplete": true + } +} diff --git a/down/down.go b/down/down.go new file mode 100644 index 000000000..66fb9e810 --- /dev/null +++ b/down/down.go @@ -0,0 +1,94 @@ +package down + +import ( + "bytes" + "fmt" + "io" + "io/ioutil" + "mime" + "net/http" + "os" + "strconv" + "strings" +) + +// Resolve 解析下载请求 +func Resolve(request *Request) (*Response, error) { + httpRequest, err := http.NewRequest(strings.ToUpper(request.Method), request.URL, nil) + if err != nil { + return nil, err + } + /* for k, v := range request.Header { + httpRequest.Header.Add(k, v) + } */ + httpClient := &http.Client{} + response, err := httpClient.Do(httpRequest) + if err != nil { + return nil, err + } + if response.StatusCode != 200 && response.StatusCode != 206 { + fmt.Println(response.Header) + body, _ := ioutil.ReadAll(response.Body) + fmt.Println(string(body)) + return nil, fmt.Errorf("Response status error:%d", response.StatusCode) + } + + ret := &Response{} + + //解析文件名 + contentDisposition := response.Header.Get("Content-Disposition") + if contentDisposition != "" { + _, params, _ := mime.ParseMediaType(contentDisposition) + filename := params["filename"] + if filename != "" { + ret.Name = filename + } + } + if ret.Name == "" { + + } + //解析文件大小 + contentLength := response.Header.Get("Content-Length") + if contentLength != "" { + ret.size, _ = strconv.ParseInt(contentLength, 10, 64) + } + //判断是否支持分段下载 + ret.Partial = ret.size > 0 && response.StatusCode == 206 + return ret, nil +} + +// Down 下载 +func Down(request *Request) { + httpRequest, err := http.NewRequest(request.Method, request.URL, bytes.NewReader(request.content)) + if err != nil { + fmt.Println("create http request error") + return + } + for k, v := range request.Header { + httpRequest.Header.Add(k, v) + } + httpClient := &http.Client{} + response, err := httpClient.Do(httpRequest) + if err != nil { + fmt.Printf("do http request error:%s\n", err) + return + } + if response.StatusCode >= 200 && response.StatusCode < 300 { + _, params, _ := mime.ParseMediaType(response.Header.Get("Content-Disposition")) + filename := params["filename"] + if len(filename) > 0 { + fmt.Printf("filename:%s\n", filename) + } + } + + fmt.Printf("response status:%d %s\n", response.StatusCode, response.Status) + fmt.Printf("response heads:%v\n", response.Header) + file, err := os.Create("test.txt") + if err != nil { + fmt.Println("create file error") + return + } + defer file.Close() + fmt.Println("file close") + io.Copy(file, response.Body) +} diff --git a/down/down_test.go b/down/down_test.go new file mode 100644 index 000000000..a4bb1e9bc --- /dev/null +++ b/down/down_test.go @@ -0,0 +1,87 @@ +package down + +import ( + "reflect" + "testing" +) + +func TestDown(t *testing.T) { + type args struct { + request *Request + } + tests := []struct { + name string + args args + }{ + { + "readme", + args{ + &Request{ + "get", + "https://raw.githubusercontent.com/proxyee-down-org/proxyee-down/master/README.md", + map[string]string{ + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", + "Host": "raw.githubusercontent.com", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", + "Cache-Control": "no-cache", + "Connection": "keep-alive", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36", + }, + nil, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + Down(tt.args.request) + }) + } +} + +func TestResolve(t *testing.T) { + type args struct { + request *Request + } + tests := []struct { + name string + args args + want *Response + wantErr bool + }{ + { + "proxyee-down", + args{ + &Request{ + "get", + "https://github.com/proxyee-down-org/proxyee-down/releases/download/3.4/proxyee-down-main.jar", + map[string]string{ + "Host": "github.com", + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36", + "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8", + "Referer": "https://github.com/proxyee-down-org/proxyee-down/releases", + "Accept-Encoding": "gzip, deflate, br", + "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8", + }, + nil, + }, + }, + &Response{"proxyee-down-main.jar", 30159703, false}, + false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := Resolve(tt.args.request) + if (err != nil) != tt.wantErr { + t.Errorf("Resolve() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("Resolve() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/down/request.go b/down/request.go new file mode 100644 index 000000000..cafe03f95 --- /dev/null +++ b/down/request.go @@ -0,0 +1,8 @@ +package down + +type Request struct { + Method string + URL string + Header map[string]string + content []byte +} diff --git a/down/response.go b/down/response.go new file mode 100644 index 000000000..569c010e3 --- /dev/null +++ b/down/response.go @@ -0,0 +1,7 @@ +package down + +type Response struct { + Name string + size int64 + Partial bool +} diff --git a/go.mod b/go.mod new file mode 100644 index 000000000..1d25c50c4 --- /dev/null +++ b/go.mod @@ -0,0 +1,8 @@ +module pdown-core + +go 1.12 + +require ( + github.com/karalabe/xgo v0.0.0-20190301120235-2d6d1848fb02 // indirect + github.com/zserge/webview v0.0.0-20190123072648-16c93bcaeaeb +) diff --git a/go.sum b/go.sum new file mode 100644 index 000000000..d9780b231 --- /dev/null +++ b/go.sum @@ -0,0 +1,4 @@ +github.com/karalabe/xgo v0.0.0-20190301120235-2d6d1848fb02 h1:nI4Q7WQDcng8eRmi8bRP1SXlJIYLkgdgR7ZhJuzPbhs= +github.com/karalabe/xgo v0.0.0-20190301120235-2d6d1848fb02/go.mod h1:iYGcTYIPUvEWhFo6aKUuLchs+AV4ssYdyuBbQJZGcBk= +github.com/zserge/webview v0.0.0-20190123072648-16c93bcaeaeb h1:zVjnyZIM7UtkG3dNckiudIm+TUHkZqi5xlVQPd3J6/c= +github.com/zserge/webview v0.0.0-20190123072648-16c93bcaeaeb/go.mod h1:a1CV8KR4Dd1eP2g+mEijGOp+HKczwdKHWyx0aPHKvo4= diff --git a/main.go b/main.go new file mode 100644 index 000000000..02043b31f --- /dev/null +++ b/main.go @@ -0,0 +1,9 @@ +package main + +import "github.com/zserge/webview" + +func main() { + // Open wikipedia in a 800x600 resizable window + webview.Open("Minimal webview example", + "https://www.baidu.com", 800, 600, true) +} \ No newline at end of file