Python CGI programming

Slides:



Advertisements
Similar presentations
Chapter 6 Server-side Programming: Java Servlets
Advertisements

PHP Form and File Handling
E-Commerce CMM503 – Lecture 8 Stuart Watt Room C2.
Presenter: James Huang Date: Sept. 29,  HTTP and WWW  Bottle Web Framework  Request Routing  Sending Static Files  Handling HTML  HTTP Errors.
Lecture 6/2/12. Forms and PHP The PHP $_GET and $_POST variables are used to retrieve information from forms, like user input When dealing with HTML forms.
Browsers and Servers CGI Processing Model ( Common Gateway Interface ) © Norman White, 2013.
1 Chapter 12 Working With Access 2000 on the Internet.
PHP (2) – Functions, Arrays, Databases, and sessions.
Servlets and a little bit of Web Services Russell Beale.
 2002 Prentice Hall. All rights reserved. 1 Chapter 6 – Introduction to the Common Gateway Interface (CGI) Outline 6.1 Introduction 6.2 Client and Web.
Python and Web Programming
Guide To UNIX Using Linux Third Edition
ASP.NET Programming with C# and SQL Server First Edition
Christopher M. Pascucci Basic Structural Concepts of.NET Browser – Server Interaction.
Introduction to InfoSec – Recitation 10 Nir Krakowski (nirkrako at post.tau.ac.il) Itamar Gilad (itamargi at post.tau.ac.il)
1 ‘Dynamic’ Web Pages So far, we have developed ‘static’ web-pages, e.g., cv.html, repair.html and order.html. There is often a requirement to produce.
1 Homework / Exam Exam 3 –Solutions Posted –Questions? HW8 due next class Final Exam –See posted schedule Websites on UNIX systems Course Evaluations.
FALL 2005CSI 4118 – UNIVERSITY OF OTTAWA1 Part 4 Web technologies: HTTP, CGI, PHP,Java applets)
1 HTML and CGI Scripting CSC8304 – Computing Environments for Bioinformatics - Lecture 10.
CHAPTER 12 COOKIES AND SESSIONS. INTRO HTTP is a stateless technology Each page rendered by a browser is unrelated to other pages – even if they are from.
Classroom User Training June 29, 2005 Presented by:
4-1 INTERNET DATABASE CONNECTOR Colorado Technical University IT420 Tim Peterson.
Basics of Web Databases With the advent of Web database technology, Web pages are no longer static, but dynamic with connection to a back-end database.
About Dynamic Sites (Front End / Back End Implementations) by Janssen & Associates Affordable Website Solutions for Individuals and Small Businesses.
27.1 Chapter 27 WWW and HTTP Copyright © The McGraw-Hill Companies, Inc. Permission required for reproduction or display.
1 PHP and MySQL. 2 Topics  Querying Data with PHP  User-Driven Querying  Writing Data with PHP and MySQL PHP and MySQL.
Internet Forms and Database Bob Kisel Amgraf, Inc.
9 Chapter Nine Compiled Web Server Programs. 9 Chapter Objectives Learn about Common Gateway Interface (CGI) Create CGI programs that generate dynamic.
1 In the good old days... Years ago… the WWW was made up of (mostly) static documents. –Each URL corresponded to a single file stored on some hard disk.
Class 1Intro to Databases Goals of this class Understand the architecture behind web database applications Gain a basic understanding of what relational.
COMP3121 E-Commerce Technologies Richard Henson University of Worcester November 2011.
JAVA SERVER PAGES. 2 SERVLETS The purpose of a servlet is to create a Web page in response to a client request Servlets are written in Java, with a little.
10/13/2015 ©2006 Scott Miller, University of Victoria 1 Content Serving Static vs. Dynamic Content Web Servers Server Flow Control Rev. 2.0.
Using Python for CGI programming Modified from Guido van Rossum CPE 401 / 601 Computer Network Systems Mehmet Hadi Gunes.
Lecture 8 – Cookies & Sessions SFDV3011 – Advanced Web Development 1.
Extending HTML CPSC 120 Principles of Computer Science April 9, 2012.
1 Basic Perl CGI Programming. 2 Issues How and when your program is invoked. Generating Response –HTTP Headers –HTML (or whatever document type you want)
Chapter 6 Server-side Programming: Java Servlets
Prof Frankl, Spring 2008CS Polytechnic University 1 Overview of Web database applications with PHP.
CGI Common Gateway Interface. CGI is the scheme to interface other programs to the Web Server.
CSC 2720 Building Web Applications Server-side Scripting with PHP.
Creating PHPs to Insert, Update, and Delete Data CS 320.
Intro to PHP IST2101. Review: HTML & Tags 2IST210.
Java server pages. A JSP file basically contains HTML, but with embedded JSP tags with snippets of Java code inside them. A JSP file basically contains.
Cookies and Sessions IDIA 618 Fall 2014 Bridget M. Blodgett.
ECMM6018 Enterprise Networking for Electronic Commerce Tutorial 7
1 CSC160 Chapter 7: Events and Event Handlers. 2 Outline Event and event handlers onClick event handler onMouseOver event handler onMouseOut event handler.
Module: Software Engineering of Web Applications Chapter 2: Technologies 1.
 2001 Prentice Hall, Inc. All rights reserved. Chapter 7 - Introduction to Common Gateway Interface (CGI) Outline 7.1Introduction 7.2A Simple HTTP Transaction.
8 Chapter Eight Server-side Scripts. 8 Chapter Objectives Create dynamic Web pages that retrieve and display database data using Active Server Pages Process.
| imodules.com Top 10 FAQ in Application Support Kelly Schmiedeler & Amber Quayle.
5 th ed: Chapter 17 4 th ed: Chapter 21
(Some from Chapter 11.9 – “Web” 4 th edition and
IS2803 Developing Multimedia Applications for Business (Part 2) Lecture 1: Introduction to IS2803 Rob Gleasure
ITM © Port,Kazman 1 ITM 352 Cookies. ITM © Port,Kazman 2 Problem… r How do you identify a particular user when they visit your site (or any.
Chapter 16 Web Pages And CGI Scripts Department of Biomedical Informatics University of Pittsburgh School of Medicine
Bayu Priyambadha, S.Kom. Static content  Web Server delivers contents of a file (html) 1. Browser sends request to Web Server 3. Web Server sends HTML.
Session 11: Cookies, Sessions ans Security iNET Academy Open Source Web Development.
IST 210: PHP Basics IST 210: Organization of Data IST2101.
PHP: Further Skills 02 By Trevor Adams. Topics covered Persistence What is it? Why do we need it? Basic Persistence Hidden form fields Query strings Cookies.
© Janice Regan, CMPT 128, Jan 2007 CMPT 371 Data Communications and Networking HTTP 0.
111 State Management Beginning ASP.NET in C# and VB Chapter 4 Pages
The Common Gateway Interface (CGI) Pat Morin COMP2405.
CS122B: Projects in Databases and Web Applications Spring 2017
CS122B: Projects in Databases and Web Applications Winter 2017
WWW and HTTP King Fahd University of Petroleum & Minerals
Chapter 19 PHP Part III Credits: Parts of the slides are based on slides created by textbook authors, P.J. Deitel and H. M. Deitel by Prentice Hall ©
PHP / MySQL Introduction
CS122B: Projects in Databases and Web Applications Winter 2018
CS122B: Projects in Databases and Web Applications Spring 2018
Presentation transcript:

Python CGI programming

Outline HTML forms Basic CGI usage Setting up a debugging framework Security Handling persistent data Locking Sessions Cookies File upload Generating HTML Performance

A typical HTML form <form method="POST" action="http://host.com/cgi-bin/test.py"> <p>Your first name: <input type="text" name="firstname"> <p>Your last name: <input type="text" name="lastname"> <p>Click here to submit form: <input type="submit" value="Yeah!"> <input type="hidden" name="session" value="1f9a2"> </form>

A typical CGI script #!/usr/local/bin/python import cgi def main(): print "Content-type: text/html\n" form = cgi.FieldStorage() # parse query if form.has_key("firstname") and form["firstname"].value != "": print "<h1>Hello", form["firstname"].value, "</h1>" else: print "<h1>Error! Please enter first name.</h1>" main()

CGI script structure Check form fields Perform action use cgi.FieldStorage class to parse query takes care of decoding, handles GET and POST "foo=ab+cd%21ef&bar=spam" --> {'foo': 'ab cd!ef', 'bar': 'spam'} # (well, actually, ...) Perform action this is up to you! database interfaces available Generate HTTP + HTML output print statements are simplest template solutions available

Structure refinement form = cgi.FieldStorage() if not form: ...display blank form... elif ...valid form...: ...perform action, display results (or next form)... else: ...display error message (maybe repeating form)...

FieldStorage details Behaves like a dictionary: Items .keys(), .has_key() # but not others! dictionary-like object ("mapping") Items values are MiniFieldStorage instances .value gives field value! if multiple values: list of MiniFieldStorage instances if type(...) == types.ListType: ... may also be FieldStorage instances used for file upload (test .file attribute)

Other CGI niceties cgi.escape(s) translate "<", "&", ">" to "<", "&", "&gt" cgi.parse_qs(string, keep_blank_values=0) parse query string to dictionary {"foo": ["bar"], ...} cgi.parse([file], ...) ditto, takes query string from default locations urllib.quote(s), urllib.unquote(s) convert between "~" and "%7e" (etc.) urllib.urlencode(dict) convert dictionary {"foo": "bar", ...} to query string "foo=bar&..." # note asymmetry with parse_qs() above

Dealing with bugs Things go wrong, you get a traceback... By default, tracebacks usually go to the server's error_log file... Printing a traceback to stdout is tricky could happen before "Content-type" is printed could happen in the middle of HTML markup could contain markup itself What's needed is a...

Debugging framework import cgi def main(): print "Content-type: text/html\n" # Do this first try: import worker # module that does the real work except: print "<!-- --><hr><h1>Oops. An error occurred.</h1>" cgi.print_exception() # Prints traceback, safely main()

Security notes Watch out when passing fields to the shell Solutions: e.g. os.popen("finger %s" % form["user"].value) what if the value is "; cat /etc/passwd" ... Solutions: Quote: user = pipes.quote(form["user"].value) Refuse: if not re.match(r"^\w+$", user): ...error... Sanitize: user = re.sub(r"\W", "", form["user"].value)

Using persistent data Store/update data: In plain files (simplest) FAQ wizard uses this In a (g)dbm file (better performance) string keys, string values In a "shelf" (stores objects) avoids parsing/unparsing the values In a real database (if you must) 3rd party database extensions available not my field of expertise

Plain files key = ...username, or session key, or whatever... try: f = open(key, "r") data = f.read() # read previous data f.close() except IOError: data = "" # no file yet: provide initial data data = update(data, form) # do whatever must be done f = open(key, "w") f.write(data) # write new data # (could delete the file instead if updated data is empty)

(G)DBM files # better performance if there are many records import gdbm key = ...username, or session key, or whatever... db = gdbm.open("DATABASE", "w") # open for reading+writing if db.has_key(key): data = db[key] # read previous data else: data = "" # provide initial data data = update(data, form) db[key] = data # write new data db.close()

Shelves # a shelf is a (g)dbm files that stores pickled Python objects import shelve class UserData: ... key = ...username, or session key, or whatever... db = shelve.open("DATABASE", "w") # open for reading+writing if db.has_key(key): data = db[key] # an object! else: data = UserData(key) # create a new instance data.update(form) db[key] = data db.close()

Locking (G)DBM files and shelves are not protected against concurrent updates! Multiple readers, single writer usually OK simplest approach: only lock when writing Good filesystem-based locking is hard no cross-platform solutions unpleasant facts of life: processes sometimes die without unlocking processes sometimes take longer than expected NFS semantics

A simple lock solution import os, time class Lock: def __init__(self, filename): self.filename = filename self.locked = 0 def lock(self): assert not self.locked while 1: try: os.mkdir(self.filename) self.locked = 1 return # or break except os.error, err: time.sleep(1) def unlock(self): assert self.locked self.locked = 0 os.rmdir(self.filename) # auto-unlock when lock object is deleted def __del__(self): if self.locked: self.unlock() # for a big production with timeouts, # see the Mailman source code (LockFile.py); # it works on all Unixes and supports NFS; # but not on Windows, # and the code is very complex...

Sessions How to correlate requests from same user? Assign session key on first contact Incorporate session key in form or in URL In form: use hidden input field: <input type="hidden" name="session" value="1f9a2"> In URL: http://myhost.com/cgi-bin/myprog.py/1f9a2 passed in environment (os.environ[...]): PATH_INFO=/1f9a2 PATH_TRANSLATED=<rootdir>/1f9a2

Cookies How to correlate sessions from the same user? Store "cookie" in browser controversial, but useful Module: Cookie.py (Tim O'Malley) writes "Set-Cookie" headers parses HTTP_COOKIE environment variable Note: using cookies affects our debug framework cookies must be printed as part of HTTP headers cheapest solution: move printing of blank line into worker module (and into exception handler of debug framework)

Cookie example import os, cgi, Cookie c = Cookie.Cookie() try: c.load(os.environ["HTTP_COOKIE"]) except KeyError: pass form = cgi.FieldStorage() user = form["user"].value user = c["user"].value user = "nobody" c["user"] = user print c print """ <form action="/cgi-bin/test.py" method="get"> <input type="text" name="user" value="%s"> </form> """ % cgi.escape(user) # debug: show the cookie header we wrote print "<pre>" print cgi.escape(str(c)) print "</pre>"

File upload example import cgi form = cgi.FieldStorage() if not form: print """ <form action="/cgi-bin/test.py" method="POST" enctype="multipart/form-data"> <input type="file" name="filename"> <input type="submit"> </form> """ elif form.has_key("filename"): item = form["filename"] if item.file: data = item.file.read() # read contents of file print cgi.escape(data) # rather dumb action

Generating HTML HTMLgen (Robin Friedrich) HTMLcreate (Laurence Tratt) http://starship.python.net/crew/friedrich/HTMLgen/html/main.html >>> print H(1, "Chapter One") <H1>Chapter One</H1> >>> print A("http://www.python.org/", "Home page") <A HREF="http://www.python.org/">Home page</A> >>> # etc. (tables, forms, the works) HTMLcreate (Laurence Tratt) http://www.spods.dcs.kcl.ac.uk/~laurie/comp/python/htmlcreate/ not accessible at this time

CGI performance What causes slow response? One process per CGI invocation process creation (fork+exec) Python interpreter startup time importing library modules (somewhat fixable) Connecting to a database! this can be the killer if you use a real database Your code? probably not the bottleneck!

Avoiding fork() Python in Apache (mod_pyapache) problems: stability; internal design advantage: CGI compatible may work if CGI scripts are simple and trusted doesn't avoid database connection delay Use Python as webserver slow for static content (use different port) advantage: total control; session state is easy FastCGI, HTTPDAPI etc. ZOPE

ZOPE Z Object Publishing Environment http://www.zope.org complete dynamic website management tool written in cross-platform Python; Open Source http://host/path/to/object?size=5&type=spam calls path.to.object(size=5, type="spam") DTML: templatized HTML (embedded Python code) ZOBD (Z Object DataBase; stores Python objects) transactionsm selective undo, etc. etc., etc.

Case study

FAQ wizard Tools/faqwiz/faqwiz.py in Python distribution http://www.python.org /cgi-bin/faqw.py

faqw.py - bootstrap import os, sys try: FAQDIR = "/usr/people/guido/python/FAQ" SRCDIR = "/usr/people/guido/python/src/Tools/faqwiz" os.chdir(FAQDIR) sys.path.insert(0, SRCDIR) import faqwiz except SystemExit, n: sys.exit(n) except: t, v, tb = sys.exc_type, sys.exc_value, sys.exc_traceback print import cgi cgi.print_exception(t, v, tb)

faqwiz.py - main code class FaqWizard: def __init__(self): self.ui = UserInput() self.dir = FaqDir() def do_home(self): self.prologue(T_HOME) emit(HOME) def do_search(self): ... def do_index(self): ... def do_roulette(self): ... def do_show(self): ... def do_edit(self): ... def do_review(self): ... def do_help(self): ... ...etc... def go(self): print 'Content-type: text/html' req = self.ui.req or 'home' mname = 'do_%s' % req try: meth = getattr(self, mname) except AttributeError: self.error("Bad request type %s." % `req`) else: meth() except InvalidFile, exc: self.error("Invalid entry file name %s" % exc.file) except NoSuchFile, exc: self.error("No entry with file name %s" % exc.file) except NoSuchSection, exc: self.error("No section number %s" % exc.section) self.epilogue()

Example: do_roulette() def do_roulette(self): import random files = self.dir.list() if not files: self.error("No entries.") return file = random.choice(files) self.prologue(T_ROULETTE) emit(ROULETTE) self.dir.show(file)

Persistency All data stored in files (faqNN.MMM.htp) Backed up by RCS files (RCS/faqNN.MMM.htp,v) RCS logs and diffs viewable RCS commands invoked with os.system() or os.popen() search implemented by opening and reading each file NO LOCKING! infrequent updates expected in practice, one person makes most updates :-) one historic case of two users adding an entry to the same section at the same time; one got an error back not generally recommended

faqconf.py, faqcust.py faqconf.py defines named string constants for every bit of output generated by faqwiz.py designed for customization (e.g. i18n) so you can customize your own faq wizard e.g. OWNEREMAIL = "guido@python.org" this includes the list of sections in your faq :-( faqcust.py defines overrides for faqconf.py so you don't need to edit faqwiz.py to make it easier to upgrade to newer faqwiz version

Webchecker Tools/webchecker/webchecker.py in Python distribution Not a CGI application but a web client application while still pages to do: request page via http parse html, collecting links pages once requested won't be requested again links outside original tree treated as leaves existence checked but links not followed reports on bad links what the bad URL is on which page(s) it is referenced could extend for other reporting

Reference URLs Python websites Python web programming topic guide http://www.python.org (official site) http://starship.python.net (community) Python web programming topic guide http://www.python.org/topics/web/ These slides on the web (soon) http://www.python.org/doc/essays/ppt/sd99east.ppt

Reference books http://www.python.org/psa/bookstore/ 1996 1998 1999 Programming Python (Lutz) [Internet Programming with Python (Watters e.a.)] 1998 Python Pocket Reference (Lutz) 1999 Learning Python (Lutz, Ascher) Python: Essential Reference (Beazley) Quick Python Book (Harms, McDonald) Expected 1999/2000 Win 32, Tkinter, teach-yourself-in-24-hrs, annotated archives, ...