From 5f40867b2bea010de393cd23eb0e6ed8b68190c5 Mon Sep 17 00:00:00 2001 From: "Yoshihide Taniguchi (ravelll)" Date: Wed, 16 May 2018 16:40:12 +0900 Subject: [PATCH] =?UTF-8?q?[wip]=20=E4=B8=A6=E5=88=97=E3=81=A7=E3=81=AF?= =?UTF-8?q?=E3=81=AA=E3=81=84=E3=81=91=E3=81=A9=E5=88=86=E5=89=B2DL?= =?UTF-8?q?=E3=82=92=E3=81=99=E3=82=8B=E3=81=A8=E3=81=93=E3=82=8D=E3=81=BE?= =?UTF-8?q?=E3=81=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kadai3/ravelll/2/main.go | 108 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 kadai3/ravelll/2/main.go diff --git a/kadai3/ravelll/2/main.go b/kadai3/ravelll/2/main.go new file mode 100644 index 0000000..3e0fc83 --- /dev/null +++ b/kadai3/ravelll/2/main.go @@ -0,0 +1,108 @@ +package main + +import ( + "fmt" + "io/ioutil" + "log" + "net/http" + "net/url" + "os" + "path/filepath" +) + +const ( + BatchByteSize = 500 +) + +func main() { + contentURL := os.Args[1] + os.Exit(download(contentURL)) +} + +func checkContentLength(contentURL string) (int64, error) { + req, err := http.Head(contentURL) + if err != nil { + return 0, err + } + + return req.ContentLength, nil +} + +func rangeHeaderVal(i int, partNum int) string { + if i == partNum-1 { + return fmt.Sprintf( + "bytes=%d-", i*BatchByteSize) + } + + return fmt.Sprintf( + "bytes=%d-%d", i*BatchByteSize, (i+1)*BatchByteSize-1) +} + +func request(contentURL string) (string, error) { + partedBody := make([]string, 0, 20) + + contentLength, err := checkContentLength(contentURL) + if err != nil { + return "", err + } + + partNum := int((contentLength / BatchByteSize) + 1) + + for i := 0; partNum > i; i++ { + client := http.Client{} + req, err := http.NewRequest("GET", contentURL, nil) + req.Header.Add("Range", rangeHeaderVal(i, partNum)) + downloaded, err := client.Do(req) + respBody, err := ioutil.ReadAll(downloaded.Body) + if err != nil { + return "", err + } + + partedBody = append(partedBody, string(respBody)) + } + + var body string + + for i := 0; i < len(partedBody); i++ { + body += partedBody[i] + } + + return body, nil +} + +func getFilename(contentURL string) (string, error) { + parsed, err := url.Parse(contentURL) + if err != nil { + log.Fatal(err) + return "", err + } + _, filename := filepath.Split(parsed.EscapedPath()) + return filename, nil +} + +func download(contentURL string) int { + if contentURL == "" { + fmt.Println("Error: no url specified.") + return 1 + } + + filename, filenameErr := getFilename(contentURL) + if filenameErr != nil { + return 1 + } + + responseBody, reqErr := request(contentURL) + if reqErr != nil { + return 1 + } + + output, createErr := os.Create(filename) + defer output.Close() + if createErr != nil { + return 1 + } + + output.WriteString(responseBody) + + return 0 +}