-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 8adfa27
Showing
6 changed files
with
147 additions
and
0 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,7 @@ | ||
ADDR=":8888" | ||
LINK_PREVIEW_KEY="123456" | ||
|
||
# optional ssl certificates | ||
SSL_CERT="cert.pem" | ||
SSL_KEY="cert.key" | ||
|
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,2 @@ | ||
.env | ||
v1 |
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,20 @@ | ||
# LinkPreview.net Proxy Server in Go | ||
|
||
|
||
How to use: | ||
|
||
1. Download executable | ||
2. Create .env file configuration, see .env.example | ||
|
||
|
||
Sample .env file: | ||
|
||
``` | ||
ADDR="localhost:8000" | ||
LINK_PREVIEW_KEY="123456" | ||
``` | ||
|
||
3. Start your server | ||
|
||
|
||
|
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,8 @@ | ||
module linkpreview.net/proxy/v1 | ||
|
||
go 1.17 | ||
|
||
require ( | ||
github.com/joho/godotenv v1.4.0 | ||
github.com/muesli/cache2go v0.0.0-20211005105910-8e46465cca4a | ||
) |
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,4 @@ | ||
github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg= | ||
github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= | ||
github.com/muesli/cache2go v0.0.0-20211005105910-8e46465cca4a h1:IZxQOY9gAiiGGuEdlOBnqaC3yumj8UvyQluBNqGP2Ek= | ||
github.com/muesli/cache2go v0.0.0-20211005105910-8e46465cca4a/go.mod h1:WERUkUryfUWlrHnFSO/BEUZ+7Ns8aZy7iVOGewxKzcc= |
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,106 @@ | ||
package main | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"io" | ||
"log" | ||
"net/http" | ||
"os" | ||
"time" | ||
|
||
"github.com/joho/godotenv" | ||
"github.com/muesli/cache2go" | ||
) | ||
|
||
const linkpreviewAPI = "https://api.linkpreview.net" | ||
|
||
var linkpreviewKey = "" | ||
|
||
var cache *cache2go.CacheTable | ||
|
||
type cachedResponse struct { | ||
body []byte | ||
status int | ||
} | ||
|
||
type lpreq struct { | ||
Key string `json:"key"` | ||
Q string `json:"q"` | ||
Fields string `json:"fields"` | ||
} | ||
|
||
func main() { | ||
|
||
err := godotenv.Load() | ||
if err != nil { | ||
log.Fatal("Error loading .env file") | ||
} | ||
|
||
addr := os.Getenv("ADDR") | ||
linkpreviewKey = os.Getenv("LINK_PREVIEW_KEY") | ||
|
||
cache = cache2go.Cache("myCache") | ||
|
||
http.HandleFunc("/", proxyHandler) | ||
|
||
if os.Getenv("SSL_CERT") != "" && os.Getenv("SSL_KEY") != "" { | ||
fmt.Printf("Proxy secure server started on https://%s\n", addr) | ||
if err := http.ListenAndServeTLS(addr, os.Getenv("SSL_CERT"), os.Getenv("SSL_KEY"), nil); err != nil { | ||
panic(err) | ||
} | ||
} | ||
|
||
fmt.Printf("Proxy server started on http://%s\n", addr) | ||
if err := http.ListenAndServe(addr, nil); err != nil { | ||
panic(err) | ||
} | ||
|
||
} | ||
|
||
func proxyHandler(w http.ResponseWriter, r *http.Request) { | ||
|
||
query := r.URL.Query().Get("q") | ||
|
||
// keep results in cache for one day (based on the key scheme) | ||
cacheKey := fmt.Sprintf("%s%d", query, time.Now().Day()) | ||
|
||
cached, err := cache.Value(cacheKey) | ||
if err == nil { | ||
fmt.Println("Serving from Cache: " + query) | ||
w.WriteHeader(cached.Data().(*cachedResponse).status) | ||
w.Write(cached.Data().(*cachedResponse).body) | ||
return | ||
} | ||
|
||
body, _ := json.Marshal(&lpreq{ | ||
Key: linkpreviewKey, | ||
Q: query, | ||
Fields: "title,description,image,url", // see https://docs.linkpreview.net/#query-parameters | ||
}) | ||
|
||
fmt.Println("Requesting from the API: " + query) | ||
client := &http.Client{} | ||
req, _ := http.NewRequest("POST", linkpreviewAPI, bytes.NewBuffer(body)) | ||
resp, err := client.Do(req) | ||
if err != nil { | ||
http.Error(w, "Server Error", http.StatusInternalServerError) | ||
return | ||
} | ||
defer resp.Body.Close() | ||
|
||
cr := cachedResponse{} | ||
cr.body, err = io.ReadAll(resp.Body) | ||
cr.status = resp.StatusCode | ||
if err != nil { | ||
http.Error(w, "Server Error", http.StatusInternalServerError) | ||
return | ||
} | ||
|
||
w.WriteHeader(cr.status) | ||
w.Write(cr.body) | ||
|
||
// add to cache and automatically expire unused after one day | ||
cache.Add(cacheKey, 24*time.Hour, &cr) | ||
} |