gzip bug reports when storing on disk. Set max payload size
This commit is contained in:
parent
646ace6e59
commit
e8c51a0b54
1 changed files with 56 additions and 14 deletions
|
@ -5,13 +5,19 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
|
"compress/gzip"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var maxPayloadSize = 1024 * 1024 * 55 // 55 MB
|
||||||
|
|
||||||
type LogEntry struct {
|
type LogEntry struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Lines string `json:"lines"`
|
Lines string `json:"lines"`
|
||||||
|
@ -24,28 +30,64 @@ type Payload struct {
|
||||||
Logs []LogEntry `json:"logs"`
|
Logs []LogEntry `json:"logs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func respond(code int, w http.ResponseWriter) {
|
||||||
|
w.WriteHeader(code)
|
||||||
|
w.Write([]byte("{}"))
|
||||||
|
}
|
||||||
|
|
||||||
|
func gzipAndSave(data []byte, filepath string) error {
|
||||||
|
var b bytes.Buffer
|
||||||
|
gz := gzip.NewWriter(&b)
|
||||||
|
if _, err := gz.Write(data); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := gz.Flush(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := gz.Close(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := ioutil.WriteFile(filepath, b.Bytes(), 0644); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
|
http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
|
||||||
if req.Method != "POST" && req.Method != "OPTIONS" {
|
if req.Method != "POST" && req.Method != "OPTIONS" {
|
||||||
w.WriteHeader(405)
|
respond(405, w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// Set CORS
|
||||||
|
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||||
|
w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS")
|
||||||
|
w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
|
||||||
|
if req.Method == "OPTIONS" {
|
||||||
|
respond(200, w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if length, err := strconv.Atoi(req.Header.Get("Content-Length")); err != nil || length > maxPayloadSize {
|
||||||
|
respond(413, w)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Set CORS
|
|
||||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
||||||
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
|
|
||||||
w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
|
|
||||||
if req.Method == "OPTIONS" {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var p Payload
|
var p Payload
|
||||||
if err := json.NewDecoder(req.Body).Decode(&p); err != nil {
|
if err := json.NewDecoder(req.Body).Decode(&p); err != nil {
|
||||||
w.WriteHeader(400)
|
respond(400, w)
|
||||||
w.Write([]byte("Body is not JSON"))
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Dump bug report to disk
|
// Dump bug report to disk as form:
|
||||||
fmt.Println(p)
|
// "bugreport-20170115-112233.log.gz" => user text, version, user agent, # logs
|
||||||
|
// "bugreport-20170115-112233-0.log.gz" => most recent log
|
||||||
|
// "bugreport-20170115-112233-1.log.gz" => ...
|
||||||
|
// "bugreport-20170115-112233-N.log.gz" => oldest log
|
||||||
|
t := time.Now()
|
||||||
|
prefix := t.Format("bugreport-20060102-150405")
|
||||||
|
if err := gzipAndSave([]byte(p.Text), prefix+".log.gz"); err != nil {
|
||||||
|
respond(500, w)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
respond(200, w)
|
||||||
})
|
})
|
||||||
|
|
||||||
port := os.Args[1]
|
port := os.Args[1]
|
||||||
|
|
Loading…
Reference in a new issue