diff --git a/drpc-beacon-proxy/Dockerfile b/drpc-beacon-proxy/Dockerfile index 7793149a..b548d549 100644 --- a/drpc-beacon-proxy/Dockerfile +++ b/drpc-beacon-proxy/Dockerfile @@ -1,9 +1,21 @@ -FROM python:3.11-slim +# Use a Go base image +FROM golang:1.20-alpine +# Set the working directory in the container WORKDIR /app -RUN pip install flask requests +# Copy the Go files into the container +COPY . . -COPY proxy.py /app/ +# Build the Go application +RUN go build -o proxy-server . -CMD ["python", "proxy.py"] +# Set environment variables for DKEY and TARGET_URL +ENV DKEY="Ate9WjrXn0VNqbW90nyMLzBECtvs-kcR754SnqSgS7QB" +ENV TARGET_URL="https://lb.drpc.org/rest/eth-beacon-chain-holesky" + +# Expose port 80 +EXPOSE 80 + +# Run the Go proxy server +CMD ["./proxy-server"] diff --git a/drpc-beacon-proxy/go_proxy.go b/drpc-beacon-proxy/go_proxy.go new file mode 100644 index 00000000..004655b1 --- /dev/null +++ b/drpc-beacon-proxy/go_proxy.go @@ -0,0 +1,95 @@ +package main + +import ( + "bytes" + "compress/gzip" + "fmt" + "io" + "log" + "net/http" + "net/url" + "os" +) + +var targetBaseURL string + +func init() { + // Set the target base URL from environment variable or default value + targetBaseURL = os.Getenv("TARGET_URL") + if targetBaseURL == "" { + targetBaseURL = "https://lb.drpc.org/rest/eth-beacon-chain-holesky" + } +} + +func proxyHandler(w http.ResponseWriter, r *http.Request) { + // Parse the incoming request + subpath := r.URL.Path + query := r.URL.Query() + + // Add the dkey parameter to the query string + dkey := os.Getenv("DKEY") + if dkey == "" { + dkey = "your-default-dkey" + } + query.Set("dkey", dkey) + + // Build the new URL for the request + proxyURL := fmt.Sprintf("%s%s?%s", targetBaseURL, subpath, query.Encode()) + log.Printf("Forwarding request to: %s", proxyURL) + + // Create a new HTTP request to forward to the upstream API + req, err := http.NewRequest(r.Method, proxyURL, r.Body) + if err != nil { + http.Error(w, "Error creating request: "+err.Error(), http.StatusInternalServerError) + return + } + + // Copy the incoming request headers to the new request, except for 'Host' and 'Accept-Encoding' + req.Header = r.Header.Clone() + req.Header.Del("Host") + req.Header.Del("Accept-Encoding") + + // Send the request to the upstream API + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + http.Error(w, "Error forwarding request: "+err.Error(), http.StatusInternalServerError) + return + } + defer resp.Body.Close() + + // Handle the response + body := resp.Body + if resp.Header.Get("Content-Encoding") == "gzip" { + log.Println("Response is gzipped, decompressing...") + // Decompress the gzip response + gzipReader, err := gzip.NewReader(resp.Body) + if err != nil { + http.Error(w, "Error decompressing gzip response: "+err.Error(), http.StatusInternalServerError) + return + } + defer gzipReader.Close() + body = gzipReader + } + + // Write the response headers and body back to the client + for key, values := range resp.Header { + for _, value := range values { + w.Header().Add(key, value) + } + } + w.WriteHeader(resp.StatusCode) + io.Copy(w, body) +} + +func main() { + // Set up the HTTP server + http.HandleFunc("/", proxyHandler) + + port := ":80" + log.Printf("Starting proxy server on port %s", port) + err := http.ListenAndServe(port, nil) + if err != nil { + log.Fatalf("Error starting server: %s", err) + } +}