Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- import socket
- import urlparse
- import cgi
- import threading
- import sys
- import traceback
- import re
- import os
- import mimetypes
- import sqlite3
- import Cookie # wtf why is this capitalized
- import random
- import crypt
- # per-site secret; only first two characters are used.
- secret = 'GG IS MY SECRET'
- # initialize random number generator from the system time on import.
- random.seed()
- def generate_session_id(user):
- """
- Generate a unique session ID based on the user name with the given
- site-specific secret. How secure is this, really?
- """
- salt = secret[:2]
- return crypt.crypt(user + str(random.random()), salt)
- conn = sqlite3.connect('webserve-info.db')
- def serve(interface, port):
- sock = socket.socket()
- sock.bind((interface, port))
- sock.listen(10)
- print 'Listening on port', port
- while True:
- (client_sock, client_address) = sock.accept()
- process = threading.Thread(target=handle_connection, args=(client_sock, client_address))
- process.start()
- def handle_connection(client_sock, client_address):
- full_data = ''
- while True:
- data = client_sock.recv(1)
- full_data += data
- if full_data.endswith('\r\n\r\n'):
- break
- header_lines = full_data.split('\r\n')[:-2]
- method, path, _ = header_lines[0].split()
- _, _, path, query, _ = urlparse.urlsplit(path)
- query = cgi.parse_qs(query)
- headers = [h.split(': ', 1) for h in header_lines[1:]]
- post_data = None
- if method == 'POST':
- length = int(re.findall(r'Content-Length: (\d+)', full_data)[0])
- post_data = client_sock.recv(length)
- post_data = cgi.parse_qs(post_data)
- try:
- status, head, data = delegate(method, path, headers, query, post_data)
- except:
- print "Exception in user code:"
- print '-' * 60
- traceback.print_exc(file=sys.stdout)
- print '-' * 60
- status, head, data = 500, [], '<h1>500 Internal Server Error</h1>'
- if status == 200: # we dont got any html pages to serve up for failures, sry
- if not any(h[0] == 'Content-Type' for h in head):
- head.insert(0, ('Content-Type', 'text/html'))
- if ('Content-Type', 'text/html') in head:
- # add top and bottom halves
- data = open('files/top.html').read() + data + open('files/bottom.html').read()
- head.append(('Content-Length', str(len(data))))
- head = '\r\n'.join(["%s: %s" % (k, v) for (k, v) in head])
- status_responses = {200: '200 OK', 401: '401 Unauthorized', 404: '404 Not Found', 500: '500 Internal Server Error'}
- if status not in status_responses:
- status = 500
- client_sock.sendall("HTTP/1.1 %s\r\n%s\r\n\r\n%s" % (status_responses[status], head, data))
- client_sock.close()
- def delegate(request_type, path, headers, get, post = None):
- if(path.endswith('/')):
- path += 'index.html'
- if(os.path.isfile("files%s" % path)):
- return read_file(headers, get, post, path)
- go = '_'.join(path[1:].split('/'))
- if go in globals():
- return globals()[go](headers, get, post)
- return page_missing(headers, get, post, path)
- def read_file(received_headers, get, post, path):
- mime = mimetypes.guess_type("files%s" % path)[0]
- return 200, [('Content-Type', mime)], open("files%s" % path).read()
- def page_missing(received_headers, get, post, path):
- if path.startswith('/test/'):
- data = 'hello, %s' % path
- for request_data, name in ((get, 'get_data:'), (post, 'post_data:')):
- if request_data:
- data += " %s" % name
- for key in request_data:
- for val in request_data[key]:
- data += " key=%s; value=%s;" % (key, val)
- return 200, [], data
- else:
- return 404, [], ''
- def auth_login(received_headers, get, post):
- print repr(post['username'][0]), ' is trying to login.'
- if post:
- _conn = sqlite3.connect('webserve-info.db')
- c = _conn.cursor()
- c.execute("SELECT * FROM users WHERE username = ? AND password = ? LIMIT 1", (post['username'][0], post['password'][0]))
- results = c.fetchone()
- if results:
- session = generate_session_id(post['username'][0])
- c.execute("""INSERT INTO sessions (user_id, session_id) VALUES(?, ?)""", (results[0], session))
- _conn.commit()
- C = Cookie.SimpleCookie()
- C['session'] = session
- C['session']['Path'] = '/'
- cookie_header = C.output().split(': ', 1)
- return 200, [cookie_header], ''
- return 401, [], '<h1>401 Unauthorized</h1>'
- def auth_logout(received_headers, get, post):
- cookies_in = Cookie.SimpleCookie()
- for (k, v) in received_headers:
- if k.lower() == 'cookie':
- cookies_in.load(v)
- C = Cookie.SimpleCookie()
- C['session'] = ''
- C['session']['Path'] = '/'
- _conn = sqlite3.connect('webserve-info.db')
- c = _conn.cursor()
- c.execute("""DELETE FROM sessions WHERE session_id = ?""", (cookies_in['session'].value,))
- cookie_header = C.output().split(': ', 1)
- return 200, [("Set-Cookie", "user=; Path=/"), cookie_header], ''
- def auth_print(received_headers, get, post):
- cookies_in = Cookie.SimpleCookie()
- for (k, v) in received_headers:
- if k.lower() == 'cookie':
- cookies_in.load(v)
- if 'session' in cookies_in:
- user = cookies_in['session'].value
- _conn = sqlite3.connect('webserve-info.db')
- c = _conn.cursor()
- c.execute("SELECT * FROM users INNER JOIN sessions WHERE users.id = sessions.user_id AND sessions.session_id = ? LIMIT 1", (user,))
- user = c.fetchone()
- if user:
- return 200, [], 'you are user %s' % (user[1],)
- return 200, [], 'no user specified'
- def movies_search_pair(received_headers, get, post):
- data = 'Movies Found:'
- actress = post['actress'][0]
- actor = post['actor'][0]
- _conn = sqlite3.connect('webserve-info.db')
- c = _conn.cursor()
- c.execute(
- """SELECT title FROM movies
- WHERE id IN (
- SELECT movie_id FROM roles INNER JOIN actors ON actors.id = actor_id
- WHERE (name = ? and male = 1) OR (name = ? and male = 0)
- GROUP BY movie_id
- HAVING count(*) = 2
- )
- """, (actor, actress))
- results = c.fetchall()
- if results:
- data += "<ul>"
- for movie in results:
- data += "<li>%s</li>" % (movie)
- return 200, [], data
- def add_user(username, password):
- _conn = sqlite3.connect('webserve-info.db')
- c = _conn.cursor()
- c.execute('INSERT INTO users (username, password) VALUES(?, ?)', (username, password))
- _conn.commit()
- def generate_session_id(user):
- """
- Generate a unique session ID based on the user name with the given
- site-specific secret. How secure is this, really? ANSWER: VERY SECURE
- """
- salt = secret[:2]
- return crypt.crypt(user + str(random.random()), salt)
- if __name__ == '__main__':
- host, port = sys.argv[1:]
- serve(host, int(port))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement