-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement create a bin, better output, bins in memory
- Loading branch information
1 parent
edce8bc
commit f3d3f85
Showing
2 changed files
with
115 additions
and
25 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
POST /r/ HTTP/1.1 | ||
Host: 316e-174-81-238-56.ngrok.io | ||
User-Agent: curl/7.68.0 | ||
Content-Length: 28 | ||
Accept: */* | ||
Accept-Encoding: gzip | ||
Content-Type: application/json | ||
X-Forwarded-For: 192.222.245.48 | ||
X-Forwarded-Proto: https | ||
|
||
{"dragons": "are dangerous"} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,130 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"fmt" | ||
"log" | ||
"math/rand" | ||
"net/http" | ||
"os" | ||
"net/http/httputil" | ||
"time" | ||
) | ||
|
||
var letters = []rune("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") | ||
|
||
type BinStore struct { | ||
Bins map[string][]string | ||
randGen *rand.Rand | ||
} | ||
|
||
func NewBinStore() *BinStore { | ||
source := rand.NewSource(time.Now().UnixNano()) | ||
gen := rand.New(source) | ||
|
||
return &BinStore{make(map[string][]string), gen} | ||
} | ||
|
||
func (store *BinStore) NewBin() string { | ||
b := make([]rune, 8) | ||
for i := range b { | ||
b[i] = letters[store.randGen.Intn(len(letters))] | ||
} | ||
|
||
result := string(b) | ||
store.Bins[result] = []string{} | ||
|
||
return result | ||
} | ||
|
||
func (store BinStore) GetBin(binName string) ([]string, bool) { | ||
bin, exists := store.Bins[binName] | ||
return bin, exists | ||
} | ||
|
||
func (store *BinStore) AddRekwest(binName string, rekwest string) bool { | ||
_, exists := store.Bins[binName] | ||
if !exists { | ||
return false | ||
} | ||
|
||
binSize := len(store.Bins[binName]) | ||
|
||
if binSize >= 20 { | ||
store.Bins[binName] = store.Bins[binName][binSize+1-20:] | ||
} | ||
|
||
store.Bins[binName] = append(store.Bins[binName], rekwest) | ||
return true | ||
} | ||
|
||
var binStore = NewBinStore() | ||
|
||
func main() { | ||
http.HandleFunc("/r/", binHandler) | ||
http.HandleFunc("/", rootHandler) | ||
log.Fatal(http.ListenAndServe(":8080", nil)) | ||
} | ||
|
||
func rootHandler(w http.ResponseWriter, r *http.Request) { | ||
fmt.Fprintf(w, "<h1>Welcome to Rekwest Bin</h1><form method='POST' action='/r/'><button type='submit'>Create a bin</button></form>") | ||
} | ||
|
||
func binHandler(w http.ResponseWriter, r *http.Request) { | ||
if r.Method == "POST" { | ||
binName := binStore.NewBin() | ||
|
||
http.Redirect(w, r, "/r/"+binName+"?inspect", 302) | ||
return | ||
} | ||
|
||
hash := r.URL.Path[len("/r/"):] | ||
binAddress := fmt.Sprintf("http://%s/r/%s", r.Host, hash) | ||
|
||
if r.URL.RawQuery == "inspect" { | ||
rekwest, err := loadRequest(hash) | ||
rekwests, exists := loadRequest(hash) | ||
|
||
if err != nil { | ||
if !exists { | ||
http.NotFound(w, r) | ||
return | ||
} | ||
|
||
fmt.Fprintf(w, "<h1>Here is the last rekwest:</h1><p>%s</p>", rekwest) | ||
fmt.Fprintf(w, "<h1>Here are your rekwests:</h1>") | ||
if len(rekwests) == 0 { | ||
fmt.Fprintf(w, "<h2>No rekwests</h2>") | ||
fmt.Fprintf(w, "<p>Make a request to: %s", binAddress) | ||
fmt.Fprintf(w, "<p>View request at: %s", binAddress+"?inspect") | ||
} | ||
|
||
for i, rekwest := range rekwests { | ||
fmt.Fprintf(w, "<h2>Rekwest %d</h2><p>%s</p>", i+1, rekwest) | ||
} | ||
} else { | ||
var buf bytes.Buffer | ||
r.Write(&buf) | ||
requestString := buf.Bytes() | ||
dump, err := httputil.DumpRequest(r, true) | ||
|
||
if err != nil { | ||
http.Error(w, fmt.Sprint(err), http.StatusInternalServerError) | ||
return | ||
} | ||
|
||
saveRequest(hash, requestString) | ||
dump = append([]byte("<pre>"), dump...) | ||
dump = append([]byte(dump), []byte("</pre>")...) | ||
|
||
fmt.Fprintf(w, "<h1>Request saved</h1><p>%s</p>", r.RemoteAddr) | ||
} | ||
} | ||
requesterIP := r.Header.Get("X-Forwarded-For") | ||
|
||
func main() { | ||
http.HandleFunc("/r/", binHandler) | ||
log.Fatal(http.ListenAndServe(":8080", nil)) | ||
if saveRequest(hash, dump) { | ||
fmt.Fprintf(w, "<h1>Request saved</h1><p>%s</p>", requesterIP) | ||
fmt.Fprintf(w, "<p><a href=%s>View requests</a>", binAddress+"?inspect") | ||
} else { | ||
http.NotFound(w, r) | ||
} | ||
} | ||
} | ||
|
||
func saveRequest(hash string, request []byte) error { | ||
filename := hash + ".txt" | ||
return os.WriteFile("./rekwests/"+filename, request, 0600) | ||
func saveRequest(hash string, rekwest []byte) bool { | ||
success := binStore.AddRekwest(hash, string(rekwest)) | ||
return success | ||
} | ||
|
||
func loadRequest(hash string) ([]byte, error) { | ||
filename := hash + ".txt" | ||
body, err := os.ReadFile(filename) | ||
if err != nil { | ||
return []byte{}, err | ||
} | ||
return body, nil | ||
func loadRequest(hash string) ([]string, bool) { | ||
bins, exists := binStore.GetBin(hash) | ||
return bins, exists | ||
} |