Last active
May 9, 2022 02:12
-
-
Save iamphill/9dfafc668a3c1cd79bcd to your computer and use it in GitHub Desktop.
Very basic golang HTTP server
This file contains hidden or 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
package main | |
import ( | |
"fmt" | |
"net/http" | |
) | |
type Error struct { } | |
func (e Error) notFoundError(w http.ResponseWriter, r *http.Request) { | |
w.Header().Set("Content-Type", "text/html") | |
w.WriteHeader(http.StatusNotFound) | |
fmt.Fprintf(w, "404! Not found") | |
} |
This file contains hidden or 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
<!DOCTYPE html> | |
<html> | |
<head> | |
<link rel="stylesheet" href="/assets/style.css" /> | |
</head> | |
<body> | |
<p> | |
Hello, {{.Name}} | |
</p> | |
<ul> | |
{{range .Data}} | |
<li> | |
{{.Username}} | |
</li> | |
{{end}} | |
</ul> | |
</body> | |
</html> |
This file contains hidden or 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
package main | |
import ( | |
"net/http" | |
"Regexp" | |
) | |
type route struct { | |
pattern *regexp.Regexp | |
handler http.Handler | |
} | |
type RegexpHandler struct { | |
routes []*route | |
} | |
func (h *RegexpHandler) Handler(pattern *regexp.Regexp, handler http.Handler) { | |
h.routes = append(h.routes, &route{pattern, handler}) | |
} | |
func (h *RegexpHandler) HandleFunc(pattern *regexp.Regexp, handler func(http.ResponseWriter, *http.Request)) { | |
h.routes = append(h.routes, &route{pattern, http.HandlerFunc(handler)}) | |
} | |
func (h *RegexpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { | |
for _, route := range h.routes { | |
if route.pattern.MatchString(r.URL.Path) { | |
route.handler.ServeHTTP(w, r) | |
return | |
} | |
} | |
http.NotFound(w, r) | |
} |
This file contains hidden or 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
package main | |
import ( | |
"time" | |
"fmt" | |
"net/http" | |
"encoding/json" | |
"os" | |
"Regexp" | |
"io/ioutil" | |
"strings" | |
"html/template" | |
"bytes" | |
) | |
func parseTemplate(fileName string, data interface{})(output []byte, err error) { | |
var buf bytes.Buffer | |
template, err := template.ParseFiles(fileName) | |
if err != nil { | |
return nil, err | |
} | |
err = template.Execute(&buf, data) | |
if err != nil { | |
return nil, err | |
} | |
return buf.Bytes(), nil | |
} | |
type User struct { | |
UserId int `json:"id"` | |
Username string `json:"username"` | |
Friends []*User `json:"friends"` | |
} | |
func sayHelloWorld(w http.ResponseWriter, r *http.Request) { | |
fmt.Printf("%v: Recieved request for index\n", time.Now()) | |
w.Header().Set("Content-Type", "application/json") | |
d := []*User{} | |
d = append(d, &User{ | |
UserId: 3, | |
Username: "Another User!"}) | |
d = append(d, &User{ | |
UserId: 2, | |
Username: "asdasd"}) | |
user := &User{ | |
UserId: 1, | |
Username: "Phil Hughes", | |
Friends: d} | |
var outputjson []byte | |
var err error | |
if r.FormValue("pretty") != "" && r.FormValue("pretty") == "true" { | |
outputjson, err = json.MarshalIndent(user, "", " ") | |
} else { | |
outputjson, err = json.Marshal(user) | |
} | |
if err == nil { | |
fmt.Printf("%v: Sent response for index\n", time.Now()) | |
fmt.Fprintf(w, string(outputjson)) | |
} | |
} | |
func handleCss(w http.ResponseWriter, r *http.Request) { | |
w.Header().Set("Content-Type", "text/css") | |
fileName := strings.Split(r.URL.Path, "/") | |
dat, err := ioutil.ReadFile(fileName[len(fileName) - 1]) | |
if err == nil { | |
fmt.Fprintf(w, string(dat)) | |
} else { | |
err := &Error{} | |
err.notFoundError(w, r) | |
} | |
} | |
func indexAction(w http.ResponseWriter, r *http.Request) { | |
w.Header().Set("Content-Type", "text/html") | |
template, err := parseTemplate("templates/home.html", map[string]interface{}{ | |
"Name": "Phil Hughes", | |
"Data": []*User{ | |
&User{UserId: 2, Username: "username1"}, | |
&User{UserId: 3, Username: "username2"}, | |
&User{UserId: 4, Username: "username3"}}}) | |
cookie := http.Cookie{Name: "test", Value: "1", Expires: time.Now().Add(2 * time.Hour)} | |
http.SetCookie(w, &cookie) | |
if err == nil { | |
fmt.Fprintf(w, string(template)) | |
} | |
} | |
func main() { | |
var port string | |
if os.Getenv("PORT") != "" { | |
port = os.Getenv("PORT") | |
} else { | |
port = "9000" | |
} | |
handler := &RegexpHandler{} | |
handler.HandleFunc(regexp.MustCompile("^/assets/([a-zA-Z]+/?)+.css$"), handleCss) | |
handler.HandleFunc(regexp.MustCompile("^/hello-world"), sayHelloWorld) | |
handler.HandleFunc(regexp.MustCompile("^/"), indexAction) | |
fmt.Printf("Server is running on port %v\n", port) | |
http.ListenAndServe(":" + port, handler) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment