Usando nginx para reescribir URL dentro de respuestas salientes

8

Tenemos un cliente con un sitio que se ejecuta en Apache. Recientemente, el sitio ha visto un aumento de la carga y, como un espacio intermedio, queremos cambiar todo el contenido estático del sitio a dominios sin cookies, por ejemplo http://static.thedomain.com.

La aplicación no se entiende bien. Entonces, para darles a los desarrolladores tiempo para enmendar el código para que apunten sus enlaces al servidor de contenido estático ( http://static.thedomain.com), pensé en enviar el sitio proxy a través de nginx y reescribir las respuestas salientes de modo que los enlaces /images/...se vuelvan a escribir como http://static.thedomain.com/images/....

Entonces, por ejemplo, en la respuesta de Apache a nginx hay un blob de encabezados + HTML. En el HTML devuelto por Apache tenemos <img>etiquetas que se ven así:

<img src="/images/someimage.png" />

Quiero transformar esto a:

<img src="http://static.thedomain.com/images/someimage.png" />

Para que el navegador al recibir la página HTML solicite las imágenes directamente desde el servidor de contenido estático.

¿Es esto posible con nginx (o HAProxy)?

He tenido una mirada superficial a través de los documentos, pero nada me llamó la atención, excepto reescribir las URL entrantes.

Kev
fuente

Respuestas:

5

Hay un http://wiki.nginx.org/HttpSubModule : "Este módulo puede buscar y reemplazar texto en la respuesta nginx".

copiar pasado de documentos:

Sintaxis:

sub_filter string replacement

Ejemplo:

location / {
  sub_filter      </head>
  '</head><script language="javascript" src="$script"></script>';
  sub_filter_once on;
}
Oleg Neumyvakin
fuente
¿Hay algo como esto para haproxy?
bradvido
@bradvido No he encontrado tal característica en haproxy.
Oleg Neumyvakin
3

Es mejor utilizar la función de proxy y buscar el contenido desde el lugar apropiado, en lugar de reescribir URL y enviar redireccionamientos al navegador.

Un buen ejemplo de contenido proxy se ve así:

#
#  This configuration file handles our main site - it attempts to
# serve content directly when it is static, and otherwise pass to
# an instance of Apache running upon 127.0.0.1:8080.
#
server {
    listen :80;

    server_name  www.debian-administration.org debian-administration.org;
        access_log  /var/log/nginx/d-a.proxied.log;

        #
        # Serve directly:  /images/ + /css/ + /js/
        #
    location ^~ /(images|css|js) {
        root   /home/www/www.debian-administration.org/htdocs/;
        access_log  /var/log/nginx/d-a.direct.log ;
    }

    #
    # Serve directly: *.js, *.css, *.rdf,, *.xml, *.ico, & etc
    #
    location ~* \.(js|css|rdf|xml|ico|txt|gif|jpg|png|jpeg)$ {
        root   /home/www/www.debian-administration.org/htdocs/;
        access_log  /var/log/nginx/d-a.direct.log ;
    }


        #
        # Proxy all remaining content to Apache
        #
        location / {

            proxy_pass         http://127.0.0.1:8080/;
            proxy_redirect     off;

            proxy_set_header   Host             $host;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

            client_max_body_size       10m;
            client_body_buffer_size    128k;

            proxy_connect_timeout      90;
            proxy_send_timeout         90;
            proxy_read_timeout         90;

            proxy_buffer_size          4k;
            proxy_buffers              4 32k;
            proxy_busy_buffers_size    64k;
            proxy_temp_file_write_size 64k;
        }
}

En esta configuración, en lugar de redirigir solicitudes static.domain.comy esperar que el navegador realice otra solicitud, nginx simplemente sirve el archivo desde la ruta local relevante. Si la solicitud es dinámica, el proxy se activa y obtiene la respuesta de un servidor Apache (local o remoto) sin que el usuario final lo sepa.

Espero que eso ayude

Tak
fuente
Gracias por el tiempo dedicado a responder esto. Instalaré una plataforma de prueba y veré cómo funciona. Lo importante aquí es mover todo el contenido estático fuera del servidor Apache. Entonces, supongo que podría ejecutar nginx en el servidor CDN y proxy_passconfigurarlo en el servidor Apache, por ejemplo proxy_pass http://172.16.3.1:80. es decir, trasladamos la dirección IP pública del sitio al servidor nginx / CDN.
Kev
Sí, eso es correcto. Y no hay problemas: ahora mismo estoy hasta las rodillas en nginx y me encanta.
Tak
No he olvidado tu respuesta :) Todavía no tuve la oportunidad de probar esto todavía.
Kev