Initial commit
This commit is contained in:
21
24 - HTTP Servers/httpserver/certificate.cer
Normal file
21
24 - HTTP Servers/httpserver/certificate.cer
Normal file
@@ -0,0 +1,21 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDXzCCAkegAwIBAgIJAJItNUc9TmNiMA0GCSqGSIb3DQEBCwUAMEgxCzAJBgNV
|
||||
BAYTAkdCMQ8wDQYDVQQIEwZMb25kb24xDzANBgNVBAcTBkxvbmRvbjEXMBUGA1UE
|
||||
AxMOd3d3LmFwcmVzcy5jb20wHhcNMjEwNzAzMTcwMDAwWhcNMzEwNzA0MTcwMDAw
|
||||
WjBIMQswCQYDVQQGEwJHQjEPMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25k
|
||||
b24xFzAVBgNVBAMTDnd3dy5hcHJlc3MuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
||||
AQ8AMIIBCgKCAQEAugrxUGydOzJ0Sz+l7IuXEuJ3JusjpW4uyfkUF8aYvJBDGIjI
|
||||
ovXMjMio5qCKfNpJbyCQKh7x6VZydC0CdBT8Qp4rtfhVqrS6r+orA3MK/PlPx5YO
|
||||
SWHYkLreaMNUapTKKaTQLQh1PHO2hn+yrc5q0AYkUZQcoLGSfKd9iDayHCZBHI78
|
||||
opiqNVQ3/5P+KZw3aeIugy6WUmNtszwvACQYIB6s+fy7C9z+T2WXG7LVuEiS8oaR
|
||||
2xoJjiALN2BEa+Cf1s6WeVNcAUbBXVvBxUi2QjL4zrG1b1c297k9GWP04RRjRoxD
|
||||
s4CnKNz/A4Q9xAplqruglemzCw5XvPMQuXm/bwIDAQABo0wwSjAJBgNVHRMEAjAA
|
||||
MBEGCWCGSAGG+EIBAQQEAwIE8DALBgNVHQ8EBAMCBaAwHQYDVR0lBBYwFAYIKwYB
|
||||
BQUHAwIGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IBAQCb8mTNFLQiUpweQZWF
|
||||
8TZsv050Qr/ATuNzmYwwUJd4BtHF8k40Pfbve1Xu1ZDT5cYXpBVtlqLU/med6Mpt
|
||||
wfMdVmMZffjhay+qiscKt6GKV+csbXOiIKbWXLtnnOxDZAiya1fX12bKgxGXxln5
|
||||
7MS6n2Jeg8uWe9d3fnyIiydrHd4cK3bSeq4Z7EgkPR6nxRCOTPoPLMmNDIHVzWET
|
||||
HrncocRZ6YOJGNWPBXbJmZlwipUE9E+fcZOLwp9Qd9EAQuV7hfWLUf4j2373xqPf
|
||||
QQydl4h05aG1mn3FAaDASXjkVh5S9YTJyDl75t2bvR44klG2gXr7IqKdsTPF7qiw
|
||||
w24i
|
||||
-----END CERTIFICATE-----
|
||||
27
24 - HTTP Servers/httpserver/certificate.key
Normal file
27
24 - HTTP Servers/httpserver/certificate.key
Normal file
@@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAugrxUGydOzJ0Sz+l7IuXEuJ3JusjpW4uyfkUF8aYvJBDGIjI
|
||||
ovXMjMio5qCKfNpJbyCQKh7x6VZydC0CdBT8Qp4rtfhVqrS6r+orA3MK/PlPx5YO
|
||||
SWHYkLreaMNUapTKKaTQLQh1PHO2hn+yrc5q0AYkUZQcoLGSfKd9iDayHCZBHI78
|
||||
opiqNVQ3/5P+KZw3aeIugy6WUmNtszwvACQYIB6s+fy7C9z+T2WXG7LVuEiS8oaR
|
||||
2xoJjiALN2BEa+Cf1s6WeVNcAUbBXVvBxUi2QjL4zrG1b1c297k9GWP04RRjRoxD
|
||||
s4CnKNz/A4Q9xAplqruglemzCw5XvPMQuXm/bwIDAQABAoIBAG2pIZDMVOmd1dq9
|
||||
C6qgpU4mWyF/nKVYiw/WV7ekAkezqTj+93TG+elKJfS7UKZDbOGqChAp6WIm6JP+
|
||||
K+IMtJz36r/6P1S97wTePLhtyV5P/myg0I8Es8irvYl3CX1BcuCVG3hP8frOIhqp
|
||||
jsLQVzmDRUkoyq8VvEjp2R6/TsEz8Oq6InLvCnCqYY3CBrXop7XWwGDAJjek6YvV
|
||||
5e4QPa6fQSQwYWL9/s+mbW475PuACZoLYqrHoSaYllXSkBTCdbrsNtknH6hDGdm7
|
||||
98i1sQkfO0bxTChNkN6AwKUbX5rfQXj2qO9M0uPNZfeAex0qMkU2fouQWllMuKd/
|
||||
3gA2itECgYEA75tbNxRWmUq/1smOYF2Pi95mzduML9xcvopq6GzG/c7fskqhR5ht
|
||||
a8b/VjGvxQAoHsj72fFlROoABU1cuSc8fC0vQ4nssc3lN2WQIYHLaCTDzXy9Pze4
|
||||
p3gaxUPC2f7NWMREUoQTJt2MERGtvmKFXbpHGeiWUImTydsHNSNDPQ0CgYEAxsVt
|
||||
NN5XgHoMU5XFcAt8sequluFJGhs+Cb7GvYey9qv58OTd2Jv1DeBbkFBqnD9gZZGy
|
||||
ts/OUnu99td3MteftZDuPU8U2yo0SgnjZL+44iEyVLlsuIeHfavnKIzg1qoJCWuu
|
||||
omdwxgurNCGx5jviDQvEOUKm6WghTW1WDTxLZ2sCgYEAtz3QnGbpc4I/BDxQrlHf
|
||||
HdCQPo7Qvyl/pBineej2pdQ4L1nzzZU82VfunjSRf8+G30RFl3+NOw7ZxTRM3Sys
|
||||
jSrhIn2wjqovyhXaDEX/ET5MoDHtaRNsHGc10fboZV8AHAq9VX28R9TW8ZbbkOY3
|
||||
qF51UdMWYbFVXOIsuO6m1WECgYBXhnOyBf3NyvBGlfqcfdJonYhHU+hWoIxOyjzF
|
||||
FE3PpKaoVn8BdJsRgyuOfnqTVqzhzKg/K34Uf/yEBxirwJrI3oqpYHs0jn774yLI
|
||||
KEwG9sss14FyN+uHgPyGtJIEtFbKWSpKxPW5n0XB7NxjHxdI21eKRzksKfgQGgb8
|
||||
SQKDBQKBgQDt2eAgS82ZWBEVGegzmBsjJYIrN1TF7H8x6CyUzItX4elZjrqN0djX
|
||||
qaJw+EsvB4XZYKtI1+H2BiwprktE9w3ZReon8lnAWyz32LWfil3WaoaCZ3k1vp84
|
||||
ZS1dNzJCA9gZ+eAb8ziWPwpnbIYl63Zhg6JnSLUR1iWAlhHLUEKriQ==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
32
24 - HTTP Servers/httpserver/cookies.go
Normal file
32
24 - HTTP Servers/httpserver/cookies.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"fmt"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func GetAndSetCookie(writer http.ResponseWriter, request *http.Request) {
|
||||
|
||||
counterVal := 1
|
||||
counterCookie, err := request.Cookie("counter")
|
||||
if (err == nil) {
|
||||
counterVal, _ = strconv.Atoi(counterCookie.Value)
|
||||
counterVal++
|
||||
}
|
||||
http.SetCookie(writer, &http.Cookie{
|
||||
Name: "counter", Value: strconv.Itoa(counterVal),
|
||||
})
|
||||
|
||||
if (len(request.Cookies()) > 0) {
|
||||
for _, c := range request.Cookies() {
|
||||
fmt.Fprintf(writer, "Cookie Name: %v, Value: %v", c.Name, c.Value)
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintln(writer, "Request contains no cookies")
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
http.HandleFunc("/cookies", GetAndSetCookie)
|
||||
}
|
||||
45
24 - HTTP Servers/httpserver/dynamic.go
Normal file
45
24 - HTTP Servers/httpserver/dynamic.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Context struct {
|
||||
Request *http.Request
|
||||
Data []Product
|
||||
}
|
||||
|
||||
var htmlTemplates *template.Template
|
||||
|
||||
func HandleTemplateRequest(writer http.ResponseWriter, request *http.Request) {
|
||||
path := request.URL.Path
|
||||
if (path == "") {
|
||||
path = "products.html"
|
||||
}
|
||||
t := htmlTemplates.Lookup(path)
|
||||
if (t == nil) {
|
||||
http.NotFound(writer, request)
|
||||
} else {
|
||||
err := t.Execute(writer, Context{ request, Products})
|
||||
if (err != nil) {
|
||||
http.Error(writer, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
htmlTemplates = template.New("all")
|
||||
htmlTemplates.Funcs(map[string]interface{} {
|
||||
"intVal": strconv.Atoi,
|
||||
})
|
||||
htmlTemplates, err = htmlTemplates.ParseGlob("templates/*.html")
|
||||
if (err == nil) {
|
||||
http.Handle("/templates/", http.StripPrefix("/templates/",
|
||||
http.HandlerFunc(HandleTemplateRequest)))
|
||||
} else {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
22
24 - HTTP Servers/httpserver/forms.go
Normal file
22
24 - HTTP Servers/httpserver/forms.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func ProcessFormData(writer http.ResponseWriter, request *http.Request) {
|
||||
if (request.Method == http.MethodPost) {
|
||||
index, _ := strconv.Atoi(request.PostFormValue("index"))
|
||||
p := Product {}
|
||||
p.Name = request.PostFormValue("name")
|
||||
p.Category = request.PostFormValue("category")
|
||||
p.Price, _ = strconv.ParseFloat(request.PostFormValue("price"), 64)
|
||||
Products[index] = p
|
||||
}
|
||||
http.Redirect(writer, request, "/templates", http.StatusTemporaryRedirect)
|
||||
}
|
||||
|
||||
func init() {
|
||||
http.HandleFunc("/forms/edit", ProcessFormData)
|
||||
}
|
||||
3
24 - HTTP Servers/httpserver/go.mod
Normal file
3
24 - HTTP Servers/httpserver/go.mod
Normal file
@@ -0,0 +1,3 @@
|
||||
module httpserver
|
||||
|
||||
go 1.17
|
||||
15
24 - HTTP Servers/httpserver/json.go
Normal file
15
24 - HTTP Servers/httpserver/json.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
func HandleJsonRequest(writer http.ResponseWriter, request *http.Request) {
|
||||
writer.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(writer).Encode(Products)
|
||||
}
|
||||
|
||||
func init() {
|
||||
http.HandleFunc("/json", HandleJsonRequest)
|
||||
}
|
||||
49
24 - HTTP Servers/httpserver/main.go
Normal file
49
24 - HTTP Servers/httpserver/main.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type StringHandler struct {
|
||||
message string
|
||||
}
|
||||
|
||||
func (sh StringHandler) ServeHTTP(writer http.ResponseWriter,
|
||||
request *http.Request) {
|
||||
Printfln("Request for %v", request.URL.Path)
|
||||
io.WriteString(writer, sh.message)
|
||||
}
|
||||
|
||||
func HTTPSRedirect(writer http.ResponseWriter,
|
||||
request *http.Request) {
|
||||
host := strings.Split(request.Host, ":")[0]
|
||||
target := "https://" + host + ":5500" + request.URL.Path
|
||||
if len(request.URL.RawQuery) > 0 {
|
||||
target += "?" + request.URL.RawQuery
|
||||
}
|
||||
http.Redirect(writer, request, target, http.StatusTemporaryRedirect)
|
||||
}
|
||||
|
||||
func main() {
|
||||
http.Handle("/message", StringHandler{ "Hello, World"})
|
||||
http.Handle("/favicon.ico", http.NotFoundHandler())
|
||||
http.Handle("/", http.RedirectHandler("/message", http.StatusTemporaryRedirect))
|
||||
|
||||
fsHandler := http.FileServer(http.Dir("./static"))
|
||||
http.Handle("/files/", http.StripPrefix("/files", fsHandler))
|
||||
|
||||
go func () {
|
||||
err := http.ListenAndServeTLS(":5500", "certificate.cer",
|
||||
"certificate.key", nil)
|
||||
if (err != nil) {
|
||||
Printfln("HTTPS Error: %v", err.Error())
|
||||
}
|
||||
}()
|
||||
|
||||
err := http.ListenAndServe(":5000", http.HandlerFunc(HTTPSRedirect))
|
||||
if (err != nil) {
|
||||
Printfln("Error: %v", err.Error())
|
||||
}
|
||||
}
|
||||
7
24 - HTTP Servers/httpserver/printer.go
Normal file
7
24 - HTTP Servers/httpserver/printer.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func Printfln(template string, values ...interface{}) {
|
||||
fmt.Printf(template + "\n", values...)
|
||||
}
|
||||
17
24 - HTTP Servers/httpserver/product.go
Normal file
17
24 - HTTP Servers/httpserver/product.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package main
|
||||
|
||||
type Product struct {
|
||||
Name, Category string
|
||||
Price float64
|
||||
}
|
||||
|
||||
var Products = []Product {
|
||||
{ "Kayak", "Watersports", 279 },
|
||||
{ "Lifejacket", "Watersports", 49.95 },
|
||||
{ "Soccer Ball", "Soccer", 19.50 },
|
||||
{ "Corner Flags", "Soccer", 34.95 },
|
||||
{ "Stadium", "Soccer", 79500 },
|
||||
{ "Thinking Cap", "Chess", 16 },
|
||||
{ "Unsteady Chair", "Chess", 75 },
|
||||
{ "Bling-Bling King", "Chess", 1200 },
|
||||
}
|
||||
7
24 - HTTP Servers/httpserver/static/bootstrap.min.css
vendored
Normal file
7
24 - HTTP Servers/httpserver/static/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
13
24 - HTTP Servers/httpserver/static/index.html
Normal file
13
24 - HTTP Servers/httpserver/static/index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Pro Go</title>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link href="bootstrap.min.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="m-1 p-2 bg-primary text-white h2">
|
||||
Hello, World
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
22
24 - HTTP Servers/httpserver/static/store.html
Normal file
22
24 - HTTP Servers/httpserver/static/store.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Pro Go</title>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link href="bootstrap.min.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="m-1 p-2 bg-primary text-white h2 text-center">
|
||||
Products
|
||||
</div>
|
||||
<table class="table table-sm table-bordered table-striped">
|
||||
<thead>
|
||||
<tr><th>Name</th><th>Category</th><th>Price</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>Kayak</td><td>Watersports</td><td>$279.00</td></tr>
|
||||
<tr><td>Lifejacket</td><td>Watersports</td><td>$49.95</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
29
24 - HTTP Servers/httpserver/static/upload.html
Normal file
29
24 - HTTP Servers/httpserver/static/upload.html
Normal file
@@ -0,0 +1,29 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Pro Go</title>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<link href="bootstrap.min.css" rel="stylesheet" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="m-1 p-2 bg-primary text-white h2 text-center">
|
||||
Upload File
|
||||
</div>
|
||||
<form method="POST" action="/forms/upload" class="p-2"
|
||||
enctype="multipart/form-data">
|
||||
<div class="form-group">
|
||||
<label class="form-label">Name</label>
|
||||
<input class="form-control" type="text" name="name">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">City</label>
|
||||
<input class="form-control" type="text" name="city">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="form-label">Choose Files</label>
|
||||
<input class="form-control" type="file" name="files" multiple>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary mt-2">Upload</button>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
45
24 - HTTP Servers/httpserver/templates/edit.html
Normal file
45
24 - HTTP Servers/httpserver/templates/edit.html
Normal file
@@ -0,0 +1,45 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Pro Go</title>
|
||||
<link rel="stylesheet" href="/files/bootstrap.min.css" >
|
||||
</head>
|
||||
<body>
|
||||
{{ $index := intVal (index (index .Request.URL.Query "index") 0) }}
|
||||
{{ if lt $index (len .Data)}}
|
||||
{{ with index .Data $index}}
|
||||
<h3 class="bg-primary text-white text-center p-2 m-2">Product</h3>
|
||||
<form method="POST" action="/forms/edit" class="m-2">
|
||||
<div class="form-group">
|
||||
<label>Index</label>
|
||||
<input name="index" value="{{$index}}"
|
||||
class="form-control" disabled />
|
||||
<input name="index" value="{{$index}}" type="hidden" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Name</label>
|
||||
<input name="name" value="{{.Name}}" class="form-control"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Category</label>
|
||||
<input name="category" value="{{.Category}}"
|
||||
class="form-control"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>Price</label>
|
||||
<input name="price" value="{{.Price}}" class="form-control"/>
|
||||
</div>
|
||||
<div class="mt-2">
|
||||
<button type="submit" class="btn btn-primary">Save</button>
|
||||
<a href="/templates/" class="btn btn-secondary">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
<h3 class="bg-danger text-white text-center p-2">
|
||||
No Product At Specified Index
|
||||
</h3>
|
||||
{{end }}
|
||||
</body>
|
||||
</html>
|
||||
33
24 - HTTP Servers/httpserver/templates/products.html
Normal file
33
24 - HTTP Servers/httpserver/templates/products.html
Normal file
@@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Pro Go</title>
|
||||
<link rel="stylesheet" href="/files/bootstrap.min.css" >
|
||||
</head>
|
||||
<body>
|
||||
<h3 class="bg-primary text-white text-center p-2 m-2">Products</h3>
|
||||
<div class="p-2">
|
||||
<table class="table table-sm table-striped table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Index</th><th>Name</th><th>Category</th>
|
||||
<th class="text-end">Price</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{ range $index, $product := .Data }}
|
||||
<tr>
|
||||
<td>{{ $index }}</td>
|
||||
<td>{{ $product.Name }}</td>
|
||||
<td>{{ $product.Category }}</td>
|
||||
<td class="text-end">
|
||||
{{ printf "$%.2f" $product.Price }}
|
||||
</td>
|
||||
</tr>
|
||||
{{ end }}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
32
24 - HTTP Servers/httpserver/upload.go
Normal file
32
24 - HTTP Servers/httpserver/upload.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"io"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func HandleMultipartForm(writer http.ResponseWriter, request *http.Request) {
|
||||
request.ParseMultipartForm(10000000)
|
||||
fmt.Fprintf(writer, "Name: %v, City: %v\n",
|
||||
request.MultipartForm.Value["name"][0],
|
||||
request.MultipartForm.Value["city"][0])
|
||||
fmt.Fprintln(writer, "------")
|
||||
|
||||
for _, header := range request.MultipartForm.File["files"] {
|
||||
fmt.Fprintf(writer, "Name: %v, Size: %v\n", header.Filename, header.Size)
|
||||
file, err := header.Open()
|
||||
if (err == nil) {
|
||||
defer file.Close()
|
||||
fmt.Fprintln(writer, "------")
|
||||
io.Copy(writer, file)
|
||||
} else {
|
||||
http.Error(writer, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
http.HandleFunc("/forms/upload", HandleMultipartForm)
|
||||
}
|
||||
Reference in New Issue
Block a user