Merge pull request #16 from george-e-shaw-iv/master

Modulized Code and Cleaned Up Packages
This commit is contained in:
George Shaw 2017-10-20 17:38:05 -05:00 committed by GitHub
commit 39708bf2b7
12 changed files with 245 additions and 319 deletions

View file

@ -0,0 +1,36 @@
// 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
)
// 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))
msg = prefix + clientIP + "::" + msg
switch logType {
default:
fallthrough
case 1:
log.Println(msg)
case 2:
log.Fatal(msg)
}
}

42
general/logging/file.go Normal file
View file

@ -0,0 +1,42 @@
// 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"
)
// File logs a given message to a log file
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
}
}
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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