Skip to content

Commit

Permalink
feat: create initial proxy logic
Browse files Browse the repository at this point in the history
Signed-off-by: Smuu <18609909+Smuu@users.noreply.github.com>
  • Loading branch information
smuu committed Oct 24, 2023
1 parent 2c92264 commit b067ff6
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 0 deletions.
25 changes: 25 additions & 0 deletions .github/workflows/docker-build-publish.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Docker Build & Publish

# Trigger on all push events, new semantic version tags, and all PRs
on:
push:
branches:
- "main"
- "v[0-9].[0-9].x"
- "v[0-9].[0-9][0-9].x"
- "v[0-9].x"
tags:
- "v[0-9]+.[0-9]+.[0-9]+"
- "v[0-9]+.[0-9]+.[0-9]+-alpha.[0-9]+"
- "v[0-9]+.[0-9]+.[0-9]+-beta.[0-9]+"
- "v[0-9]+.[0-9]+.[0-9]+-rc[0-9]+"
pull_request:

jobs:
docker-security-build:
permissions:
contents: write
packages: write
uses: celestiaorg/.github/.github/workflows/reusable_dockerfile_pipeline.yml@v0.2.8 # yamllint disable-line rule:line-length
with:
dockerfile: Dockerfile
27 changes: 27 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Use the official Golang image to create a build artifact.
FROM golang:1.21.1 AS builder

# Set the working directory inside the container.
WORKDIR /app

# Copy go mod and sum files
#COPY go.mod go.sum ./
COPY go.mod ./

# Download all dependencies.
RUN go mod download

# Copy the source code into the container.
COPY . .

# Build the Go app
RUN CGO_ENABLED=0 GOOS=linux go build -o main .

# Use a lightweight image for the final image.
FROM alpine:3

# Copy the binary.
COPY --from=builder /app/main /app/main

# Run the binary.
CMD ["/app/main"]
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/celestiaorg/autoscale-proxy

go 1.21.1
82 changes: 82 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package main

import (
"bytes"
"io"
"net/http"
"strings"
)

func replaceDomainInResponse(originalSubdomain, replaceSubdomain, originalDomain string, buffer *bytes.Buffer) {
body := buffer.String()
fullReplace := replaceSubdomain + "." + "lunaroasis.net" // We know that statescale and snapscale are under this domain
fullOriginal := originalSubdomain + "." + originalDomain // Original domain can vary
replacedBody := strings.ReplaceAll(body, fullReplace, fullOriginal)
buffer.Reset()
buffer.WriteString(replacedBody)
}

func proxyRequest(fullSubdomain, path string, buffer *bytes.Buffer, r *http.Request) (int, map[string]string, error) {
client := &http.Client{}
target := "https://" + fullSubdomain + ".lunaroasis.net" + path
newReq, err := http.NewRequest(r.Method, target, r.Body)
if err != nil {
return 0, nil, err
}
newReq.Header = r.Header

resp, err := client.Do(newReq)
if err != nil {
return 0, nil, err
}
defer resp.Body.Close()

headers := make(map[string]string)
for key, values := range resp.Header {
for _, value := range values {
headers[key] = value
}
}

io.Copy(buffer, resp.Body)
return resp.StatusCode, headers, nil
}

func handleRequest(w http.ResponseWriter, r *http.Request) {
hostParts := strings.Split(r.Host, ".")
if len(hostParts) < 3 {
http.Error(w, "Invalid domain", http.StatusBadRequest)
return
}

subdomain := hostParts[0] // Extract original domain
originalDomain := strings.Join(hostParts[1:], ".")

buffer := new(bytes.Buffer)
backupBuffer := new(bytes.Buffer)

statusCode, headers, err := proxyRequest(subdomain+".statescale", r.RequestURI, buffer, r)
if err != nil || statusCode >= 400 {
backupStatusCode, backupHeaders, _ := proxyRequest(subdomain+".snapscale", r.RequestURI, backupBuffer, r)
replaceDomainInResponse(subdomain, subdomain+".snapscale", originalDomain, backupBuffer)

for key, value := range backupHeaders {
w.Header().Set(key, value)
}
w.WriteHeader(backupStatusCode)
io.Copy(w, backupBuffer)
return
}

replaceDomainInResponse(subdomain, subdomain+".statescale", originalDomain, buffer)
for key, value := range headers {
w.Header().Set(key, value)
}
w.WriteHeader(statusCode)
io.Copy(w, buffer)
}

func main() {
http.HandleFunc("/", handleRequest)
http.ListenAndServe(":8080", nil)
}

0 comments on commit b067ff6

Please sign in to comment.