Created
May 12, 2018 09:44
-
-
Save slaykovsky/358c9acd3516b7c10340fc63c1453e31 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 8bc692c33ec2e324e4400576d105495fa33f2ba9 Mon Sep 17 00:00:00 2001 | |
From: Alexey Slaykovsky <alexey@slaykovsky.com> | |
Date: Sat, 12 May 2018 11:38:53 +0200 | |
Subject: [PATCH] Read content from a request | |
Now it reads the content from an incoming request. | |
Also changed formatting to fit the Go standards. | |
And changed PUT to POST for a createContent handling. :) | |
And finally, added an arguments parser with a basedir parameter. | |
--- | |
storage.go | 85 ++++++++++++++++++++++++++++++------------------------ | |
1 file changed, 48 insertions(+), 37 deletions(-) | |
diff --git a/storage.go b/storage.go | |
index 30d1794..72782b8 100644 | |
--- a/storage.go | |
+++ b/storage.go | |
@@ -1,17 +1,20 @@ | |
package main | |
import ( | |
- "os" | |
- "net/http" | |
- "fmt" | |
"encoding/json" | |
+ "flag" | |
+ "io/ioutil" | |
+ "log" | |
+ "net/http" | |
"net/url" | |
+ "os" | |
"path" | |
"strings" | |
- "io/ioutil" | |
) | |
-const basedir = "/tmp" | |
+const defaultBasedir = "/tmp" | |
+ | |
+var basedir string | |
type ResponseBody interface { | |
toBytes() []byte | |
@@ -23,18 +26,18 @@ type Response struct { | |
} | |
type DataBody struct { | |
- Name string `json:"name"` | |
- IsDirectory bool `json:"directory"` | |
- ModDate int64 `json:"create_date"` | |
- Size int64 `json:"size"` | |
+ Name string `json:"name"` | |
+ IsDirectory bool `json:"directory"` | |
+ ModDate int64 `json:"create_date"` | |
+ Size int64 `json:"size"` | |
} | |
type ErrorBody struct { | |
- Msg string `json:msg` | |
+ Msg string `json:"msg"` | |
} | |
func (d *DataBody) toBytes() []byte { | |
- bytes, _:= json.Marshal(d) | |
+ bytes, _ := json.Marshal(d) | |
return bytes | |
} | |
@@ -43,11 +46,11 @@ func (e *ErrorBody) toBytes() []byte { | |
return bytes | |
} | |
-func (r *Response) parseRequest(requestUri string) (filepath string, opts url.Values, err error) { | |
- if reqUrl, err := url.ParseRequestURI(requestUri); err == nil { | |
- filepath = path.Clean(basedir + reqUrl.Path) | |
+func (r *Response) parseRequest(RequestURI string) (filepath string, opts url.Values, err error) { | |
+ if reqURL, err := url.ParseRequestURI(RequestURI); err == nil { | |
+ filepath = path.Clean(basedir + reqURL.Path) | |
if strings.HasPrefix(filepath, basedir) { | |
- opts, _ := url.ParseQuery(reqUrl.RawQuery) | |
+ opts, _ := url.ParseQuery(reqURL.RawQuery) | |
return filepath, opts, nil | |
} | |
} | |
@@ -59,7 +62,7 @@ func (r *Response) parseRequest(requestUri string) (filepath string, opts url.Va | |
func (r *Response) getContent(filepath string, opts url.Values) { | |
fileInfo, err := os.Stat(filepath) | |
- if err != nil { | |
+ if err != nil { | |
r.Code = http.StatusNotFound | |
r.Body = &ErrorBody{Msg: err.Error()} | |
return | |
@@ -67,7 +70,7 @@ func (r *Response) getContent(filepath string, opts url.Values) { | |
var size int64 | |
if fileInfo.IsDir() { | |
- files,_ := ioutil.ReadDir(filepath) | |
+ files, _ := ioutil.ReadDir(filepath) | |
size = int64(len(files)) | |
} else { | |
size = fileInfo.Size() | |
@@ -75,10 +78,10 @@ func (r *Response) getContent(filepath string, opts url.Values) { | |
r.Code = http.StatusOK | |
r.Body = &DataBody{ | |
- Name:fileInfo.Name(), | |
- IsDirectory:fileInfo.IsDir(), | |
- ModDate:fileInfo.ModTime().Unix(), | |
- Size:size, | |
+ Name: fileInfo.Name(), | |
+ IsDirectory: fileInfo.IsDir(), | |
+ ModDate: fileInfo.ModTime().Unix(), | |
+ Size: size, | |
} | |
} | |
@@ -93,33 +96,41 @@ func (r *Response) deleteContent(filepath string) { | |
} | |
func (r *Response) createContent(filepath string, content []byte) { | |
- if file, err := os.Create(filepath); err != nil { | |
+ file, err := os.Create(filepath) | |
+ if err != nil { | |
r.Code = http.StatusInternalServerError | |
r.Body = &ErrorBody{Msg: err.Error()} | |
- } else { | |
- if content != nil { | |
- file.Write(content) | |
- } | |
- file.Close() | |
- r.Code = http.StatusOK | |
- r.Body = &ErrorBody{filepath + " created"} | |
+ return | |
} | |
+ defer file.Close() | |
+ if content != nil { | |
+ file.Write(content) | |
+ } | |
+ r.Code = http.StatusOK | |
+ r.Body = &ErrorBody{filepath + " created"} | |
} | |
-func main() { | |
- http.HandleFunc("/", func (responseWriter http.ResponseWriter, request *http.Request) { | |
- response := &Response{Code:http.StatusMethodNotAllowed, Body:nil} | |
+func main() { | |
+ flag.StringVar(&basedir, "basedir", defaultBasedir, "The directory with files") | |
+ flag.Parse() | |
+ | |
+ http.HandleFunc("/", func(responseWriter http.ResponseWriter, request *http.Request) { | |
+ response := &Response{Code: http.StatusMethodNotAllowed, Body: nil} | |
if filepath, opts, err := response.parseRequest(request.RequestURI); err == nil { | |
switch request.Method { | |
- case http.MethodGet: { | |
+ case http.MethodGet: | |
+ { | |
response.getContent(filepath, opts) | |
} | |
- case http.MethodDelete: { | |
+ case http.MethodDelete: | |
+ { | |
response.deleteContent(filepath) | |
} | |
- case http.MethodPut: { | |
- response.createContent(filepath, nil) | |
+ case http.MethodPost: | |
+ { | |
+ content, _ := ioutil.ReadAll(request.Body) | |
+ response.createContent(filepath, content) | |
} | |
} | |
} | |
@@ -130,5 +141,5 @@ func main() { | |
} | |
}) | |
- fmt.Errorf("%v", http.ListenAndServe(":8080", nil)) | |
+ log.Fatal(http.ListenAndServe(":8080", nil)) | |
} | |
-- | |
2.17.0.windows.1 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment