Thursday, September 17, 2009

Magento and PHP5 Install Memory Error

If, when installing Magento Ecommerce, you experience some variant of this message:

Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 24 bytes) in /home/userdir/sites/mywebsite.com/public_html/magento/lib/Zend/Db/Statement/Pdo.php on line 232

The solution is simple. Just go to your

/etc/php5/apache2/php.ini*

and set memory higher than the default of 16M. The error trace indicates a minimum requirement of 24M for successful installation.‡

But you knew that already, right?

* php.ini may be in a different directory
‡ full disclosure: I allotted 64MB since the slice I'm using has 512MB available.

Friday, September 11, 2009

Proxy Debuggers and Flex NetConnection Debugger

With AS2, setting up a NetConnection between a Flash Player and a server running Flash Remoting could be streamlined using the Flex NetConnection Debugger. It was included with Flex 1.0 ca. 2005 and only required two short steps to enable. Many developers included it in their remoting utilities shortlist.

Now that we're living in a CS4 age, the playing field has changed. All the functionality of the NetConnection Debugger has been integrated into the Flash library. This means that instead of launching separate apps for debugging, you can simply mock up a routine using calls to available library components.

Good enough, but if you prefer a dedicated debugging app, NetConnection Debugger is out, and some other options are in its place.

Midnight Coders App Puncher

Much has been said about Midnight Coders' contributions to RIA development. Their middleware tier is arguably the best muscle around and can be a real time-saver. I'm speaking of WebORB, but particular to debugging, have a look at another of their products, the RIA App Puncher.

Charles Web Debugging Proxy

Link to Charles.

ServiceCapture

Link to ServiceCapture.

Wednesday, September 9, 2009

Virtualenv vs Virtual-Python

If you harbor multiple versions of Python, as is usually a good idea, you can go at least two routes:
  1. Virtualenv
  2. Virtual-Python
Both organize your all-important PYTHONPATH environment variable and keep your preferred python executable at the ready. This in turn makes module add-ons, test projects and installations easy.

On that note, Easy_install recommends virtual-python.py as a quick way to keep organized. It is indeed easy to set up and concise as well.

Another option, the one I use incidentally, is virtualenv. Once installed, all you need to do to switch active versions is activate it via the command line.

In a newly created virtualenv there will be a bin/activate shell script, or a Scripts/activate.bat batch file on Windows.


On Posix systems you can do:

$ source bin/activate


Even better than that is Doug Hellmann's virtualenvwrapper which, as he describes, allows you to set a working python environment with a single command. It's easy to set up as well, just a couple of lines into your bash script and bombs away, your virtualenv is wrapped.

With these options, you can initiate new projects and test new python libraries without any conflicts or misgivings. Try it out sometime. What have you got to lose?

Mimic AMF Header to get an HTTP response

Following on the last post, you can use netcat to get an error from a python gateway. But how is it possible to get a successful response from a python gateway? As previously seen, you can use a client in a python command line. But what about using the netcat 'swiss-army knife' to elicit a successful response from an AMF gateway?

Read this page from OS Flash to learn the composition of an AMF header.

Tuesday, September 8, 2009

Putting available ports to use with AMF

In a previous post, see a detailed a procedure to choose and make available a tcp/alt port on a web server to avail the use of asynchronous data services. That post leads to this one, in which AMF calls are made over the available port.

To start, here is a method to test the port for an http response using netcat, via stearns.org:
echo -e "GET http://yoursite.com HTTP/1.0\n\n" | nc yoursite.com 80 | less
...or using the alternate available port...
echo -e "GET http://yoursite.com HTTP/1.0\n\n" | nc yoursite.com 8080 | less
This is a good example of using netcat as a client to get a response from an http service.

Analogous to this is the stated goal of this post, establishing connectivity between a lightweight client and an AMF service. Does that service by definition reside on an HTTP gateway? What type of gateway is the service? That remains to be answered.

For now, note that there is a starting example available from pyamf.com that allows you to test a connection to a third-party HTTP gateway. Titled PyAMF AMF Client, it works in the following manner to establish a simple methodology.
  1. In SSH, launch a python command line
  2. Load the modules in pyamf to initiate a test
  3. Request the remote service and look for a successful response
Here, copied from the pyamf.com example, is the applicable sequence
from pyamf.remoting.client import RemotingService

client = RemotingService('http://demo.pyamf.org/gateway/recordset')
service = client.getService('service')

print service.getLanguages()
...which should directly result in the following response from pyamf.com
<pyamf.amf0.recordset><pyamf.amf0.recordset></pyamf.amf0.recordset></pyamf.amf0.recordset>
Why does this work as it should? Some of the reasons why it works

pyamf.remoting.client.RemotingService (see API)


We instantiated the class RemotingService, the instance call of which includes a parametric reference to an available gateway. Once you provide a valid gateway address, you have established a client for AMF calls.


getService method


The method parameter is the name of a service, in this case the service defined at http://demo.pyamf.org/gateway/recordset/. Try browsing to this address and you will see


400 Bad Request

To access this PyAMF gateway you must use POST requests (GET received)

The gateway provides information that it is a PyAMF gateway and only accepts POST requests. If you use netcat to contact the gateway...


echo -e "GET http://demo.pyamf.org/gateway/recordset HTTP/1.0\n\n" | nc demo.pyamf.org 80 | less

...you will get a similar response. If you netcat a POST to the gateway, you will get this...

HTTP/1.1 500 Internal Server Error
Date: Wed, 09 Sep 2009 15:21:18 GMT
Server: Apache/2.0.55 (Ubuntu) DAV/2 SVN/1.5.6 mod_python/3.3.1 Python/2.5.4 mod_wsgi/2.4 PHP/5.1.2 mod_ssl/2.0.55 OpenSSL/0.9.8a mod_perl/2.0.2 Perl/v5.8.7
Content-Length: 534
Connection: close
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>500 Internal Server Error</title>
</head><body>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error or
misconfiguration and was unable to complete
your request.</p>
<p>Please contact the server administrator,
info@pyamf.org and inform them of the time the error occurred,
and anything you might have done that may have
caused the error.</p>
<p>More information about this error may be available
in the server error log.</p>
</body></html>

This is a longer response, but not a successful response. The question remains, how can a request to the server result in a service initiation? Let's look at some other possibilities.

Friday, September 4, 2009

RemoteObject Endpoints in Django

A few quick assumptions about your project:
  • It's built with a lightweight proxy server such as nginx or lighttpd
  • It utilizes the Django web framework
  • It remotes data using some form of ORM
  • It is presented via Flash/Flex
If this is the case, the simplest and most straightforward way to configure your gateway is by setting it at the root URL:

#my /etc/nginx/sites-enabled/mysite.conf
server {
listen 50.5.5.50:80;
server_name myurl.com www.myurl.com;
if ($host = 'www.myurl.com' ) {
rewrite ^/(.*)$ http://myurl.com/$1 permanent;
}

location / {
proxy_pass http://127.0.0.1:80/;
include /etc/nginx/proxy.conf;
}

location /media/ {
root /home/django/domains/myurl.com/public_html/;
}
}


Thus all web traffic that doesn't match '/media/' is passed to the urls.py for further processing. This is however at odds with your remoting requirements for Flash/Flex. To wit, you need a static file called crossdomain.xml to be available at your site's web root in order to meet the Flash client's security needs.

I looked for a good answer to this and found the Django-Flashpolicies by James Bennett effective and QUICK for this very purpose.

All you will need to do, essentially, is this:
easy_install django-flashpolicies

...and this...


url(r^'crossdomain.xml$',
'flashpolicies.views.simple',
{'domains': ['media.example.com', 'api.example.com']}),

...and you're good to go. Works better than a savage karate chop to the nose, most of the time anyway.

Hope that allows you to move forward quickly.

Thursday, September 3, 2009

Apache DocumentRoot in Python and Django

Be very deliberate in your overall architecture when setting up new django projects. The directory dependencies resulting from an apache-nginx-python-django server configuration can make your path dependencies very complicated.

Generally put, being indiscriminate in your setup now will result in extreme challenges to resource deployment later on.

Here are some working methods that can greatly complicate your setup:
  • Hosting several modules on one URL
  • Having only one virtual host for many projects
  • Hosting several modules on one server account
  • Setting Python gateway modules off the root of your URL
  • Using Python server.py-type gateways in addition to ordinary http gateways
Here are some ways to simplify your paths:
  • Set up several virtual hosts
  • Host only one Django project per URL (or as few as you can manage)
  • Clearly structure your resources to discourage any overlap on your VPS or dedicated server
  • Consider the trade-offs between a complex rig of sites and resources and several simple unrelated server environments. There's really no need to attempt the most complex possible solution unless that's your bag.
The nice thing about Python and Django is that they can handle either direction. There's a way to work everything out however you prefer, and the choice is yours to make.

That said, remember also that it is nice when projects just work without a lot of complex troubleshooting or traffic control.

Here is an example of a moderately complex configuration with a mixed bag of pros and cons.

Simple Endpoint Test for Asynchronous Unit and Integration Processes

In the creation of open-source RIAs, it can be very difficult to ensure connectivity of endpoints. There are potential snags and edge cases surrounding the following critical points:
  • Security clearance of port
  • Availability of port resource
  • Conflicts between multiple running servers
  • Properly-declared URI endpoints
As in point three, matters can be complicated when proxy servers, such as lighttpd or nginx are working in conjunction with apache. Most likely, both are open on different IP registers on port 80; apache proxy on localhost, and the lightweight server on the public IP.

An RIA will asynchronously connect via a RemoteObject call on another port. It requires a valid connection. Utilities like netcat can save you from a quagmire of ineffectual random testing.

First, open the port in apache, as it will be the ORM-enabled server. Typically, the port is 8000 or 8080 for arbitrary reasons of convention and familiarity. Make sure your 8000 or 8080 is not tied up with memchache or some other port-requisite ancillary utility. Open up ports.conf and add the port in the configuration script.

TEST THE PORT

Restart the apache server. Using a port utility such as netcat, test port connectivity. One quick way is to use netcat from a command line. Netcat will attempt to connect to any port(s) you specify and report the protocol it encountered:

nc -v -w 2 -z target 20-30

FIREWALLS

Don't forget to modify your security settings to allow the port! Specifically, if you have set up a firewall, iptables requires an entry allowing public connections over the port in question or connections will fail. If they have been changed, be sure to restart the apache server and that the rules have been saved either via command-line or the initializing script, usually /etc/network/interfaces.

Be sure your apache server's NameVirtualHost settings allow the wildcard * and not only localhost connections. This way, requests from your http-alt port will bypass your proxy server altogether. Apache might warn you thus, but it can be ignored:

[Thu Sep 03 16:20:42 2009] [warn] NameVirtualHost *:80 has no VirtualHosts

With these potential obstructions addressed, you should be able to tunnel your way to fame and fortune.

NEXT UP

How to put that port to use in an RIA RemoteObject call.