How to run a python cgi web server in windows - python

I'm wanting to run a very simply python based server in a windows environment, to test CGI scripts. I want to do this in windows, but run ultimately in a unix environment. So far, I have a simple server, and a simple program. When I go to the site, I am seeing a blank page, with nothing in the source, and I can't figure out what's going on.
Server
from http.server import HTTPServer, CGIHTTPRequestHandler
class Handler(CGIHTTPRequestHandler):
cgi_directories = ["/cgi-bin"]
PORT = 8080
httpd = HTTPServer(("", PORT), Handler)
print("serving at port", PORT)
httpd.serve_forever()
httpd.serve_forever()
App:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import cgi, cgitb
form = cgi.FieldStorage()
# Get data from fields
first_name = form.getvalue('first_name')
last_name = form.getvalue('last_name')
print ("Content-type:text/html\r\n\r\n")
print ("<html>")
print ("<head>")
print ("<title>Hello - Second CGI Program</title>")
print ("</head>")
print ("<body>")
print ("<h2>Hello %s %s</h2>" % (first_name, last_name))
print ("</body>")
print ("</html>")
I go to the program in my web browser, and I'm getting a downloadable output, with it being the name of the file. It appears the file has executed, but I'm not getting a valid web site. What am I doing wrong?

Of course I figured out the answer just as I posted it... I should just use a \n\n, not \r\n\r\n.
print ("Content-Type: text/html\n\n")

Related

Python: Page will not load when using Python SImpleHTTPServer with a RequestHandler

I'm creating a simple server to serve a form via Python. The user will post their name and a message through an HTML form, on the server-side python will retrieve these values and append them to a file. I've tested each part on their own, other then the cgi.fieldstorage. When running the code, it returns no errors but will not display my HTML page. Any suggestions?
The Python file is below
#!/usr/bin/python
import sys
import os
import SimpleHTTPServer
import cgi
import SocketServer
class MyHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
def do_GET(self):
form = cgi.FieldStorage()
user = form.getvalue("name")
message = form.getvalue("line")
#Append to data.txt
data = open('data.txt', 'a') #open this txt file to then append to it
data.write('%s: %s\n'% (user, message)) #Append this line to the file
data.close()
if __name__=="__main__":
PORT = 9020 #declare which port to serve on.
server = SocketServer.TCPServer(('',PORT),MyHandler) #call the class to generate the server
print "Serving on port: ", PORT #Print what port the Server is serving on
server.serve_forever() #Loop serving requests

Writing compressed html from python3

I'm trying to write a python script that can be run from a browser and displays a very basic html page.
When I use a multiline code block for the html code the web page displays fine.
When i run the script below in a browser from the cgi-bin folder it displays a blank page. Is there a way to do it in a single line?
#!/usr/bin/env python3
str="test"
print("<html><head></head><body><h1>Sample string:", str, "</h1></body></html>")
The code below is to start the python server that serves the script:
#!/usr/bin/env python3
import http.server
import socketserver
import cgitb
# debugging via de web browser
cgitb.enable(format="text")
Handler = http.server.CGIHTTPRequestHandler
PORT = 8000
httpd = socketserver.TCPServer(("", PORT), Handler)
httpd.server_name = ""
httpd.server_port = PORT
print("serving at port", PORT)
httpd.serve_forever()

How to access to a file on localhost

I'm a total newbie when it comes to servers, so this question my sound silly to you, but I stucked and I need you help once more.
I have written a simple server in python, which looks like this:
#!/usr/bin/env python
from socket import *
import time
s = socket(AF_INET, SOCK_STREAM)
s.bind(('', 8888))
s.listen(5)
while 1:
client,addr = s.accept()
print 'Connected to ', addr
client.send(time.ctime(time.time()))
client.close()
So when i write localhost:8888 in my browser, i get the message with the current server time.
The next thing i want to do, is to configure my server to allow opening various files from my computer i.e. html or text ones. So when I write in my browser localhost:8888/text.html, this file opens. Where do i start with that?
I should mention I'm using linux mint and don't want to use any existing framework. I want to fully understand how the servers are working and responding.
Try this:
Create a script named webserver.py
import SimpleHTTPServer
import SocketServer
PORT = 8888
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", PORT), Handler)
print "serving at port", PORT
httpd.serve_forever()
Create a file named text.html and place it on the same dir where your webserver.py script is.
Run python webserver.py
Navigate to http://localhost:8888/text.html

How to run Python CGI script

I have never setup a server (let alone a python server) before and i am a bit lost. How do i utilize the following code? I have tried to put in in the cgi bin directory but that didnt work. It returned an internal server error. have a look at this here
#!/usr/bin/env python
#
# Funf: Open Sensing Framework
# Copyright (C) 2010-2011 Nadav Aharony, Wei Pan, Alex Pentland.
# Acknowledgments: Alan Gardner
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from SocketServer import ThreadingMixIn
import sys
import cgi
import urlparse
import os.path
import shutil
import time
server_dir = os.path.dirname(__file__)
config_path = '/config'
config_file_path = os.path.join(server_dir, 'config.json')
upload_path = '/data'
upload_dir = os.path.join(server_dir, 'uploads')
def read_config():
config = None
try:
with open(config_file_path) as config_file:
config = config_file.read()
except IOError:
pass
return config
def backup_file(filepath):
shutil.move(filepath, filepath + '.' + str(int(time.time()*1000)) + '.bak')
def write_file(filename, file):
if not os.path.exists(upload_dir):
os.mkdir(upload_dir)
filepath = os.path.join(upload_dir, filename)
if os.path.exists(filepath):
backup_file(filepath)
with open(filepath, 'wb') as output_file:
while True:
chunk = file.read(1024)
if not chunk:
break
output_file.write(chunk)
class RequestHandler(BaseHTTPRequestHandler):
def do_GET(self):
parsed_url = urlparse.urlparse(self.path)
if parsed_url.path == config_path:
config = read_config()
if config:
self.send_response(200)
self.end_headers()
self.wfile.write(config)
else:
self.send_error(500)
elif parsed_url.path == upload_path:
self.send_error(405)
else:
self.send_error(404)
def do_POST(self):
parsed_url = urlparse.urlparse(self.path)
path = parsed_url.path
ctype, pdict = cgi.parse_header(self.headers['Content-Type'])
if path == upload_path:
if ctype=='multipart/form-data':
form = cgi.FieldStorage(self.rfile, self.headers, environ={'REQUEST_METHOD':'POST'})
try:
fileitem = form["uploadedfile"]
if fileitem.file:
try:
write_file(fileitem.filename, fileitem.file)
except Exception as e:
print e
self.send_error(500)
else:
self.send_response(200)
self.end_headers()
self.wfile.write("OK")
return
except KeyError:
pass
# Bad request
self.send_error(400)
elif parsed_url.path == config_path:
self.send_error(405)
else:
self.send_error(404)
class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
"""Handle requests in a separate thread."""
if __name__ == '__main__':
if sys.argv[1:]:
port = int(sys.argv[1])
else:
port = 8000
server_address = ('', port)
httpd = ThreadedHTTPServer(server_address, RequestHandler)
sa = httpd.socket.getsockname()
print "Serving HTTP on", sa[0], "port", sa[1], "..."
print 'use <Ctrl-C> to stop'
httpd.serve_forever()
If you want to run a CGI on something like Apache (as opposed via custom server code like you pasted above), you can create a .py file like this in a (.py) CGI-enabled directory.
#!/usr/bin/env python
print "Content-Type: text/html"
print
print 'Hello World'
If you're using Apache, here's some info on how to set up CGI executables.
edit: (As Adrien P. says, the Python script should be made executable.)
You do not have to place it into a cgi-bin directory.
If you are running windows, you can launch Idle from your start menu under the python entry. Paste the code in, and hit F5 to run the code.
If you are running *nix, look to Adrien's answer for the commands and copy what is output when you run ./your_script.py.
Are you attempting to program a website in Python? This is code to create a web server, not site, so navigating to the program in a web browser will yield no results.
$ chmod +x your_script.py
$ ./your_script.py
A quick look a your code: it launch a simple http server who listen on port 8000
Heroku is a good place to host and python scripts.
Pre-req
pythonscripts.py
procfile
requirements.txt
and After add, commit and push the scripts to heroku app. Just run the following command on terminal to run the scripts.
heroku run python your_scripts.py
More if you want to run this scripts on a schedule timing. then heroku provides lots of adds-on. just search it on heroku

Calling urlopen from within cgi script, 'connection refused' error

I have a python cgi-script that checks if a process is active, and starts it if this process is not found. The process itself is a webserver (based on web.py). After I ensure that the process is running, I try to make a url request to it. The idea is to redirect the results of this request to the requester of my cgi script, basically I want to redirect a query to a local webserver that listens to a different port.
This code works fine if I have started the server first (findImgServerProcess returns True), from a shell, not using cgi requests. But if I try to start the process through the cgi-script below, I do get as far as the urllib2.urlopen call, which throws an exception that the connection is refused.
I don't understand why?
If I print the list of processes (r in findImgServerProcess()) I can see the process is there, but why does urllib2.urlopen throw an exception? I have the apache2 webserver set up to use suexec.
Here's the code:
#!/usr/bin/python
import cgi, cgitb
cgitb.enable()
import os, re
import sys
import subprocess
import urllib2
urlbase = "http://localhost:8080/getimage"
imgserver = "/home/martin/public_html/cgi-bin/stlimgservermirror.py" # this is based on web.py
def findImgServerProcess():
r = subprocess.Popen(["ps", "aux"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT).communicate()[0]
return re.match(".*%s" % os.path.split(imgserver)[-1], r, re.DOTALL)
def ensureImgServerProcess():
if findImgServerProcess():
return True
os.environ['LD_LIBRARY_PATH'] = '/home/martin/lib'
fout = open("/dev/null", "w")
ferr = fout
subprocess.Popen([sys.executable, imgserver], stdout=fout, stderr=subprocess.STDOUT)
# now try and find the process
return findImgServerProcess() != None
def main():
if not ensureImgServerProcess():
print "Content-type: text/plain\n"
print "image server down!"
return
form = cgi.FieldStorage()
if form.has_key("debug"):
print "Content-type: text/plain\n"
print os.environ['QUERY_STRING']
else:
try:
img = urllib2.urlopen("%s?%s" % (urlbase, os.environ['QUERY_STRING'])).read()
except Exception, e:
print "Content-type: text/plain\n"
print e
sys.exit()
print "Content-type: image/png\n"
print img
if __name__ == "__main__":
main()
A possibility is that the subprocess hasn't had an opportunity to completely start up before you try to connect to it. To test this, try adding a time.sleep(5) before you call urlopen.
This isn't ideal, but will at least help you figure out if that's the problem. Down the road, you'll probably want to set up a better way to check that the HTTP daemon is running and keep it running.

Categories

Resources