Search code examples
phpproxyhttp-headersgeoserver

PHP GeoServer Proxy Shape/Zip Request Returns Text


The Problem

Our GeoServer access is being proxied by a PHP script that handles the authorization/authentication. This works fine for WMS/WFS requests within an OpenLayers map, but not so much when trying to download a zipped-up shapefile the same way: the response ALWAYS returns the request as text.

I know that my URL is correct, because when I take the prepped GeoServer URL and enter credentials manually, I get the desired "Save As" popup:

FF Save Dialog

When running it through the proxy, however, I get no dialog and a bunch of garbage:

enter image description here

The Solution Attempts

Most suggestions I've found point to:

The Code

URL Prep

Not sure if it matters, but here is how I am preparing the URL to send to GS (and that URL works fine sans proxy, manual credentials):

// Encode geoserver credentials
$auth = base64_encode('username:password');

// Base URL and parameters
$url = 'https://example.com/mygeoserverpath/wfs?';
$query = '';

// Extract arguments
$orig_proxy_url = $_SERVER['REQUEST_URI'];
$orig_query = parse_url($orig_proxy_url, PHP_URL_QUERY);
parse_str($orig_query, $orig_args);

// Loop over arguments, append to base url
foreach ($orig_args as $key => $value) {
    if ($key === 'cql_filter') {
        $value = rawurlencode($value);
    }
    $query = $query . '&' . $key . '=' . $value;
}

$url = $url . $query;

Using stream_context_create with Other Stuff

$opts = array(
    'http' => array (
        'method' => "GET",
        'header' => "Authorization: Basic $auth"
        . "Content-Description: File Transfer\r\n"
        . "Content-Type: application/zip\r\n"
        . "Content-disposition: attachment; filename=testing.zip\r\n"
    ));
$ctx = stream_context_create($opts);

...in conjunction with some other attempts:

// file_get_contents returns text
$output = file_get_contents($url,false,$ctx);

// readfile returns text
readfile($url,false,$ctx);    

// fopen/passthru returns text
$fp = fopen($url,'r',0,$ctx);
fpassthru($fp);
exit;

Setting Headers Directly

I could get the Save dialog to appear this way, but it always was an empty zip.

header("Content-Description: File Transfer");
header("Content-Type: application/zip");
header("Content-disposition: attachment; filename=testing.zip");
header("Authorization: Basic $auth");

cURL

Not much to comment on here as I've been saving it as a very last resort.

Now What?

It shouldn't be this difficult considering GS does 99% of the work creating the zipped-up shapefile, but I'm running out of things to try. Any suggestions would be appreciated!


Solution

  • Sounded like this worked:

    $opts = array(
        'http' => array (
            'method' => "GET",
            'header' => "Authorization: Basic $auth"
    ));
    
    header("Content-Disposition: attachment; filename=testing.zip");
    $ctx = stream_context_create($opts);
    $fp = fopen($url,'r',0,$ctx);
    fpassthru($fp);