From 05214af527a60e98156fb41cd1a425ec718f8d7a Mon Sep 17 00:00:00 2001 From: George Shaw Date: Fri, 20 Oct 2017 17:29:40 -0500 Subject: [PATCH 1/2] modualized code and cleaned up packages --- general/logging/console.go | 35 ++++++++++++ general/logging/file.go | 41 ++++++++++++++ general/routing/contentTypes.go | 42 ++++++++++++++ general/routing/http_status.go | 9 +++ main.go | 8 +-- private_server/logging/logging.go | 91 ------------------------------- private_server/private_server.go | 58 ++++++++++++++++++++ private_server/routing/routing.go | 66 ---------------------- public_server/logging/logging.go | 91 ------------------------------- public_server/public_server.go | 50 +++++++++++++++++ public_server/routing/routing.go | 57 ------------------- 11 files changed, 239 insertions(+), 309 deletions(-) create mode 100644 general/logging/console.go create mode 100644 general/logging/file.go create mode 100644 general/routing/contentTypes.go create mode 100644 general/routing/http_status.go delete mode 100644 private_server/logging/logging.go create mode 100644 private_server/private_server.go delete mode 100644 private_server/routing/routing.go delete mode 100644 public_server/logging/logging.go create mode 100644 public_server/public_server.go delete mode 100644 public_server/routing/routing.go diff --git a/general/logging/console.go b/general/logging/console.go new file mode 100644 index 0000000..865ff0e --- /dev/null +++ b/general/logging/console.go @@ -0,0 +1,35 @@ +// Package logging handles the various mediums and logic of logging messages and reports. +package logging + +import ( + "log" + "strings" + + "github.com/Ennovar/gPanel/general/networking" +) + +const ( + PRIVATE_PREFIX string = "PRIVATE::" + PUBLIC_PREFIX string = "PUBLIC::" +) + +const ( + NORMAL_LOG int = 1 + FATAL_LOG int = 2 +) + +func Console(prefix string, logType int, msg string) { + rawClientIP, _ := networking.GetClientIP() + clientIP := strings.TrimSpace(string(rawClientIP)) + + msg = prefix + clientIP + "::" + msg + + switch logType { + default: + fallthrough + case 1: + log.Println(msg) + case 2: + log.Fatal(msg) + } +} diff --git a/general/logging/file.go b/general/logging/file.go new file mode 100644 index 0000000..1918e71 --- /dev/null +++ b/general/logging/file.go @@ -0,0 +1,41 @@ +// Package logging handles the various mediums and logic of logging messages and reports. +package logging + +import "os" + +const ( + PRIVATE_LOG_FOLDER string = "logs/private/" + PUBLIC_LOG_FOLDER string = "logs/public/" +) + +const ( + ERROR string = "error.log" + WARNING string = "warning.log" +) + +func File(logFolder string, logFile string, msg string) (string, error) { + msg += "\n" + + f, err := os.OpenFile(logFolder+logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + + if err != nil { + return "", err + } else { + writtenBytes, err := f.Write([]byte(msg)) + + if err != nil { + return string(writtenBytes), err + } else { + err := f.Close() + + if err != nil { + return string(writtenBytes), err + } else { + return string(writtenBytes), nil + } + + } + + } + +} diff --git a/general/routing/contentTypes.go b/general/routing/contentTypes.go new file mode 100644 index 0000000..4b8db09 --- /dev/null +++ b/general/routing/contentTypes.go @@ -0,0 +1,42 @@ +// Package routing contains various functions related to HTTP routing +package routing + +import ( + "errors" + "strings" +) + +// getContentType returns the http header safe content-type attribute for the +// requested path. If the requested path is not formatted correctly with an extension +// then the function will return the zero-value for a string and an error. +// BUG(george-e-shaw-iv) Cannot handle interpreted files such as .php files +// BUG(george-e-shaw-iv) Does not cover the bulk of encountered content types on the web +func GetContentType(path string) (string, error) { + var contentType string + splitPath := strings.Split(path, ".") + + if len(splitPath) == 1 && splitPath[0] == path { + return contentType, errors.New("Invalid path, contained no period-separated content-type") + } + + fileType := splitPath[len(splitPath)-1] + + switch fileType { + case "html": + contentType = "text/html" + case "css": + contentType = "text/css" + case "js": + contentType = "text/javascript" + case "png": + contentType = "image/png" + case "jpg": + fallthrough + case "jpeg": + contentType = "image/jpeg" + default: + contentType = "text/plain" + } + + return contentType, nil +} diff --git a/general/routing/http_status.go b/general/routing/http_status.go new file mode 100644 index 0000000..1bcddbc --- /dev/null +++ b/general/routing/http_status.go @@ -0,0 +1,9 @@ +// Package routing contains various functions related to HTTP routing +package routing + +import "net/http" + +func HttpThrowStatus(code int, context http.ResponseWriter) { + context.WriteHeader(code) + context.Write([]byte(http.StatusText(code))) +} diff --git a/main.go b/main.go index ef83cf0..cebc595 100644 --- a/main.go +++ b/main.go @@ -4,13 +4,13 @@ import ( "log" "net/http" - "github.com/Ennovar/gPanel/private_server/routing" - "github.com/Ennovar/gPanel/public_server/routing" + "github.com/Ennovar/gPanel/private_server" + "github.com/Ennovar/gPanel/public_server" ) func main() { - private := privateRouting.NewPrivateHost() - public := publicRouting.NewPublicWeb() + private := private_server.NewPrivateHost() + public := public_server.NewPublicWeb() log.Printf("To Exit: CTRL+C") diff --git a/private_server/logging/logging.go b/private_server/logging/logging.go deleted file mode 100644 index c9a7c2b..0000000 --- a/private_server/logging/logging.go +++ /dev/null @@ -1,91 +0,0 @@ -package privateLogging - -import ( - "log" - "os" - "strings" - - "github.com/Ennovar/gPanel/general/networking" -) - -const ( - CONSOLE_PREFIX string = "PRIVATE::" - LOG_FOLDER string = "logs/private/" -) - -/* - A function to log to the console - - @param logType int - The integer identifier cooresponding to the type of log. - The following integers are defined: - - 1: Normal (log.Println) - - 2: Fatal (log.Fatal) - @param msg string - The message to log - - @return bool - Dependant on whether or not logType was defined with a valid logType -*/ -func Console(logType int, msg string) bool { - rawClientIP, _ := networking.GetClientIP() - clientIP := strings.TrimSpace(string(rawClientIP)) - - msg = CONSOLE_PREFIX + clientIP + "::" + msg - - switch logType { - case 1: - log.Println(msg) - case 2: - log.Println(msg) - default: - return false - } - - return true -} - -/* - A function to log errors for the public server into files - - @param fileType int - The integer identifier cooresponding to the file to log to. - The following integers are defined: - - 1: error.log - - 2: warning.log - @param msg string - The message to log. - - @return bool - Dependant on whether or not fileType was defined with a valid fileType OR if file operations fail -*/ -func File(fileType int, msg string) bool { - msg += "\n" - fileName := LOG_FOLDER - - switch fileType { - case 1: - fileName += "error.log" - case 2: - fileName += "warning.log" - default: - return false - } - - f, err := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return false - } else { - _, err := f.Write([]byte(msg)) - if err != nil { - return false - } else { - err := f.Close() - if err != nil { - return false - } else { - return true - } - } - } -} diff --git a/private_server/private_server.go b/private_server/private_server.go new file mode 100644 index 0000000..ea6d296 --- /dev/null +++ b/private_server/private_server.go @@ -0,0 +1,58 @@ +// Package private_server handles the logic of the private_server +package private_server + +import ( + "bufio" + "net/http" + "os" + + "github.com/Ennovar/gPanel/general/logging" + "github.com/Ennovar/gPanel/general/routing" +) + +type privateHost struct { + Auth int + Directory string +} + +func NewPrivateHost() privateHost { + priv := privateHost{} + + priv.Auth = 1 // Handle Auth + priv.Directory = "private/" + + return priv +} + +func (priv *privateHost) ServeHTTP(w http.ResponseWriter, req *http.Request) { + path := req.URL.Path[1:] + path = (priv.Directory + path) + + if priv.Auth != 1 { + routing.HttpThrowStatus(404, w) + logging.Console(logging.PRIVATE_PREFIX, logging.NORMAL_LOG, "Path \""+path+"\" rendered a 401 error.") + } else { + f, err := os.Open(path) + + if err == nil { + bufferedReader := bufio.NewReader(f) + contentType, err := routing.GetContentType(path) + + if err == nil { + w.Header().Add("Content Type", contentType) + bufferedReader.WriteTo(w) + + logging.Console(logging.PRIVATE_PREFIX, logging.NORMAL_LOG, "Path \""+path+"\" rendered a 200 success.") + } else { + routing.HttpThrowStatus(404, w) + logging.Console(logging.PRIVATE_PREFIX, logging.NORMAL_LOG, "Path \""+path+"\" content type could not be determined, 404 error.") + } + + } else { + routing.HttpThrowStatus(404, w) + logging.Console(logging.PRIVATE_PREFIX, logging.NORMAL_LOG, "Path \""+path+"\" rendered a 404 error.") + } + + } + +} diff --git a/private_server/routing/routing.go b/private_server/routing/routing.go deleted file mode 100644 index c7c696f..0000000 --- a/private_server/routing/routing.go +++ /dev/null @@ -1,66 +0,0 @@ -package privateRouting - -import ( - "bufio" - "net/http" - "os" - "strings" - - "github.com/Ennovar/gPanel/private_server/logging" -) - -type privateHost struct { - Auth int - Directory string -} - -func NewPrivateHost() privateHost { - priv := privateHost{} - - priv.Auth = 1 // Handle Auth - priv.Directory = "private/" - - return priv -} - -func (priv *privateHost) ServeHTTP(w http.ResponseWriter, req *http.Request) { - path := req.URL.Path[1:] - path = (priv.Directory + path) - - if priv.Auth != 1 { - w.WriteHeader(401) - w.Write([]byte("401 - " + http.StatusText(401))) - - privateLogging.Console(2, "Path \""+path+"\" rendered a 401 error: "+http.StatusText(401)) - } else { - privateLogging.Console(1, path) - f, err := os.Open(path) - - if err == nil { - bufferedReader := bufio.NewReader(f) - var contentType string - - if strings.HasSuffix(path, ".html") { - contentType = "text/html" - } else if strings.HasSuffix(path, ".css") { - contentType = "text/css" - } else if strings.HasSuffix(path, ".js") { - contentType = "text/javascript" - } else if strings.HasSuffix(path, ".png") { - contentType = "image/png" - } else if strings.HasSuffix(path, ".jpg") || strings.HasSuffix(path, ".jpeg") { - contentType = "image/jpeg" - } else { - contentType = "text/plain" - } - - w.Header().Add("Content Type", contentType) - bufferedReader.WriteTo(w) - } else { - w.WriteHeader(404) - w.Write([]byte("404 - " + http.StatusText(404))) - - privateLogging.Console(2, "Path \""+path+"\" rendered a 404 error: "+http.StatusText(404)) - } - } -} diff --git a/public_server/logging/logging.go b/public_server/logging/logging.go deleted file mode 100644 index 1c9f73d..0000000 --- a/public_server/logging/logging.go +++ /dev/null @@ -1,91 +0,0 @@ -package publicLogging - -import ( - "log" - "os" - "strings" - - "github.com/Ennovar/gPanel/general/networking" -) - -const ( - CONSOLE_PREFIX string = "PUBLIC::" - LOG_FOLDER string = "logs/public/" -) - -/* - A function to log to the console - - @param logType int - The integer identifier cooresponding to the type of log. - The following integers are defined: - - 1: Normal (log.Println) - - 2: Fatal (log.Fatal) - @param msg string - The message to log - - @return bool - Dependant on whether or not logType was defined with a valid logType -*/ -func Console(logType int, msg string) bool { - rawClientIP, _ := networking.GetClientIP() - clientIP := strings.TrimSpace(string(rawClientIP)) - - msg = CONSOLE_PREFIX + clientIP + "::" + msg - - switch logType { - case 1: - log.Println(msg) - case 2: - log.Println(msg) - default: - return false - } - - return true -} - -/* - A function to log errors for the public server into files - - @param fileType int - The integer identifier cooresponding to the file to log to. - The following integers are defined: - - 1: error.log - - 2: warning.log - @param msg string - The message to log. - - @return bool - Dependant on whether or not fileType was defined with a valid fileType OR if file operations fail -*/ -func File(fileType int, msg string) bool { - msg += "\n" - fileName := LOG_FOLDER - - switch fileType { - case 1: - fileName += "error.log" - case 2: - fileName += "warning.log" - default: - return false - } - - f, err := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - return false - } else { - _, err := f.Write([]byte(msg)) - if err != nil { - return false - } else { - err := f.Close() - if err != nil { - return false - } else { - return true - } - } - } -} diff --git a/public_server/public_server.go b/public_server/public_server.go new file mode 100644 index 0000000..d918490 --- /dev/null +++ b/public_server/public_server.go @@ -0,0 +1,50 @@ +// Package public_server handles the logic of the public facing website +package public_server + +import ( + "bufio" + "net/http" + "os" + + "github.com/Ennovar/gPanel/general/logging" + "github.com/Ennovar/gPanel/general/routing" +) + +type publicWeb struct { + Directory string +} + +func NewPublicWeb() publicWeb { + pub := publicWeb{} + + pub.Directory = "public/" + + return pub +} + +func (pub *publicWeb) ServeHTTP(w http.ResponseWriter, req *http.Request) { + path := req.URL.Path[1:] + path = (pub.Directory + path) + + f, err := os.Open(path) + + if err == nil { + bufferedReader := bufio.NewReader(f) + contentType, err := routing.GetContentType(path) + + if err == nil { + w.Header().Add("Content Type", contentType) + bufferedReader.WriteTo(w) + + logging.Console(logging.PUBLIC_PREFIX, logging.NORMAL_LOG, "Path \""+path+"\" rendered a 200 success.") + } else { + routing.HttpThrowStatus(404, w) + logging.Console(logging.PUBLIC_PREFIX, logging.NORMAL_LOG, "Path \""+path+"\" content type could not be determined, 404 error.") + } + + } else { + routing.HttpThrowStatus(404, w) + logging.Console(logging.PUBLIC_PREFIX, logging.NORMAL_LOG, "Path \""+path+"\" rendered a 404 error.") + } + +} diff --git a/public_server/routing/routing.go b/public_server/routing/routing.go deleted file mode 100644 index c72c61c..0000000 --- a/public_server/routing/routing.go +++ /dev/null @@ -1,57 +0,0 @@ -package publicRouting - -import ( - "bufio" - "net/http" - "os" - "strings" - - "github.com/Ennovar/gPanel/public_server/logging" -) - -type publicWeb struct { - Directory string -} - -func NewPublicWeb() publicWeb { - pub := publicWeb{} - - pub.Directory = "public/" - - return pub -} - -func (pub *publicWeb) ServeHTTP(w http.ResponseWriter, req *http.Request) { - path := req.URL.Path[1:] - path = (pub.Directory + path) - - publicLogging.Console(1, path) - f, err := os.Open(path) - - if err == nil { - bufferedReader := bufio.NewReader(f) - var contentType string - - if strings.HasSuffix(path, ".html") { - contentType = "text/html" - } else if strings.HasSuffix(path, ".css") { - contentType = "text/css" - } else if strings.HasSuffix(path, ".js") { - contentType = "text/javascript" - } else if strings.HasSuffix(path, ".png") { - contentType = "image/png" - } else if strings.HasSuffix(path, ".jpg") || strings.HasSuffix(path, ".jpeg") { - contentType = "image/jpeg" - } else { - contentType = "text/plain" - } - - w.Header().Add("Content Type", contentType) - bufferedReader.WriteTo(w) - } else { - w.WriteHeader(404) - w.Write([]byte("404 - " + http.StatusText(404))) - - publicLogging.Console(2, "Path \""+path+"\" rendered a 404 error: "+http.StatusText(404)) - } -} From 6eeb83453704fbf5ca65e33c5c8927981fd755b6 Mon Sep 17 00:00:00 2001 From: George Shaw Date: Fri, 20 Oct 2017 17:34:13 -0500 Subject: [PATCH 2/2] updated comments to follow conventions --- general/logging/console.go | 1 + general/logging/file.go | 1 + general/networking/ip_address.go | 14 ++++---------- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/general/logging/console.go b/general/logging/console.go index 865ff0e..595c73f 100644 --- a/general/logging/console.go +++ b/general/logging/console.go @@ -18,6 +18,7 @@ const ( FATAL_LOG int = 2 ) +// Console logs a prefix, IP, and message all appeneded together to the console. func Console(prefix string, logType int, msg string) { rawClientIP, _ := networking.GetClientIP() clientIP := strings.TrimSpace(string(rawClientIP)) diff --git a/general/logging/file.go b/general/logging/file.go index 1918e71..e0c8217 100644 --- a/general/logging/file.go +++ b/general/logging/file.go @@ -13,6 +13,7 @@ const ( WARNING string = "warning.log" ) +// File logs a given message to a log file func File(logFolder string, logFile string, msg string) (string, error) { msg += "\n" diff --git a/general/networking/ip_address.go b/general/networking/ip_address.go index 4c7396f..c0e7dad 100644 --- a/general/networking/ip_address.go +++ b/general/networking/ip_address.go @@ -1,3 +1,5 @@ +// Package networking contains various functions used to communicate between networks and +// draw data from the client network. package networking import ( @@ -5,16 +7,8 @@ import ( "net/http" ) -/* - A function to get the client IP - - @return []byte - The IP Address - @return error - If no error exists, the value is nil - - Known Problems: Uses an external API -*/ +// GetClientIP returns the current client's IP as an array of bytes. +// BUG(george-e-shaw-iv) Uses an external API func GetClientIP() ([]byte, error) { resp, err := http.Get("http://myexternalip.com/raw")