Friday 23 November 2012

Linux driver file (PPD) for Fuji Xerox printers

The cheapskates at FX don't provide PPDs for Linux, even though they are the same as the MacOS files.

Now, opening apple's *.dmg files is surprisingly convoluted.  Here's a step-by-step guide to, hopefully, save you some time.

1. Download the MacOS ApeosPort IV drivers from Fuji Xerox's site.
2. Download dmg2img (I downloaded the source code for dmg2img and ran `make' - you guys rock!).
3. Convert the dmg file into an image:

./dmg2img ~/Downloads/fxmacprnps1208am105iml.dmg /tmp/out.img

4. Mount the obtained image:

sudo mount  -o loop /tmp/out.img /mnt/iso/

5. Use xar (yum install xar) to extract the pkg file:


cp /mnt/iso/Fuji\ Xerox\ PS\ Plug-in\ Installer.pkg /tmp/
cd /tmp && mkdir fx && cd fx
xar -xf ../Fuji\ Xerox\ PS\ Plug-in\ Installer.pkg 

6. Inside the extracted folders, locate and copy the Payload file with the PPDs:

cp ppd.pkg/Payload /tmp/Payload.cpio.gz

7. Gunzip the file and extract the cpio archive:

cd /tmp
gunzip Payload.cpio.gz
mkdir ppd && cd /tmp/ppd
cpio -id < ../Payload.cpio

8. VoilĂ ! your PPD files are in Library/Printers/PPDs/Contents/Resources/:

$ls
Fuji Xerox 4112 PS.gz          FX ApeosPort-IV C4475 PS.gz     FX DocuCentre-IV 7080 PS.gz
Fuji Xerox 4127 PS.gz          FX ApeosPort-IV C5570 PS.gz     FX DocuCentre-IV C2260 PS.gz
Fuji Xerox D110 PS.gz          FX ApeosPort-IV C5575 PS.gz     FX DocuCentre-IV C2263 PS.gz
Fuji Xerox D125 PS.gz          FX ApeosPort-IV C5580 PS.gz     FX DocuCentre-IV C2265 PS.gz
Fuji Xerox D95 PS.gz           FX ApeosPort-IV C6680 PS.gz     FX DocuCentre-IV C2270 PS.gz
FX ApeosPort 350 I  PS B.gz    FX ApeosPort-IV C7780 PS.gz     FX DocuCentre-IV C2275 PS.gz
FX ApeosPort 350 I  PS.gz      FX DocuCentre 450 I  PS B.gz    FX DocuCentre-IV C3370 PS.gz
(...)

Enjoy.

Thursday 8 November 2012

Caching 301 redirects in Varnish while keeping the protocol

I have noticed a drop in our Varnish cache hit ratio and, upon investigation, found that the backend was not allowing 301 redirects to be cached:

Client request:
   42 RxRequest    c GET
   42 RxURL        c /img_resized/au/images/gifts/2012/hero/christmas-homepage-hero-alyce.jpg
   42 RxProtocol   c HTTP/1.1

Backend request: 
   21 TxRequest    b GET
   21 TxURL        b /img_resized/au/images/gifts/2012/hero/christmas-homepage-hero-alyce.jpg
   21 TxProtocol   b HTTP/1.1

Backend response: 
   21 RxHeader     b Cache-Control: no-cache
   21 RxHeader     b Location: http://static.example.com/img/au/images/gifts/2012/hero/christmas-homepage-hero-alyce.jpg
   21 RxHeader     b Status: 301

I logged a bug for the application to be fixed and, in the meantime, added a VCL snippet to override the backend headers:

        # WSF-xxxx: App is not allowing redirects to be cached
        if ((req.http.Host == "static.example.com") &&
           (beresp.status == 301) &&
           (beresp.http.Cache-Control ~ "no-cache")) {
                set beresp.http.Cache-Control = "public, max-age=604800";
        }

There's a catch though.  We do SSL offloading for static.example.com in our F5 BigIP LTM load balancer.  In other words, the load balancer receives a https request and, in turn, makes a http request to Varnish.

As Varnish doesn't support SSL natively it is unaware of the protocol (http or https) being used; thus, the requests below get cached with the first answer it sees:

HTTP request
curl -I http://static.example.com/img/au/images/gifts/2012/hero/christmas-homepage-hero-alyce.jpg
(...)
HTTP/1.1 301 Moved Permanently
Location: http://static.example.com/img/au/images/gifts/2012/rectangle-75-58/christmas-promo-tile-alyce.jpg

HTTPS request
curl -I https://static.example.com/img/au/images/gifts/2012/hero/christmas-homepage-hero-alyce.jpg
(...)
HTTP/1.1 301 Moved Permanently
Location: http://static.example.com/img/au/images/gifts/2012/rectangle-75-58/christmas-promo-tile-alyce.jpg

Notice that the HTTPS request was redirected to a HTTP URL.  This will most certainly cause issues, including mixed-mode SSL alerts in some browsers.

Our backend is a Ruby on Rails application and, to my surprise, it understands the X-Forwarded-Proto HTTP header.  This means that the application will use the value of X-Forwarded-Proto to build the URL in the Location header.

I improved the F5 iRule by instructing the load balancer to insert a X-Forwarded-Proto header in HTTPS requests which were being off-loaded to Varnish:

when HTTP_REQUEST {
      HTTP::header replace X-Forwarded-Proto "https"
}

In addition to this, I also had to instruct Varnish to use the X-Forwarded-Proto header in the cache hash:

sub vcl_hash {
if (req.http.X-Forwarded-Proto) {
set req.hash += req.http.X-Forwarded-Proto;
}
}

With these tweaks Varnish is now able to account for SSL offloading and correctly serve the appropriate cached version of a page.  An improvement on this configuration would be to only use X-Forwarded-Proto in the hash if the response is a redirect; at the moment I can't be bothered that Varnish is caching objects twice.

HTTP request
$curl -I http://static.example.com/img_resized/au/images/gifts/2012/rectangle-75-58/christmas-promo-tile-alyce.jpg
HTTP/1.1 301 Moved Permanently
Location: http://static.example.com/img/au/images/gifts/2012/rectangle-75-58/christmas-promo-tile-alyce.jpg

HTTPS request
$curl -I https://static.example.com/img_resized/au/images/gifts/2012/rectangle-75-58/christmas-promo-tile-alyce.jpg
HTTP/1.1 301 Moved Permanently
Location: https://static.example.com/img/au/images/gifts/2012/rectangle-75-58/christmas-promo-tile-alyce.jpg