Merge pull request #6 from TomWright/png-functionality

Cleanup and Makefile
This commit is contained in:
Tom Wright 2020-10-02 14:39:02 +01:00 committed by GitHub
commit 44f409a807
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 56 additions and 26 deletions

21
Makefile Normal file
View File

@ -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}

View File

@ -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)
}
} }
} }