---
# System prepended metadata

title: Apache2. Servidors d'aplicacions web
tags: [daw, ' M8']

---

---
title: Apache2. Servidors d'aplicacions web
tags: daw, M8
---
<div style="width: 45%; margin-left: auto;">

![](https://hackmd.io/_uploads/HJiR4eGJT.png)  
![image](https://hackmd.io/_uploads/By3ai4Bolx.png)

</div>

<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="Llicència de Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /></a><br />Aquesta obra està subjecta a una llicència de <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Reconeixement-CompartirIgual 4.0 Internacional de Creative Commons</a>

# Servidors d'aplicacions web
* [vincle a font en MarkDown](https://hackmd.io/@JdaXaviQ/S1MNdT4x9)

---
## 1. Common Gateway Interface (CGI).
CGI és el mecanisme més primitiu per a enviar contingut web dinàmic a través d'un servidor web. Utilitza variables d'entorn i els fluxos estàndar (stdin/stdout) per a comunicar amb el programa executat. A més, si estem cridant a un llenguatge interpretat com per exemple Python, necessita cridar a l'intèrpret quan es realitza la crida des del client.

Si esteu acostumats a servir aplicacions PHP en altres moduls, aquesta forma us semblarà molt natural, però no vol dir que sigui la millor.
Per a poder executar programes per CGI necessiteu habilitar el mòdul mod_cgi: ```sudo a2enmod cgi```

### Exemple de crida a un programa Python amb CGI clàssic.
El programa:
```python=
#!/usr/bin/python3
# -*- encodign: utf-8 -*-


def send_html_content():
    print("Content-type: text/html\n\n")
    print("<!DOCTYPE html>")
    print("<html><head><title>Hola DAW</title></head>")
    print("<body><h1>Hola DAW</h1></body></html>")

send_html_content()
```
Assegurar-s'hi de que té permisos d'execució '755'.
```bash=
-rwxr-xr-x 1 xavi xavi 269 feb 31 25:62 test.py
```
Habilitar l'execució d'scripts CGI al directori on hem desat el nostre programa:
```
<Directory /var/www/cgi-bin/>
        Options +ExecCGI
        AddHandler cgi-script .cgi .pl .py
        AllowOverride All
        Require all granted
</Directory>
```
I eventualment activar un nou servidor virtual si aquest directori queda fora dels directoris servits pels servidors actius.
## 2. Web Server Gateway Interface (WSGI).
WSGI és una interface desenvolupada per la comunitat Python que permet que els navegador puguin carregar l'intèrpret de Python de manera prèvia a l'arrivada de les peticions i que cada petició web es transformi en una crida a una funció que rep la informació d'entorn i una callback com a paràmetres, amb el consegüent estalvi de temps i de recursos.
### Exemple d'aplicació servida des de WSGI.
Primer de tot necessitem un mòdul de WSGI al nostre apache:
```bash=
sudo apt install libapache2-mod-wsgi-py3
```
La mínima expressió d'una aplicació WSGI consistiria només en una funció que per defecte s'ha d'anomenar 'application' i ha de poder rebre dos paràmetres (environ, start_response).
```python=
#!/usr/bin/python3
# -*- encodign: utf-8 -*-


def application(environ, start_response):
    status = '200 OK'
    output = b'Hello World!'

    response_headers = [('Content-type', 'text/plain'),
                        ('Content-Length', str(len(output)))]
    start_response(status, response_headers)

    return [output]
```
I afegim la informació de la nostra aplicació al servidor web:
```
WSGIScriptAlias /myapp /var/www/cgi-bin/la_meva_wsgi.wsgi
```
Ara ja podem cridar a la nostra aplicació:
```
$curl -X GET http://cgi.localhost/myapp
Hello World!
```
### Delegant la execució a processos '_Daemon_':
Si volem evitar haver de reiniciar el nostre Apache desprès de fer canvis al codi python o volem tenir un control del nombre de processos llestos per a servir la nostra aplicació, en els sistemes Unix, podem delegar l'execució de l'intèrpret de Python a un grup de processos diferents del procés arrel d'Apache.
```
WSGIDaemonProcess cgi.localhost processes=2 threads=15 display-name=%{GROUP}
WSGIProcessGroup cgi.localhost
```
Així ha quedat la configuració del meu servidor virtual:
```
<VirtualHost *:80>
	ServerName cgi.localhost
	ServerAdmin webmaster@localhost
	DocumentRoot /var/www/cgi-bin

    ErrorLog ${APACHE_LOG_DIR}/error.log
	CustomLog ${APACHE_LOG_DIR}/access.log combined


	WSGIDaemonProcess cgi.localhost processes=2 threads=15 display-name=%{GROUP}
	WSGIProcessGroup cgi.localhost

	WSGIScriptAlias /myapp /var/www/cgi-bin/la_meva_wsgi.wsgi
</VirtualHost>

```
## 3. Asynchronous Server Gateway Interface (ASGI).
ASGI és el succesor natural de WSGI, al igual que WSGI defineix una interface entre el servidor web i la nostra aplicació Python, però aquesta vegada ho fa de forma asícrona, obrint la porta a eines que la web ha anat incorporant els darrers anys com poden ser els web-sockets i els sse (server sent events).
En aquest cas l'aplicació rep 3 paràmetres en lloc de 2.
```python=


async def application(scope, receive, send):
    event = await receive()
    ...
    await send({"type": "websocket.send", ...})
```
On receive és una callback per a rebre comunicacions i send és una altra callback per a enviar informació al client.
ASGI ha estat dissenyada per a oferir compatibilitat a aplicacions WSGI mitjançant alguna eina de traducció.
[Documentació acerca d'ASGI](https://asgi.readthedocs.io/en/latest/introduction.html)