Skip to content

Commit

Permalink
Initial
Browse files Browse the repository at this point in the history
  • Loading branch information
JulianFun123 committed Jan 28, 2023
0 parents commit 96899ea
Show file tree
Hide file tree
Showing 14 changed files with 395 additions and 0 deletions.
Binary file added .DS_Store
Binary file not shown.
47 changes: 47 additions & 0 deletions .github/workflows/docker-hub.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

name: Publish Docker image

on:
release:
types: [published]

jobs:
push_to_registry:
name: Push Docker image to Docker Hub
runs-on: ubuntu-latest
steps:
- name: Check out the repo
uses: actions/checkout@v2

- name: Set up QEMU
uses: docker/setup-qemu-action@v2
with:
platforms: 'amd64,arm64'

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2

- name: Log in to Docker Hub
uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
with:
images: interaapps/punyshort-redirect-proxy

- name: Build and push Docker image
uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
23 changes: 23 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@


# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Dependency directories (remove the comment below to include it)
# vendor/

# Go workspace file
go.work
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/redirect-proxy.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM golang:1.19

# Set the Current Working Directory inside the container
WORKDIR /punyshort-proxy

# Copy everything from the current directory to the PWD (Present Working Directory) inside the container
COPY . .

# Download all the dependencies
RUN go get -d -v ./...

# Install the package
RUN go install -v ./...

# Run the executable
CMD ["punyshort-redirect-proxy"]
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Punyshort Redirection Proxy

```bash
docker run -p 80:80 \
-e PUNYSHORT_BASE_URL='https://api.punyshort.ga' \
-e PUNYSHORT_ERROR_URL='https://punyshort.ga/error-page' \
-e PUNYSHORT_KEY='xxx' \
-e PUNYSHORT_IP_FORWARDING='true' \
interaapps/punyshort-redirect-proxy
```

## Environment Variables
- PUNYSHORT_BASE_URL
- PUNYSHORT_KEY
- PUNYSHORT_IP_FORWARDING - Allow x-forwarded-for
- PUNYSHORT_ERROR_URL
- PUNYSHORT_USE_SSL: !! Experimental !! - Generating SSL Certificate with Let's Encrypt automatically
72 changes: 72 additions & 0 deletions apiclient/apiclient.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package apiclient

import (
"bytes"
"encoding/json"
"io"
"io/ioutil"
"net/http"
)

type PunyshortAPI struct {
baseUrl string
apiToken string
httpClient http.Client
}

func NewClient(baseUrl string, key string) PunyshortAPI {
api := PunyshortAPI{
baseUrl: "https://api.punyshort.ga",
httpClient: http.Client{},
}
api.SetBaseURL(baseUrl)
api.SetApiToken(key)
return api
}

func (apiClient *PunyshortAPI) SetApiToken(token string) {
apiClient.apiToken = token
}

func (apiClient *PunyshortAPI) SetBaseURL(baseURL string) {
apiClient.baseUrl = baseURL
}

func (apiClient PunyshortAPI) Request(method string, url string, body interface{}) (*http.Response, error) {
var bodyReader io.Reader = nil

if body != nil {
bodyJson, _ := json.Marshal(body)
bodyReader = bytes.NewReader(bodyJson)
}

req, err := http.NewRequest(method, apiClient.baseUrl+url, bodyReader)

if err != nil {
return nil, err
}
if apiClient.apiToken != "" {
req.Header.Set("Authorization", "Bearer "+apiClient.apiToken)
}
res, err := apiClient.httpClient.Do(req)

return res, err
}

func (apiClient PunyshortAPI) RequestMap(method string, url string, body interface{}, ma interface{}) (*http.Response, error) {
response, err := apiClient.Request(method, url, body)
if err != nil {
return response, err
}
all, err := ioutil.ReadAll(response.Body)

if err != nil {
return nil, err
}

err2 := json.Unmarshal(all, &ma)
if err2 != nil {
return nil, err2
}
return response, err
}
26 changes: 26 additions & 0 deletions apiclient/shortenlink.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package apiclient

type ShortenLink struct {
Error bool `json:"error"`
Exception string `json:"exception"`
Domain string `json:"path"`
Path string `json:"path"`
LongLink string `json:"long_link"`
}

type RedirectionData struct {
Domain string `json:"domain"`
Referrer string `json:"referrer"`
Ip string `json:"ip"`
Path string `json:"path"`
UserAgent string `json:"user_agent"`
}

func (apiClient PunyshortAPI) FollowRedirection(data RedirectionData) (ShortenLink, error) {
proxyConfig := ShortenLink{}
_, err := apiClient.RequestMap("POST", "/v1/follow", data, &proxyConfig)
if err != nil {
return ShortenLink{}, err
}
return proxyConfig, nil
}
10 changes: 10 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module punyshort-redirect-proxy

go 1.19

require golang.org/x/crypto v0.5.0

require (
golang.org/x/net v0.5.0 // indirect
golang.org/x/text v0.6.0 // indirect
)
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
42 changes: 42 additions & 0 deletions helper/redirect_proxy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package helper

import (
"errors"
"net"
"net/http"
"strings"
)

func GetIP(r *http.Request, allowForwarded bool) (string, error) {
ips := ""

if forwarded := r.Header.Get("X-Forwarded-For"); forwarded != "" && allowForwarded {
ips = forwarded
}

splitIps := strings.Split(ips, ",")

if len(splitIps) > 0 {
// get last IP in list since ELB prepends other user defined IPs, meaning the last one is the actual client IP.
netIP := net.ParseIP(splitIps[len(splitIps)-1])
if netIP != nil {
return netIP.String(), nil
}
}

ip, _, err := net.SplitHostPort(r.RemoteAddr)
if err != nil {
return "", err
}

netIP := net.ParseIP(ip)
if netIP != nil {
ip := netIP.String()
if ip == "::1" {
return "127.0.0.1", nil
}
return ip, nil
}

return "", errors.New("IP not found")
}
Loading

0 comments on commit 96899ea

Please sign in to comment.