How can I run CGI script within Django test server? Or use GeoNode's proxy module (geoserver_proxy) in my own GeoDjango project..I request any Solution and Suggestion

961 views
Skip to first unread message

Ram Shrestha

unread,
Apr 1, 2014, 5:04:58 AM4/1/14
to geod...@googlegroups.com
Hi
This question may be nonsense but it was random idea.
idea: Embed CGI script server inside django
Ultimate goal: setup proxy in GeoDjango server to access WFS, WFS,-T layers from GeoServer.
Available Solution: GeoNode has used proxy module in the project. But I couldn't use it in my small project. (I don't need all features of GeoNode). Can someone guide me to use the module in my own GeoDjango project

Apache server can run cgi scripts (used XAMPP). I used the openlayer's proxy.cgi placed inside cgi-bin inside xampp folder. I could access WFS layers from geoserver with OpenLayers code. Now I am interested in GeoDjango. GeoDjango has its own development test-server which can be started as >>>python manage.py runserver 8000.

I read of python CGI server and CGI scripts from book: "Python  Geospatial Development" by "Errik Westra", (pages 212, 213). 

when I access http://localhost:8000/cgi-bin/proxy.py in browser I get expected result (same as Apache server with Xampp )
-->\root\
-------->webserver.py
-------->\cgi-bin\
-------------->proxy.py

#filewebserver.py
---------------------------------------------------------------------------------
import BaseHTTPServer
import CGIHTTPServer
address = ('', 8000)
handler = CGIHTTPServer.CGIHTTPRequestHandler
server = BaseHTTPServer.HTTPServer(address, handler)
server.serve_forever()

#file proxy.py
---------------------------------------------------------------------------------
#!/usr/bin/env python

"""This is a blind proxy that we use to get around browser
restrictions that prevent the Javascript from loading pages not on the
same server as the Javascript.  This has several problems: it's less
efficient, it might break some sites, and it's a security risk because
people can use this proxy to browse the web and possibly do bad stuff
with it.  It only loads pages via http and https, but it can load any
content type. It supports GET and POST requests."""

import urllib2
import cgi
import sys, os

# Designed to prevent Open Proxy type stuff.

allowedHosts = ['www.openlayers.org', 'openlayers.org', 
                'labs.metacarta.com', 'world.freemap.in', 
                'prototype.openmnnd.org', 'geo.openplans.org',
                'sigma.openplans.org', 'demo.opengeo.org',
                'www.openstreetmap.org', 'sample.azavea.com',
                'v2.suite.opengeo.org', 'v-swe.uni-muenster.de:8080', 
                'vmap0.tiles.osgeo.org', 'www.openrouteservice.org',
'localhost:8080','localhost:80']

method = os.environ["REQUEST_METHOD"]

if method == "POST":
    qs = os.environ["QUERY_STRING"]
    d = cgi.parse_qs(qs)
    if d.has_key("url"):
        url = d["url"][0]
    else:
        url = "http://www.openlayers.org"
else:
    fs = cgi.FieldStorage()
    url = fs.getvalue('url', "http://www.openlayers.org")

try:
    host = url.split("/")[2]
    if allowedHosts and not host in allowedHosts:
        print "Status: 502 Bad Gateway"
        print "Content-Type: text/plain"
        print
        print "This proxy does not allow you to access that location (%s)." % (host,)
        print
        print os.environ
  
    elif url.startswith("http://") or url.startswith("https://"):
    
        if method == "POST":
            length = int(os.environ["CONTENT_LENGTH"])
            headers = {"Content-Type": os.environ["CONTENT_TYPE"]}
            body = sys.stdin.read(length)
            r = urllib2.Request(url, body, headers)
            y = urllib2.urlopen(r)
        else:
            y = urllib2.urlopen(url)
        
        # print content type header
        i = y.info()
        if i.has_key("Content-Type"):
            print "Content-Type: %s" % (i["Content-Type"])
        else:
            print "Content-Type: text/plain"
        print
        
        print y.read()
        
        y.close()
    else:
        print "Content-Type: text/plain"
        print
        print "Illegal request."

except Exception, E:
    print "Status: 500 Unexpected Error"
    print "Content-Type: text/plain"
    print 
    print "Some unexpected error occurred. Error text was:", E
---------------------------------------------------------------------------------


Vincent

unread,
Apr 3, 2014, 6:18:38 PM4/3/14
to geod...@googlegroups.com
Hi Ram,
The easiest way I have found of doing this is to use a wsgi server to serve django/geodjango and a reverse proxy in front, e.g. gunicorn and nginx.
Nginx makes it really easy to proxy servers, both local and remote, and is great for overcoming the same origin policy problem with openlayers:
http://trac.osgeo.org/openlayers/wiki/FrequentlyAskedQuestions#WhydoIneedaProxyHost

See here for a good guide: http://lincolnloop.com/django-best-practices/deployment/index.html

See here for gunicorn: https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/gunicorn/

Basically (for linux):
pip install gunicorn
Add gunicorn to INSTALLED_APPS in settings.py
manage.py run_gunicorn --workers=4 4 --bind=127.0.0.1:9000 --timeout=60 --preload
(port 9000, 4 workers, timeout 60 seconds, load configuration at startup)

yum install nginx
Edit configuration file (see sample below)
service nginx start
chkconfig nginx on

in /etc/nginx/conf.d/servername.conf

upstream django {
  server         127.0.0.1:9000;
}

server {
  listen       80;
  server_name  hostname;
  root        /var/www/html/;

location /geoserver {
      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;
      proxy_max_temp_file_size 0;

      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;
  }

  # Check if a file exists at /var/www/domain/ for the incoming request.
  # If it doesn't proxy to Gunicorn/Django.
  try_files $uri @django;
 
  # Setup named location for Django requests and handle proxy details
  location @django {
    proxy_pass         http://django;
    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;
Reply all
Reply to author
Forward
0 new messages