Sunteți pe pagina 1din 7

MVC sobre CGI en Python

Autor: Eugenia Bahit

Resumen
Este documento está basado en el paper del proyecto «MVCGI: Modelo de
Implementación Estándar para arquitecturas MVC modulares en programas de
interfaz CGI» publicado en diciembre de 2016 , en el cual se propone un modelo
arquitectónico para la implementación de arquitecturas MVC modulares en
programas CGI, centrado en la seguridad.

El objetivo de este modelo se encuentra en:

 La agilización del sistema, por reducción de sobrecarga de procesos


 La seguridad de la aplicación, mediante la implementación de un modelo
teórico hipotético

Previa contextualización, se expone el procedimiento completo para poder


replicarlo un proyecto MVC en Python, bajo el servidor http de Apache con una
interfaz CGI.

Contexto
CGI (Common Gateway Interfaz) es definido en la RFC3875 como una interfaz
sencilla para ejecutar programas bajo servidores HTTP de forma independiente a
la plataforma (Robinson & Coard, 2004), proponiendo un mecanismo de
comunicación entre la aplicación y el servidor que facilita la independencia de
ambos.

Por su parte, MVC es un patrón arquitectónico, originalmente definido como un


«lenguaje de patrones» (Reenskaug, 1979) y posteriormente como «paradigma de
programación» (Krasner & Pope, 1988), que propone una independencia similar
entre la abstracción de los datos de un sistema y las diferentes representaciones
gráficas de éstos (Reenskaug, 1979).

La independencia que plantea la implementación simultánea de CGI como interfaz


de comunicación entre la aplicación y el servidor, por un lado, y, MVC como
método de comunicación interno de los componentes abstractos de un programa y
su interfaz gráfica de usuario (GUI), por el otro, podrían suponer la posibilidad de
crear herramientas de bajo coste para el servidor (debido a la escasez de recursos
que requieren ser consumidos) y de gran portabilidad (como consecuencia directa
de la falta de dependencia).

En los años posteriores a la presentación de los modelos ut supra mencionados (e


incluso en la actualidad) se han presentado un gran número de herramientas
destinadas al desarrollo de sistemas informáticos y de a poco, la interfaz CGI ha
ido quedando en desuso y con ella, las investigaciones sobre la seguridad en
programas que implementen dicha interfaz. Por otra parte, el scripting involucrado
en la escritura de programas CGI, no ha sido incluido hasta la actualidad, como
parte de los estudios de investigación sobre buenas prácticas de programación y
estructuras de código limpio, siendo ambas problemáticas, seguridad y falta de
estudio de las buenas prácticas en el scripting, dos posibles impedimentos para
considerar viable el diseño de programas CGI que implementen arquitecturas MVC
modulares, seguras, portables, livianas y legibles.

El modelo MVCGI surge como alternativa viable para la erradicación de ambas


problemáticas, ofreciendo una propuesta para la implementación de arquitecturas
MVC modulares en programas CGI.

Procedimiento
1. Creación del File System
MVCGI propone la siguiente estructura de archivos y directorisos (file system):

rootsystem/
├── [drwxr-xr-x] application/
│ ├── [drwxr-xr-x] core/
│ │ └── [drwxr--r--] __init__.py
│ ├── [drwxr-xr-x] modules/
│ │ └── [drwxr--r--] __init__.py
│ ├── [-rw-r--r--] __init__.py
│ ├── [-rw-r--r--] config.py
│ ├── [-rwxr-xr-x] xfc.py*
│ └── [-rw-r--r--] settings.py
└── [drwxr-xr-x] static/

# Directorios opcionales (fuera de rootsystem)


[drwxr-xr-x] logs/
[drwxrwxrwx] private/

Breve explicación de la función de cada componente del File System

 Directorio raíz del sistema


Destinado a nuclear los archivos estáticos y de la aplicación.

 Directorio de aplicación:
Destinado a nuclear los archivos fuente de la aplicación y mantenerlos
separados del contenido estático.

 Núcleo del sistema


Directorio destinado a nuclear los archivos centrales de la aplicación,
comunes a cualquier sistema.

 Módulos del sistema


Directorio destinado al almacenaje de archivos de funcionalidades
específica de la aplicación.

 Archivo de control frontal ejecutable


(eXecutable Front Controller - XFC) Manejador general de solicitudes HTTP
de la aplicación.

 Archivo de inicialización de variables de entorno


Meta-variables (o variables de entorno) de la aplicación, necesarias para su
funcionamiento pero no configurables.

 Archivo de configuración
Variables de configuración específica de la aplicación.

 Directorio estático
Destinado a nuclear archivos estáticos y binarios no ejecutables.

1.1 Creación del archivo de configuración application/config.py

DEFAULT_RESOURCE = "/modulo/recurso" # Módulo y recurso por defecto


SHOW_ERROR_404 = False

1.2 Creación del archivo de inicialización de variables application/settings.py

from os import environ

from config import *


URL_LIST = environ['REQUEST_URI'][1:].split('/')
MODULE = URL_LIST[0].replace('.', '')
PACKAGE = "modules.{}".format(MODULE)
MODULE_PATH = "{}.py".format(PACKAGE.replace('.', '/'))
CONTROLLER = "{}Controller".format(MODULE.title())
RESOURCE = URL_LIST[1] if len(URL_LIST) > 1 else ''
ARG = URL_LIST[2] if len(URL_LIST) > 2 else 0

HTTP_404 = "Status: 404 Not Found\n"


HTTP_HTML = "Content-type: text/html; charset=utf-8\n"
HOST = "http://{}".format(environ['SERVER_NAME'])
HTTP_REDIRECT = "Location: {}{}\n".format(HOST, DEFAULT_RESOURCE)

1.3 Creación del archivo ejecutable application/xfc.py

#!/usr/bin/env python
#-*- coding: utf-8 -*-

from os.path import isfile

from settings import MODULE_PATH, PACKAGE, CONTROLLER, RESOURCE, HTTP_404,\


HTTP_HTML, SHOW_ERROR_404, HTTP_REDIRECT, MODULE

error_module = error_resource = True

if isfile(MODULE_PATH):
modulo = __import__(PACKAGE, fromlist=[CONTROLLER])
controller = getattr(modulo, CONTROLLER)()
error_module = False

if not error_module and hasattr(controller, RESOURCE):


getattr(controller, RESOURCE)()
error_resource = False

if error_module or error_resource:
error_header = "{}{}\n".format(HTTP_404, HTTP_HTML)
print error_header if SHOW_ERROR_404 else HTTP_REDIRECT

2. Creación del VirtualHost


Archivo: /etc/apache2/sites-available/<hostname>.conf

<VirtualHost *:80>
ServerName <hostname>.local
DocumentRoot /<project-path>/rootsystem
ErrorLog /<project-path>/logs/error.log
CustomLog /<project-path>/logs/access.log combined

<Directory "/<project-path>/rootsystem">
Options -Indexes
AllowOverride None
RewriteEngine On
RewriteRule !(^static) application/xfc.py
</Directory>

<Directory "/<project-path>/rootsystem/application">
Options +ExecCGI -Indexes
<FilesMatch "\.py$">
setHandler cgi-script
</FilesMatch>
</Directory>

<Directory "/<project-path>/rootsystem/static">
Options -Indexes
AllowOverride None
</Directory>
</VirtualHost>

3. Configuraciones del servidor http de Apache


3.1. Habilitar VirtualHost
a2ensite <hostname>.conf
3.2. Habilitar módulo cgi
a2enmod cgi

3.2.1 Si lo anterior falla, deshabilitar worker y habilitar prefork


a2dismod mpm_worker && service apache2 restart
a2enmod mpm_prefork

3.3. Reiniciar Apache


service apache2 restart

4. Habilitación del nuevo host


echo "127.0.0.1 <hostname>.local" >> /etc/hosts

5. Creación de un módulo de prueba


Archiv: application/modules/modulo.py

from settings import HTTP_HTML

class Modulo(object):
pass

class ModuloView(object):

def vista(self):
print HTTP_HTML
print ""
print "Hola Mundo"

class ModuloController(object):

def __init__(self):
self.model = Modulo()
self.view = ModuloView()

def recurso(self):
self.view.vista()

6. Prueba
Ingresar en la URL: http://<hostname>.local/modulo/recurso y comprobar que la
salida sea Hola mundo

Política de nombres
Se utiliza como nombre de módulo el nombre del modelo. Se utilizan el nombre del
modelo con los sufijos “View” y “Controller” para crear las vistas y controladores
respectivamente. Ejemplo:

Modelo: Producto
Vista: ProductoView
Controlador: ProductoController
Helper: ProductoHelper (opcional)
Módulo: application/modules/producto.py
URI: /producto/<recurso>

S-ar putea să vă placă și