-
Notifications
You must be signed in to change notification settings - Fork 0
/
graphviz-server.go
110 lines (97 loc) · 2.77 KB
/
graphviz-server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package main
import (
"flag"
"fmt"
"encoding/base64"
"io/ioutil"
"net/http"
"os"
"os/exec"
"strconv"
)
func create_img(graph string, response http.ResponseWriter) {
cmd := exec.Command("dot", "-T", "png")
stdin, err := cmd.StdinPipe()
if err != nil {
fmt.Println(err)
return
}
defer stdin.Close()
cmd.Stdout = response
fmt.Printf("Creating graph... ")
if err = cmd.Start(); err != nil {
response.WriteHeader(500)
fmt.Println("An error occurred: ", err)
return
}
response.Header().Set("Content-type", "image/png")
fmt.Fprintf(stdin, "%s", graph)
stdin.Close()
cmd.Wait()
fmt.Println("done")
}
func handle_get(response http.ResponseWriter, request *http.Request) {
graph_encoded := request.URL.Query().Get("graph")
if graph_encoded == "" {
response.WriteHeader(400)
return
}
bgraph, err := base64.URLEncoding.DecodeString(graph_encoded)
if err != nil {
response.WriteHeader(400)
fmt.Fprintf(response, "Error: %s\n", err)
return
}
// I'm not sure why this is the easiest way to convert a byte array to a string
graph := fmt.Sprintf("%s", bgraph)
fmt.Println(graph)
create_img(graph, response)
}
func handle_post(response http.ResponseWriter, request *http.Request) {
bgraph, err := ioutil.ReadAll(request.Body)
if err != nil {
response.WriteHeader(400)
return
}
// I'm not sure why this is the easiest way to convert a byte array to a string
graph := fmt.Sprintf("%s", bgraph)
if graph == "" {
response.WriteHeader(400)
return
}
fmt.Println(graph)
create_img(graph, response)
}
func handle(response http.ResponseWriter, request *http.Request) {
fmt.Println(request.Method)
if request.Method == "GET" {
handle_get(response, request)
} else if request.Method == "POST" {
handle_post(response, request)
} else {
response.WriteHeader(405)
response.Header().Set("Allow", "GET, POST")
}
}
func main() {
var portNumber int
flag.IntVar(&portNumber, "port", 0, "Port to listen on")
flag.Parse()
if portNumber == 0 {
portNumberStr := os.Getenv("GS_PORT")
if portNumberStr == "" {
portNumber = 8000 // The default port number
} else {
portNumberStrConv, err := strconv.Atoi(portNumberStr)
if err == nil {
portNumber = portNumberStrConv
} else {
fmt.Println(err)
os.Exit(2)
}
}
}
http.HandleFunc("/", handle)
fmt.Println(fmt.Sprintf("Starting webserver on port %d", portNumber))
http.ListenAndServe(fmt.Sprintf(":%d", portNumber), nil)
}