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


</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)