2025-01-05 16:28:42 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2025-01-06 11:03:58 +00:00
|
|
|
"bytes"
|
2025-01-05 16:28:42 +00:00
|
|
|
"fmt"
|
2025-01-06 11:03:58 +00:00
|
|
|
"io"
|
|
|
|
"math/rand/v2"
|
|
|
|
"net/http"
|
2025-01-05 16:28:42 +00:00
|
|
|
"os"
|
2025-01-06 11:03:58 +00:00
|
|
|
"strings"
|
|
|
|
"time"
|
2025-01-05 16:28:42 +00:00
|
|
|
)
|
|
|
|
|
2025-01-06 11:03:58 +00:00
|
|
|
/*
|
|
|
|
Connect:
|
|
|
|
1. Client A: Create URL with public key and ID to reach on
|
|
|
|
2. Client B: Parses URL, generate AES key, upload key to storage
|
|
|
|
3. Client A: Polls for storage on server
|
|
|
|
*/
|
|
|
|
|
|
|
|
func get(id string) ([]byte, error) {
|
|
|
|
res, err := http.Get(fmt.Sprintf("http://localhost:3000/store/%s", id))
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
defer res.Body.Close()
|
|
|
|
|
|
|
|
if res.StatusCode != http.StatusOK {
|
|
|
|
return nil, fmt.Errorf("failed to get")
|
|
|
|
}
|
|
|
|
|
|
|
|
data, err := io.ReadAll(res.Body)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return data, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func put(id string, data []byte) error {
|
|
|
|
req, err := http.NewRequest(
|
|
|
|
http.MethodPut,
|
|
|
|
fmt.Sprintf("http://localhost:3000/store/%s", id),
|
|
|
|
bytes.NewReader(data),
|
|
|
|
)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
res, err := http.DefaultClient.Do(req)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
defer res.Body.Close()
|
|
|
|
if res.StatusCode != http.StatusNoContent {
|
|
|
|
return fmt.Errorf("failed to get")
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func randomId() string {
|
|
|
|
var charset = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
|
|
|
|
|
|
|
runes := make([]rune, 512)
|
|
|
|
for i := range runes {
|
|
|
|
runes[i] = charset[rand.IntN(len(charset))]
|
|
|
|
}
|
|
|
|
|
|
|
|
return string(runes)
|
|
|
|
}
|
|
|
|
|
|
|
|
func connect() (string, string) {
|
|
|
|
// link: chitchat:<temporary-id>
|
|
|
|
var selfId, partnerId string
|
|
|
|
selfId = randomId()
|
|
|
|
|
|
|
|
fmt.Printf("Your ID: %s\n", selfId)
|
|
|
|
fmt.Printf("Partner ID: ")
|
|
|
|
fmt.Scanln(&partnerId)
|
|
|
|
|
|
|
|
partnerId = strings.TrimSpace(partnerId)
|
|
|
|
return selfId, partnerId
|
|
|
|
}
|
|
|
|
|
|
|
|
func pollPartner(partnerId string) {
|
|
|
|
var message string
|
|
|
|
|
|
|
|
for {
|
|
|
|
time.Sleep(5 * time.Second)
|
|
|
|
|
|
|
|
data, err := get(partnerId)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("Failed to poll: %s\n", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
partnerId, message, _ = strings.Cut(string(data), ":")
|
|
|
|
fmt.Printf("%s\n", message)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func pollInput(selfId string) {
|
|
|
|
var message string
|
|
|
|
|
|
|
|
for {
|
|
|
|
fmt.Scanln(&message)
|
|
|
|
nextId := randomId()
|
|
|
|
data := fmt.Sprintf("%s:%s", nextId, message)
|
|
|
|
|
|
|
|
err := put(selfId, []byte(data))
|
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("Failed to put: %s\n", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
selfId = nextId
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-01-05 16:28:42 +00:00
|
|
|
func run() error {
|
2025-01-06 11:03:58 +00:00
|
|
|
selfId, partnerId := connect()
|
|
|
|
if partnerId == "" {
|
|
|
|
fmt.Printf("Waiting for partner to connect to you...\n")
|
|
|
|
|
|
|
|
for {
|
|
|
|
time.Sleep(5 * time.Second)
|
|
|
|
|
|
|
|
data, err := get(selfId)
|
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("Partner hasn't connected: %s\n", err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
partnerId = string(data)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
err := put(partnerId, []byte(selfId))
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("failed to put next id: %w", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Printf("Your ID: %s\n", selfId)
|
|
|
|
fmt.Printf("Partner ID: %s\n", partnerId)
|
|
|
|
|
|
|
|
fmt.Printf("Chat away!\n")
|
|
|
|
|
|
|
|
go pollInput(partnerId)
|
|
|
|
go pollPartner(selfId)
|
|
|
|
for {
|
|
|
|
}
|
|
|
|
|
2025-01-05 16:28:42 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
err := run()
|
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("%s\n", err)
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
}
|