HTTP and HTTPS server with Python

Python 2 has already included an HTTP server module in its later versions. And running the server is as simple as this:

root@ubuntu-server1:/var/www/# python -m SimpleHTTPServer
Serving HTTP on 0.0.0.0 port 8000 ...

It starts the server on port 8000 (by default), and if we want to run on a different port, we will just add the new port number at the end of the command.

root@ubuntu-server1:/var/www/# python -m SimpleHTTPServer 8080
Serving HTTP on 0.0.0.0 port 8080 ...

With Python 3, the package merged into http.server. So we would call:

root@ubuntu-server1:/var/www/# python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 ...

When we need to customize how the server behaves (e.g. to run the server on a specific IP address), we can write a very simple python codes:

import SimpleHTTPServer
import SocketServer

web_server = SocketServer.TCPServer(("localhost", 8080), SimpleHTTPServer.SimpleHTTPRequestHandler)
web_server.serve_forever()

If we want HTTPS server, we will need to use built-in “ssl” module. We need to wrap the httpd socket with wrap_socket method. The certificate needs to be in PEM format (RFC1422).

import BaseHTTPServer, SimpleHTTPServer
import ssl

web_server = BaseHTTPServer.HTTPServer(('localhost', 8443), SimpleHTTPServer.SimpleHTTPRequestHandler)
web_server.socket = ssl.wrap_socket (web_server.socket,
                                     server_side=True,
                                     certfile="mydomain.crt",
                                     keyfile="mydomain.key")
web_server.serve_forever()

In general, we just need a socket and a handler to serve.

Making SQL Queries

This article is to summarize how do we make SQL queries using different languages and their methods. Making connection to the database will not be covered here.

In the examples, we will be querying “SELECT * FROM employees where eid =and dept =”

It is not recommended to use SQL statements without placeholders in order to reduce the risk of SQL injection.

Java

In Java, we can use JDBC, Hibernate, or some other database frameworks to interact with databases. Generally, I would prefer to use methods that allow me to insert “values” into an sql query. With JDBC, we can use PreparedStatement method. There is also createStatement method, where you insert user-supplied values into the query directly.

Basically the flow looks like this:

  1. Get a “Connection” object, with DriverManager
  2. From “Connection” object, we create a “Statement” object with sql statement.
  3. From the statement object, we generate “ResultSet”.
int employeeId = 512 // we will query for employee with id 512
int deptId = 206 // from department 206

Connection connection = DriverManager.getConnection(...); // please fill in
PreparedStatement statement = connection.prepareStatement("SELECT * FROM employees WHERE eid = ? AND dept = ?");
statement.setInt(1, employeeId); // use setString if the argument is a String
statement.setInt(2, deptId);
ResultSet rs = statement.executeQuery();
while (rs.next()) { // Iterate the result set
// ...
}

PHP

PHP has more methods to interact with database. It also depends on the module the php interpreter is built with. We can use MySQL extension, PostgreSQL extension, or ADODB or PDO as generic abstraction interfaces.

With mysqli extension

$db = new mysqli('localhost', 'user', 'password', 'world');
$statement = $db->prepare('SELECT * FROM employees WHERE eid = ? AND dept = ?');
$statement->bind_param('dd', $employeeId, $deptId); // types and variables

$employeeId = 512;
$deptId = 206;

$statement->execute();

NOTE: Why mysqli instead of mysql command? If we are using MySQL v4.1.3 and above, PHP manual recommends to use mysqli which is an improved version. Reference.

With PostgreSQL extension

$db = pg_connect("dbname=world");

$employeeId = 512;
$deptId = 206;

$result = pg_query_params($db, 'SELECT * FROM employees WHERE eid = ? AND dept = ?', array($employeeId, $deptId));

With ADODB

$db = NewADOConnection('mysql');
$db->Connect('localhost', 'user', 'password', 'world');
// Can also use $db = NewADOConnection('mysql://$user:$pwd@$server/$db?persist")
$rs = $db->execute('SELECT * FROM employees WHERE eid = ? AND dept = ?', array($employeeId, $deptId));
while($array = $rs->FetchRow()) {
//...
}

With PDO

$db = new PDO('mysql:host=$host;dbname=$dbname', $user, $pass);
$employeeId = 512;
$deptId = 206;

// We will use unamed placeholders.
$statement = $db->prepare('SELECT * FROM employees WHERE eid = ? AND dept = ?');
$statement->bindParam(1, $employeeId);
$statement->bindParam(2, $deptId);
$statement->execute();
// ...

KDE 4.8, Google Chrome and the Proxy

My KDE was just upgraded to v4.8 from v4.7.x. Privoxy was also configured on the same PC, just to strip some codes. Google Chrome is configured to use the Privoxy proxy on port 8118.

After the upgrade, Google Chrome has failed to connect to internet. At the same time, Firefox was working perfectly with or without using privoxy.

I tried to capture the packets on the local interface and on port 8118, and got nothing coming in. I wasn’t still sure what’s happening, and even tried to re-compile the privoxy, and tweak some of its settings. It was still not working.

Then, I needed to check KDE’s config file where it stores the proxy settings, as Google Chrome uses KDE’s settings. And there, the proxy is stored as “http://127.0.0.1 8118″, with a space between the host and the port. In version 4.7.x, it uses http://: format to store. Google Chrome fails to parse the setting. The config file is located under ~/.kde4/share/config/kioslaverc.

In order to make things work, I needed to manually tweak that line back to v4.7.x format, or exec Google Chrome with –proxy-server setting.

Python: Pyql module to obtain stock quotes from Y! Finance

I just made an initial attempt to fetch the stock quotes via YQL, and put the codes into a module. The method “lookup” will return a list of python dictionary item(s), based on the information decoded from Yahoo’s JSON data.

The current snapshot is posted on Google Code. The code doesn’t work with Python 3. It should work fine with Python 2.2 or higher.

To clone the source codes to a local resource, please feel free to do so via mercurial.

hg clone https://pyql.googlecode.com/hg/ pyql

Example Usage:

import pyql

tickers = ['AAPL', 'GOOG']
print ( pyql.lookup( tickers ) )
singleTicker = ['FFIV']
print ( pyql.lookup( singleTicker) )

UPDATE: Running WordPress with Nginx on ArchLinux

After moving to nginx with php-cgi, as described in my previous post, I found that “php-cgi” script has become pretty much unstable, with a lot of segmentation faults. I switched to “spawn-cgi” and the result is much more satisfactory =)