Do some cleanup and add a Makefile
This commit is contained in:
parent
bfa4d5076b
commit
aac3f97894
|
|
@ -0,0 +1,21 @@
|
||||||
|
DOCKER_IMAGE=tomwright/mermaid-server:latest
|
||||||
|
CONTAINER_NAME=mermaid-server
|
||||||
|
|
||||||
|
docker-image:
|
||||||
|
docker build -t ${DOCKER_IMAGE} .
|
||||||
|
|
||||||
|
docker-run:
|
||||||
|
docker run -d --name ${CONTAINER_NAME} -p 80:80 ${DOCKER_IMAGE}
|
||||||
|
|
||||||
|
docker-stop:
|
||||||
|
docker stop ${CONTAINER_NAME} || true
|
||||||
|
|
||||||
|
docker-rm:
|
||||||
|
make docker-stop
|
||||||
|
docker rm ${CONTAINER_NAME} || true
|
||||||
|
|
||||||
|
docker-logs:
|
||||||
|
docker logs -f ${CONTAINER_NAME}
|
||||||
|
|
||||||
|
docker-push:
|
||||||
|
docker push ${DOCKER_IMAGE}
|
||||||
|
|
@ -22,16 +22,20 @@ func writeJSON(rw http.ResponseWriter, value interface{}, status int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeImage(rw http.ResponseWriter, data []byte, status int, imgType string) {
|
func writeImage(rw http.ResponseWriter, data []byte, status int, imgType string) error {
|
||||||
if imgType == "png" {
|
switch imgType {
|
||||||
|
case "png":
|
||||||
rw.Header().Set("Content-Type", "image/png")
|
rw.Header().Set("Content-Type", "image/png")
|
||||||
} else {
|
case "svg":
|
||||||
rw.Header().Set("Content-Type", "image/svg+xml")
|
rw.Header().Set("Content-Type", "image/svg+xml")
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unhandled image type: %s", imgType)
|
||||||
}
|
}
|
||||||
rw.WriteHeader(status)
|
rw.WriteHeader(status)
|
||||||
if _, err := rw.Write(data); err != nil {
|
if _, err := rw.Write(data); err != nil {
|
||||||
panic("could not write bytes to response: " + err.Error())
|
return fmt.Errorf("could not write image bytes: %w", err)
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeErr(rw http.ResponseWriter, err error, status int) {
|
func writeErr(rw http.ResponseWriter, err error, status int) {
|
||||||
|
|
@ -45,69 +49,72 @@ func writeErr(rw http.ResponseWriter, err error, status int) {
|
||||||
// URLParam is the URL parameter getDiagramFromGET uses to look for data.
|
// URLParam is the URL parameter getDiagramFromGET uses to look for data.
|
||||||
const URLParam = "data"
|
const URLParam = "data"
|
||||||
|
|
||||||
func getDiagramFromGET(rw http.ResponseWriter, r *http.Request, imgType string) *Diagram {
|
func getDiagramFromGET(r *http.Request, imgType string) (*Diagram, error) {
|
||||||
if r.Method != http.MethodGet {
|
if r.Method != http.MethodGet {
|
||||||
writeErr(rw, fmt.Errorf("expected HTTP method GET"), http.StatusBadRequest)
|
return nil, fmt.Errorf("expected HTTP method GET")
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
queryVal := strings.TrimSpace(r.URL.Query().Get(URLParam))
|
queryVal := strings.TrimSpace(r.URL.Query().Get(URLParam))
|
||||||
if queryVal == "" {
|
if queryVal == "" {
|
||||||
writeErr(rw, fmt.Errorf("missing data"), http.StatusBadRequest)
|
return nil, fmt.Errorf("missing data")
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
data, err := url.QueryUnescape(queryVal)
|
data, err := url.QueryUnescape(queryVal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErr(rw, fmt.Errorf("could not read query param: %s", err), http.StatusBadRequest)
|
return nil, fmt.Errorf("could not read query param: %s", err)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a diagram from the description
|
// Create a diagram from the description
|
||||||
d := NewDiagram([]byte(data), imgType)
|
d := NewDiagram([]byte(data), imgType)
|
||||||
return d
|
return d, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getDiagramFromPOST(rw http.ResponseWriter, r *http.Request, imgType string) *Diagram {
|
func getDiagramFromPOST(r *http.Request, imgType string) (*Diagram, error) {
|
||||||
if r.Method != http.MethodPost {
|
if r.Method != http.MethodPost {
|
||||||
writeErr(rw, fmt.Errorf("expected HTTP method POST"), http.StatusBadRequest)
|
return nil, fmt.Errorf("expected HTTP method POST")
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
// Get description from request body
|
// Get description from request body
|
||||||
bytes, err := ioutil.ReadAll(r.Body)
|
bytes, err := ioutil.ReadAll(r.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeErr(rw, fmt.Errorf("could not read body: %s", err), http.StatusInternalServerError)
|
return nil, fmt.Errorf("could not read body: %s", err)
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a diagram from the description
|
// Create a diagram from the description
|
||||||
d := NewDiagram(bytes, imgType)
|
d := NewDiagram(bytes, imgType)
|
||||||
return d
|
return d, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const URLParamImageType = "type"
|
||||||
|
|
||||||
// generateHTTPHandler returns a HTTP handler used to generate a diagram.
|
// generateHTTPHandler returns a HTTP handler used to generate a diagram.
|
||||||
func generateHTTPHandler(generator Generator) func(rw http.ResponseWriter, r *http.Request) {
|
func generateHTTPHandler(generator Generator) func(rw http.ResponseWriter, r *http.Request) {
|
||||||
return func(rw http.ResponseWriter, r *http.Request) {
|
return func(rw http.ResponseWriter, r *http.Request) {
|
||||||
var diagram *Diagram
|
var diagram *Diagram
|
||||||
|
|
||||||
var imgType = r.URL.Query().Get("type")
|
imgType := r.URL.Query().Get(URLParamImageType)
|
||||||
if imgType == "" {
|
|
||||||
imgType = "svg"
|
|
||||||
}
|
|
||||||
|
|
||||||
if imgType != "png" && imgType != "svg" {
|
switch imgType {
|
||||||
|
case "png", "svg":
|
||||||
|
case "":
|
||||||
|
imgType = "svg"
|
||||||
|
default:
|
||||||
writeErr(rw, fmt.Errorf("unsupported image type (%s) use svg or png", imgType), http.StatusBadRequest)
|
writeErr(rw, fmt.Errorf("unsupported image type (%s) use svg or png", imgType), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
case http.MethodGet:
|
case http.MethodGet:
|
||||||
diagram = getDiagramFromGET(rw, r, imgType)
|
diagram, err = getDiagramFromGET(r, imgType)
|
||||||
case http.MethodPost:
|
case http.MethodPost:
|
||||||
diagram = getDiagramFromPOST(rw, r, imgType)
|
diagram, err = getDiagramFromPOST(r, imgType)
|
||||||
default:
|
default:
|
||||||
writeErr(rw, fmt.Errorf("unexpected HTTP method %s", r.Method), http.StatusBadRequest)
|
writeErr(rw, fmt.Errorf("unexpected HTTP method %s", r.Method), http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if err != nil {
|
||||||
|
writeErr(rw, err, http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
if diagram == nil {
|
if diagram == nil {
|
||||||
writeErr(rw, fmt.Errorf("could not create diagram"), http.StatusInternalServerError)
|
writeErr(rw, fmt.Errorf("could not create diagram"), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
|
|
@ -126,6 +133,8 @@ func generateHTTPHandler(generator Generator) func(rw http.ResponseWriter, r *ht
|
||||||
writeErr(rw, fmt.Errorf("could not read diagram bytes: %s", err), http.StatusInternalServerError)
|
writeErr(rw, fmt.Errorf("could not read diagram bytes: %s", err), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
writeImage(rw, diagramBytes, http.StatusOK, imgType)
|
if err := writeImage(rw, diagramBytes, http.StatusOK, imgType); err != nil {
|
||||||
|
writeErr(rw, fmt.Errorf("could not write diagram: %w", err), http.StatusInternalServerError)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue