Plone 4.1 with Apache and mod_wsgi (sorta)

Update 2011-06-01: Still not working perfectly, but I did manage to clean up a couple steps by using more of mod_wsgi’s bells and whistles:

Issues:

  • The site is still slow (despite using Daemon Mode)
  • I get signal errors. This is a known problem when trying to serve signal-dependent python stuff via mod_wsgi, but I’m not sure it causes any real problems.
    [Wed Jun 01 17:59:40 2011] [warn] mod_wsgi (pid=12739): Callback registration for signal 10 ignored.
    [Wed Jun 01 17:59:40 2011] [warn]   File "/var/www/Plone-ZEO-4.1rc2/zeocluster/zope2.wsgi", line 3, in 
    [Wed Jun 01 17:59:40 2011] [warn]     application = make_wsgi_app(None, '/var/www/Plone-ZEO-4.1rc2/zeocluster/parts/client1/etc/zope.conf')
    [Wed Jun 01 17:59:40 2011] [warn]   File "/var/www/Plone-ZEO-4.1rc2/buildout-cache/eggs/Zope2-2.13.7-py2.6.egg/Zope2/Startup/run.py", line 68, in make_wsgi_app
    [Wed Jun 01 17:59:40 2011] [warn]     starter.prepare()
    [Wed Jun 01 17:59:40 2011] [warn]   File "/var/www/Plone-ZEO-4.1rc2/buildout-cache/eggs/Zope2-2.13.7-py2.6.egg/Zope2/Startup/__init__.py", line 90, in prepare
    [Wed Jun 01 17:59:40 2011] [warn]     self.registerSignals()
    [Wed Jun 01 17:59:40 2011] [warn]   File "/var/www/Plone-ZEO-4.1rc2/buildout-cache/eggs/Zope2-2.13.7-py2.6.egg/Zope2/Startup/__init__.py", line 340, in registerSignals
    [Wed Jun 01 17:59:40 2011] [warn]     self.cfg.trace])
    [Wed Jun 01 17:59:40 2011] [warn]   File "/var/www/Plone-ZEO-4.1rc2/buildout-cache/eggs/Zope2-2.13.7-py2.6.egg/Signals/Signals.py", line 115, in registerZopeSignals
    [Wed Jun 01 17:59:40 2011] [warn]     SignalHandler.registerHandler(SIGUSR1, showStacks)
    [Wed Jun 01 17:59:40 2011] [warn]   File "/var/www/Plone-ZEO-4.1rc2/buildout-cache/eggs/Zope2-2.13.7-py2.6.egg/Signals/SignalHandler.py", line 37, in registerHandler
    [Wed Jun 01 17:59:40 2011] [warn]     signal.signal(signum, self.signalHandler)
  • In many cases I can’t POST to the site. I can log in as long as it’s not HTTP Basic, but I can’t edit pages or make site-setup configuration changes. Not sure why.

Notes:

  • For the following instructions I did every step as the user apache, so Plone runs as that user, as does zeo. This may not be the absolute best practice, but it made things a bit simpler.
  • You can substitute instance in probably every case cartier love bracelet ebay fake
    I used client1.
  1. Install Apache and mod_wsgi. Make sure to specify Python 2.6 for mod_wsgi.
  2. Grab a Plone 4.1 release candidate and install it as the user apache. Use the same Python 2.6 as you did for mod_wsgi.
  3. Create a path configuration file:
    $ ( # Do this in a subshell so we don't contaminate the IFS
    >   # variable in our normal shell.
    > cd /var/www/Plone-ZEO-4.1rc2/buildout-cache/eggs
    > eggs=( *.egg )
    > IFS=$'\n'
    > echo "${eggs[*]}" > mod_wsgi.pth
    > )
  4. In your fake cartier bracelets
    buildout cartier love necklace directory cartier love bangle create an empty file called ‘zope2.wsgi.in’ as a collective.recipe.template template.copy the bin/client1 file into zope2.wsgi.in (because you need all the egg paths)
  5. Put these two lines in it:
    from Zope2.Startup.run import make_wsgi_app
    application = make_wsgi_app(None, '${zope-conf}')
  6. Add a section called wsgi to your buildout.cfg file:
    [buildout]
    …
    parts =
            …
            wsgi
            …
    …
    [wsgi]
    recipe = collective.recipe.template
    input = zope2.wsgi.in
    output = zope2.wsgi
    zope-conf = ${client1:location}/etc/zope.conf
  7. In your apache config:
    …
    WSGIPythonPath /var/www/Plone-ZEO-4.1rc2/buildout-cache/eggs/
    WSGIDaemonProcess neon processes=1 threads=1 python-path=/var/www/Plone-ZEO-4.1rc2/buildout-cache/eggs/
    WSGIProcessGroup neon
    WSGIScriptAlias / /var/www/Plone-ZEO-4.1rc2/zeocluster/zope2.wsgi
    
    <Directory "/var/www/Plone-ZEO-4.1rc2/zeocluster">
            Order allow,deny
            Allow from all
    </Directory>
    …
  8. Run buildout and start replica cartier the zeoserver.
  9. I had some problems with cartier love bracelet replica HTTP Basic Authentication through WSGI, so I avoided it by starting cartier bracelet of anastasia steele actress
    the client without WSGI for the purpose of logging in to the ZMI to create the Plone site. bin/client1 fg
  10. Log in to http://localhost:8080 and create the Plone site.
  11. Once I had actually created the Plone site, I killed the client1 instance and removed the <http-server> section from zope.conf
  12. Start apache, and observe the logs as you navigate around your Plone site on port 80.

As I said, my site is slow and a lot of errors appear in the logs, but it’s functional, which is better than I’ve seen it so far. More work on this later.

The Future of the Internet is in the Client and the Cloud

Commentary on: http://www.zdnet.com/blog/btl/the-future-of-the-internet-its-in-the-app/49512?tag=nl.e539

The Forrester CEO cited in this article strikes me as remarkably naïve
(or maybe badly misquoted). I’m not downplaying the importance of
apps, but 90% of the popular www.cartierbracelets.co apps bracelets on the market are popular because
they exchange cartier love bracelet ebay fake
data with a web server. “Leaves cloud computing in the
dust”? I don’t think so. The app model depends on cloud computing.

Now, there’s been some interesting development in the area of merging
the concept of apps with websites. Both Google and Mozilla are working
on it from opposite ends: Google with its ChromeOS efforts (oddly,
ChromeOS is diametrically opposite of the space cartier bracelet of anastasia steele actress
occupied by Android,
but I think Google’s doing that strategically replica cartier love bracelets and on purpose) and
Mozilla with its Open Web Applications project.

I’m not sure cartier bracelets what approach Microsoft will really take. They’ve made
their position on HTML 5 clear, and that’s a good thing, but as for
apps they seem to just be covering their bases. (They’ve made it
possible to install Android apps on the Windows Mobile platform, for
example.)

I am interested in the app model, definitely, but the Internet isn’t
going to change as drastically as Colony seems to think. The article
does rightly point out that the Internet will use more of the power of
client machines than it has in the past, but that has less discount cartier bracelet to do with
apps than it does with the growth of HTML 5, powerful Javascript
engines like V8 and frameworks like Sencha and JQuery. (Those tend to
be hidden behind app development anyway.)

So I’m following the app discussion carefully, but really focusing my
efforts on the cross-platform frameworks like Mozilla’s OWA, because replica cartier love bracelets I
think that’s where the biggest bang for my buck will end up.

How to force HTTPS on Facebook and Twitter

HTTPS is a way of providing security and privacy cartier love cartier love bangle bracelet replica for your communication with web sites. You should expect it from sites that deal with your money, such as your bank, or Amazon.com, but you might cartier bracelet
not realize how important it is for sites like Facebook or Twitter. Think of it this way: When you protect your financial information, you’re protecting yourself, but when you protect your Facebook account, you’re protecting your friends. Using https keeps your accounts cartier bracelet and reputation secure.

Many sites, Facebook included, have support for https, but immediately redirect you back to the insecure site, or forget to record your login session in a secure way. A Firefox Add-on called hermes h bracelet
NoScript” provides a solution to both cartier love bracelet ebay fake
these problems. Here’s how to make it happen:

  1. Install the Add-on.
  2. Restart Firefox
  3. In Firefox, go to Tools cartier bracelet of anastasia steele actress
    –> Add-ons –> NoScript –> NoScript Preferences –> Advanced tab
  4. In the “Behavior” tab under “Force the following sites to use secure (HTTPS) connections:” add the sites you want to secure. If you want to secure every subdomain of a domain, start with a dot. My entry looks like:
    .facebook.com
    .twitter.com
    
  5. In the “Cookies” tab check “Enable Automatic Secure Cookies Management”.
  6. Under “Force encryption for all the cookies set over HTTPS by the following sites:” add the same sites again. This replica cartier love bracelets will keep your login secure even over open wireless.

Now, in the future, your logins to those sites will be secure. NoScript will also do other things, such as block JavaScript and Flash by default for sites it doesn’t know about. If you want Javascript on for a site, you can just whitelist that site. NoScript will make it clear when it’s blocking JavaScript. You’ll see it in action the first time you visit Facebook and Twitter.

Let’s try it:

Go to http://facebook.com. First, notice that the URL changes to https://www.facebook.com. Now, you’ll also see NoScript letting you know that it blocked facebook.com. Just select “Allow all this page” from NoScript’s options.

Now you know enough to surf safely and protect your accounts on sites like facebook.com and twitter.com. For more information, read the NoScript FAQ.

How to drop 32-bit support from AMD64 Gentoo

In the wake of the recent cartier love bracelet ebay fake
kernel exploits I determined
I didn’t really need 32-bit support on most of my 64-bit machines. The vulnerabilities in question depend upon 32-bit support, so dropping that support resolves the issue without me having to patch cartier bracelet the kernel or really change what software I’m running at all. Here’s how I did it.

I should point out that you cannot simply go back to having 32-bit support after you do this. This is a one-way change!

Step 1: Make sure you have cartier nail cartier replica bracelet
a 64-bit capable bootloader:

You can use lilo or grub2. Lilo cartier bracelet of anastasia steele actress
is documented in the Gentoo handbook, and I haven’t tried Grub2.

Step 2: Switch to non-multilib profile:

WEB-SVN ~ # eselect profile list
Available profile symlink targets:
[1] default/linux/amd64/10.0 *
[2] default/linux/amd64/10.0/desktop
[3] default/linux/amd64/10.0/desktop/gnome
[4] default/linux/amd64/10.0/desktop/kde
[5] default/linux/amd64/10.0/developer
[6] default/linux/amd64/10.0/no-multilib
[7] default/linux/amd64/10.0/server
[8] hardened/linux/amd64/10.0
[9] hardened/linux/amd64/10.0/no-multilib
[10] selinux/2007.0/amd64
[11] selinux/2007.0/amd64/hardened
[12] selinux/v2refpolicy/amd64
[13] selinux/v2refpolicy/amd64/desktop
[14] selinux/v2refpolicy/amd64/developer
[15] selinux/v2refpolicy/amd64/hardened
[16] selinux/v2refpolicy/amd64/server
WEB-SVN ~ # eselect profile set 6 && eselect profile show
Current make.profile symlink:
default/linux/amd64/10.0/no-multilib

Step 3: Emerge packages whose replica cartier useflags have changed:

WEB-SVN ~ # emerge -1 sandbox glibc gcc
...much noise...
WEB-SVN ~ # rm /etc/env.d/04multilib &&
> env-update &&
> . /etc/profile &&
> fix_libtool_files.sh "$(gcc -dumpversion)"
...well, fix_libtool_files.sh didn't seem to change anything, but it was a good idea anyway...
WEB-SVN ~ # cat /etc/ld.so.conf # to check if there are 32-bit libs left
# ld.so.conf autogenerated by env-update; make replica cartier love bracelets all changes to
# contents of /etc/env.d directory
/usr/local/lib
include ld.so.conf.d/*.conf
/usr/x86_64-pc-linux-gnu/lib
/usr/lib/gcc/x86_64-pc-linux-gnu/4.4.3
/usr/lib64/postgresql-8.4/lib64

Looks good!

Remove 32-bit support in the kernel


WEB-SVN ~ # cd /usr/src/linux && make menuconfig
...
Executable file formats / Emulations ---> [ ] IA32 Emulation
...
WEB-SVN ~ # make &&
> mount -o remount,rw /boot &&
> make install modules_install &&
> module-rebuild -X rebuild &&
> shutdown -r now

That’s it!

Doubleclick.wtf

pre { overflow-x: auto; }
code { white-space: nowrap; }

Steve and I were asked to implement doubleclick.net for some site by “oh you just drop some code in the page and it works great OK?”

No. We never do this, because we’re actually responsible for the crap that gets served from our servers, and there’s already enough clean-up we have to do.

So let’s take a look at this code (with identifying marks removed to protect the funky).

Here’s the original code:

<script type="text/javascript">
var axel = Math.random() + "";
var a = axel * 10000000000000;
document.write('<iframe src="http://fls.doubleclick.net/activityi;src=1234567;type=feline123;cat=tabby012;ord=1;num=' + a + '?" width="1" height="1" frameborder="0"></iframe>'); 
</script> 
<noscript> 
<iframe src="https://fls.doubleclick.net/activityi;src=1234567;type=feline123;cat=tabby012;ord=1;num=1?" width="1" height="1" frameborder="0"></iframe> 
</noscript>

Well that’s special. It generates an iframe so it can load whatever content it wants cartier replica from doubleclick.net’s servers. That makes me slightly nervous and annoyed, but what’s worse, the code is invalid XHTML strict, so I’m going to have to rewrite it to be valid. Might as well rewrite the whole fake cartier bracelets
thing, since cartier love bracelet the Javascript is pretty stinky, too. (At least they took the trouble cartier love bracelet ebay fake
to write a noscript cartier love bracelet version)

var axel = Math.random() + "";
var a = axel * 10000000000000;

What does it do? Well, at first
glance it looks like it tries to create a very cartier bracelet of anastasia steele actress
long string. But actually no, in Javascript, "12345.67" * 1 == Number(12345.67). So this can be rewritten to make sense, be more efficient, and be one line: var a = 10000000000000 * Math.random();

Next, we can build the attributes in a way that makes this whole block of code more reusable:

var url_src = 1234567;
var url_type = "feline123";
var url_cat = "tabby012";
var url_ord = 1;
// and just for completeness
var url_num = a;
var data = "http://fls.doubleclick.net/activityi" +
  ";src=" + url_src +
  ";type=" + url_type +
  ";cat=" + url_cat +
  ";ord=" + url_ord +
  ";num=" + url_num + "?";

Then we’ve got the invalid iframe element. The object tag can be used in most cases in place of the iframe tag, so let’s use that. We build the element into the DOM:

var o = document.createElement("object");
o.data = data;
o.width = 1;
o.height = 1;
// Ignore that "frameborder" attribute because
// it's neither valid nor valuable.

…and since we were asked to insert this code “as close as possible to the opening <body> tag,” insert it before the first child of the body element:

var b = document.body;
b.insertBefore(o, b.firstChild);

Putting it all together:

// Remember me? I got renamed!
var url_num = 10000000000000 * Math.random();
var url_src = 1234567;
var url_type = "feline123";
var url_cat = "tabby012";
var url_ord = 1;
var data = "http://fls.doubleclick.net/activityi" +
  ";src=" + url_src +
  ";type=" + url_type +
  ";cat=" + url_cat +
  ";ord=" + url_ord +
  ";num=" + url_num + "?";

var o = document.createElement("object");
o.data = data;
o.width = 1;
o.height = 1;

var b = document.body;
b.insertBefore(o, b.firstChild);

When I ran this code in Firebug, it produced the following DOM node on my page:

<object height="1" width="1" data="http://fls.doubleclick.net/activityi;src=1234567;type=feline123;cat=tabby012;ord=1;num=9608606539790.215?"></object>

So I figured I would grab a copy of that URL using wget and see what it looked like. It looks like this:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><title></title></head><body style="background-color: transparent"><img src="http://ad.doubleclick.net/activity;src=1234567;type=feline123;cat=tabby012;ord=1;num=9608606539790.215?" alt=""/></body></html>

So… Wait, what? The only differences between the URL in that <img> and the URL generated for the <object> is fls has become ad and activityi has become activity. So why didn’t we just load that <img> in the first place? Only hermes h bracelet
Doubleclick knows for sure, but loading the iframe and then the image does tell them a little bit more about browser capabilities, because it makes two different requests to their servers from your browser. Clever, but very irritating. On the other hand, maybe they’re just using the <img>.

Using find in Subversion working copies

The POSIX find command is extremely convenient and powerful for searching cartier love bracelet ebay fake
out files and features of the filesystem. In combination with its -exec action it can make changes to many files based on nuanced characteristics. I can’t live without it.

However, it’s inconvenient to use find in Subversion working copies because of all the .svn folders. Find searches within all of them, and since they contain duplicates of the files in the working copy itself, things get cumbersome fast.

You can work around this by pruning .svn:

find . -name .svn -prune -o -print

but find’s -prune flag is pretty intricate and befuddles even the smartest administrators and developers from time-to-time, especially if you don’t understand the default cartier bracelet of anastasia steele actress
cartier nail bracelet
cartier love bracelet
action, -print.

To make this easier, I’ve written cartier bracelet replica cartier love bracelet a shell function that automatically prunes “.svn” and anything found in the svn property “svn:ignore” in the target cartier bracelet
path. Feel free to use this if you find it convenient.

svnfind() {
	# find things in an svn working copy
	# excluding .svn dirs and anything
	# in the target directory's svn:ignores
	local ignores=()
	local IFS=$'\n'
	local path

	# GNU no-path compatibility
	case "$1" in
		-*) path=".";;
		*) path="$1"; shift;;
	esac

	set -f # turn replica cartier ring off globbing temporarily
	local _ignores=( $(svn pg svn:ignore "$path") )
	for i in "${_ignores[@]}"; do
		ignores+=( -o -name "$i" )
	done
	set +f

	# If find contains no "actions" other than -prune,
	# append the default action of -print
	local default="-print"
	for arg; do
		case "$arg" in
			-delete|-exec|-execdir|-fls|-fprint|-fprint0|-ls|-ok|-okdir|-print|-print0|-printf|-quit)
				unset default
				break;;
		esac
	done
	# $default must be unquoted here
	find "$path" \( -name .svn "${ignores[@]}" \) -prune -o "$@" $default
}

Sony, Hulu, and Net Neutrality

Neither Sony nor Hulu are Internet Service Providers, so you might wonder how they can be involved hermes outlet
in the Net Neutrality dispute. Let me explain how they relate.

I purchased Hulu Plus today, with the understanding that a Hulu Plus membership is required in order to view Hulu-streamed content on my television via my Sony Playstation 3. (This is already a fair-use stretch hermes replica belt
for me, because I paid money for my Playstation, and think I should be able to use it like any other computer I own.) When I went to try to use it, I discovered that in addition to a Hulu Plus membership, you must poloponynetwork.com also have a Playstation Plus membership to view the content from Hulu on a PS3.

“OK,” you might ask, “I see how that’s annoying, but what does it have to do with Net Neutrality?”

From Wikipedia, “The [Network neutrality] principle states that if a given user pays for a certain level of Internet access, and another user pays for the same level of access, then the two users should be able to connect to each other at the subscribed level of access.”

I’ve paid for my Hulu Plus membership. Hulu is providing the same level of access to people using other devices, but not to me. I would need to pay for an additional tier of access to receive that content on a device that I own. Keep in mind here, nobody is asking me to pay for software or hardware replica hermes printed enamel bracelets
that makes my Playstation able to view content it would otherwise be unable to view. That would be fair. But my Playstation 3 is capable of playing content from Hulu. In fact, Playstations used to do that and were later blocked deliberately. Asking me to pay more for services available to others who are not paying more: that is unfair and should be illegal.

Reply to this rant on Twitter — @michaelasmith.

Arbitrary-sort XSLT

I wanted hermes h belt to see if it’s possible to use xslt to sort an xml document in an order specified by another document. It is, but I’m not satisfied with my solution yet.

The problem replica hermes printed enamel bracelets
is it takes too many iterations to sort in that order. I have to loop through the sortOrder document and then loop through the context document for each node. I should be able to just look up a node by some value. Those of you who know XSLT will say “of course you can look up a node by its name! That’s what hermes belt xsl:key is for!”

You’d be right, too, except for the fact that to do this view the website
sort requires a loop over the sortOrder document, and inside the scope of that loop you cannot access the key! doh!

Anyway, I’m still thinking about this, but I’d love to hear it if anyone comes up with a solution. Just post it in a forum somewhere and I’ll find it. 😉