This commit is contained in:
Tijl 2025-08-06 20:50:31 +02:00
parent 68ef0fbf6b
commit 4191898dad
Signed by: tijl
GPG Key ID: DAE24BFCD722F053
2 changed files with 16 additions and 45 deletions

View File

@ -1,11 +1,8 @@
package client package client
import ( import (
"bytes"
"encoding/binary" "encoding/binary"
"encoding/json"
"fmt" "fmt"
"log"
"net/http" "net/http"
"time" "time"
@ -18,7 +15,6 @@ type Client struct {
httpClient *http.Client httpClient *http.Client
prefix uint16 prefix uint16
gen *generation.Generator gen *generation.Generator
domain string // e.g. https://sho.rt
db *bolt.DB db *bolt.DB
retryQueue chan shortenJob retryQueue chan shortenJob
@ -26,13 +22,13 @@ type Client struct {
} }
// NewClient with persistence and retry queue // NewClient with persistence and retry queue
func NewClient(serverURL, domain string) (*Client, error) { func NewClient(serverURL string, folder string) (*Client, error) {
httpClient, baseURL, err := createHTTPClient(serverURL) httpClient, baseURL, err := createHTTPClient(serverURL)
if err != nil { if err != nil {
return nil, err return nil, err
} }
db, err := bolt.Open(dbFileName, 0600, &bolt.Options{Timeout: 1 * time.Second}) db, err := bolt.Open(folder+"/"+dbFileName, 0600, &bolt.Options{Timeout: 1 * time.Second})
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -40,7 +36,6 @@ func NewClient(serverURL, domain string) (*Client, error) {
cli := &Client{ cli := &Client{
serverURL: baseURL, serverURL: baseURL,
httpClient: httpClient, httpClient: httpClient,
domain: domain,
db: db, db: db,
retryQueue: make(chan shortenJob, 1000), retryQueue: make(chan shortenJob, 1000),
stopRetry: make(chan struct{}), stopRetry: make(chan struct{}),
@ -109,27 +104,10 @@ func NewClient(serverURL, domain string) (*Client, error) {
func (c *Client) Shorten(longURL string) string { func (c *Client) Shorten(longURL string) string {
shortID := c.gen.NextID() shortID := c.gen.NextID()
go func() { go c.enqueueJob(shortenJob{
payload := map[string]string{ ID: shortID,
"id": shortID, URL: longURL,
"url": longURL, })
}
data, _ := json.Marshal(payload)
req, err := http.NewRequest("POST", fmt.Sprintf("%s/shorten", c.serverURL), bytes.NewReader(data)) return shortID
if err != nil {
log.Println("shorten request build error:", err)
return
}
req.Header.Set("Content-Type", "application/json")
resp, err := c.httpClient.Do(req)
if err != nil {
log.Println("shorten request failed:", err)
return
}
defer resp.Body.Close()
}()
return fmt.Sprintf("%s/%s", c.domain, shortID)
} }

View File

@ -1,11 +1,13 @@
package client package client
import ( import (
"bytes" "encoding/binary"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"log" "log"
"net/http" "net/http"
"strings"
"time" "time"
bolt "go.etcd.io/bbolt" bolt "go.etcd.io/bbolt"
@ -23,19 +25,18 @@ type shortenJob struct {
} }
func (c *Client) registerPrefix() (uint16, error) { func (c *Client) registerPrefix() (uint16, error) {
resp, err := c.httpClient.Post(fmt.Sprintf("%s/register", c.serverURL), "application/json", nil) resp, err := c.httpClient.Get(fmt.Sprintf("%s/register", c.serverURL))
if err != nil { if err != nil {
return 0, err return 0, err
} }
defer resp.Body.Close() defer resp.Body.Close()
var result struct { bytes, err := io.ReadAll(resp.Body)
Prefix uint16 `json:"prefix"` if err != nil {
}
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return 0, err return 0, err
} }
return result.Prefix, nil
return binary.LittleEndian.Uint16(bytes), nil
} }
func (c *Client) loadRetryJobs() { func (c *Client) loadRetryJobs() {
@ -108,18 +109,10 @@ func (c *Client) deleteJobFromDB(job shortenJob) {
} }
func (c *Client) sendShortenJob(job shortenJob) error { func (c *Client) sendShortenJob(job shortenJob) error {
payload := map[string]string{ req, err := http.NewRequest("POST", fmt.Sprintf("%s/shorten?s=%s", c.serverURL, job.ID), strings.NewReader(job.URL))
"id": job.ID,
"url": job.URL,
}
data, _ := json.Marshal(payload)
req, err := http.NewRequest("POST", fmt.Sprintf("%s/shorten", c.serverURL), bytes.NewReader(data))
if err != nil { if err != nil {
return err return err
} }
req.Header.Set("Content-Type", "application/json")
resp, err := c.httpClient.Do(req) resp, err := c.httpClient.Do(req)
if err != nil { if err != nil {
return err return err