Proxy inverso con GOlang | Proxy inverso con GOlang con Docker | Servidor Proxy con GOlang | Proxy reverse with GOlang | Proxy reverse with GOlang and Docker

Proxy inverso con GOlang | Proxy inverso con GOlang con Docker | Servidor Proxy con GOlang | Proxy reverse with GOlang | Proxy reverse with GOlang and Docker


El proxy inverso (proxy reverse) es un controlador de solicitudes HTTP, recibe una petición (entrante) y la envía a otro servidor, garantizando que el cliente obtenga la respuesta.


Objetivo


Crear un Proxy reverse/Proxy inverso con GOlang, garantizando:


  • Múltiples backend.

  • El proxy aceptará múltiples peticiones.

  • Tiempos de respuestas óptimos.

  • Consumo de pocos recursos máquina.


Requisitos:


  • go version go1.14.4 o superior



En Acción:


main.go
#package main

import (
"net/http"
"os"
"os/signal"
"syscall"
"time"
)

const APP_NAME string = "MS_REVERSE_PROXY"

func SetupCloseHandler() {
c := make(chan os.Signal)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
go func() {
<-c
Log.Println("\r- Ctrl+C pressed in Terminal")
os.Exit(0)
}()
}

func middlewareOne(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
next.ServeHTTP(w, r)
})
}

func main() {
mux := http.NewServeMux()
finalHandler := http.HandlerFunc(HandleRequestAndRedirect)
mux.Handle("/", middlewareOne(finalHandler))

srvHTTPs := &http.Server{
ReadTimeout: 20 * time.Second,
WriteTimeout: 20 * time.Second,
IdleTimeout: 120 * time.Second,
Addr: ":4443",
Handler: mux,
}
Log.Fatal(srvHTTPs.ListenAndServe())
}




handlers.go
package main

import (
"net/http"
"net/http/httputil"
"net/url"
)

/*Realiza el envío de la petición al backend destino*/
func ServeReverseProxy(target string, w http.ResponseWriter, r *http.Request) {
url, _ := url.Parse(target)
proxy := httputil.NewSingleHostReverseProxy(url)
r.URL.Host = url.Host
r.URL.Scheme = url.Scheme
r.Header.Set("X-Forwarded-Host", url.Host)
r.Host = url.Host
proxy.ServeHTTP(w, r)
return
}

/*Busca el HOST dentro de los backend permitidos*/
func GetNewProxyUrl(urlSource *url.URL, host string) string {
var newServer, _ = ALLOW_HOST[host]
if newServer != "" {
return newServer
} else {
return ""
}
}

/* Redirecciona la página 404 - Página no encontrada*/
func RedirectNotFound(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "https://soursop-dev.blogspot.com/404.html", http.StatusSeeOther)
return
}

/* Recibe la petición, obtiene el host y si este se encuentra dentro de la
lista de host permitidos, realiza el envío al backend.*/
func HandleRequestAndRedirect(w http.ResponseWriter, r *http.Request) {
Log.Println("Llega la petición", r.Host, r.URL.String())
url := GetNewProxyUrl(r.URL, r.Host)
if url == "" {
Log.Println("Host no existe " + r.URL.String())
RedirectNotFound(w, r)
return
} else {
Log.Println("Se redirecciona a ", url)
ServeReverseProxy(url, w, r)
return
}
}




util.go
package main

import (
"net/url"
"os"
)

var environment = UtilGetEnvironment()

var ALLOW_HOST = map[string]string{
"soursop-dev.blogspot.com": UtilHostTarget(),
}

func UtilGetEnvironment() string {
return os.Getenv("ENVIRONMENT")
}

func UtilHostTarget() string {
var URL = "soursop-dev.blogspot.com"
var scheme = "https"
url := url.URL{
Scheme: scheme,
Host: URL,
}
return url.String()
}




Explicación


Básicamente el proxy recibe la petición http y si el host esta definido en un mapa, realiza el rediccionamiento al backend correspondiente.

Código fuentes:


Notas finales:

En términos generales el proxy inverso tiene muy buen rendimiento.

* Tiempos dependen del tiempo de respuesta del backend.


No olvides compartir y dar +1

-

Próximos eventos:

* Proxy inverso con GOlang/Proxy reverse with GOlang + DOCKER
* GOlang + Docker
* Habilitar https en GOlang
* Ejecutar código HTML estático en DOCKER
* Microservicios en Python
* Python+MongoDB: CRUD
* Python+MongoDB+GridFS: Almacenamiento de archivos
* Colas - Queue Python: Envío de mensajes
* Python+AWS+SNS: Envío de mensajes de textos.
* Python3: Creación de un Chatbot básico
* NodeJS+MongoDB: CRUD

El orden de los eventos puede cambiar

Comentarios

Entradas más populares de este blog

Ejemplo Log4j 2 en JAVA | Log4j 2 en Springboot | Configuración Log4j 2 | Log4j 2 in SpringBoot| Example Log4j 2 in SpringBoot | Configuring Log4j 2

Python: Inyección de dependencias

GOlang con Docker | GOlang with Docker | GO con Docker | GO with Docker