Search code examples
phpwordpressapachehttp-headersfile-get-contents

"HTTP/1.1 406 Not Acceptable" using "file_get_contents()" - Same domain


I'm using file_get_contents() to get a PHP file which I use as a template to create a PDF.

I need to pass some POST values to it, in order to fill the template and get the produced HTML back into a PHP variable. Then use it with mPDF.

This works perfectly on MY server (a VPS using PHP 5.6.24)...
Now, at the point where I'm installing the fully tested script on the client's live site (PHP 5.6.29),
I get this error:

PHP Warning: file_get_contents(http://www.example.com/wp-content/calculator/pdf_page1.php): failed to open stream: HTTP request failed! HTTP/1.1 406 Not Acceptable

So I guess this can be fixed in php.ini or some config file.
I can ask (I WANT TO!!) my client to contact his host to fix it...

But since I know that hosters are generally not inclined to change server configs...
I would like to know exactly what to change in which file to allow the code below to work.

For my personnal knowledge... Obviously.
But also to make it look "easy" for the hoster (and my client!!) to change it efficiently. ;)

I'm pretty sure this is just one PHP config param with a strange name...

<?php
$baseAddr = "http://www.example.com/wp-content/calculator/";

// ====================================================
// CLEAR OLD PDFs

$now = date("U");
$delayToKeepPDFs = 60*60*2; // 2 hours in seconds.

if ($handle = opendir('.')) {

    while (false !== ($entry = readdir($handle))) {

      if(substr($entry,-4)==".pdf"){
        $fileTime = filemtime($entry);        // Returns unix timestamp;
        if($fileTime+$delayToKeepPDFs<$now){
          unlink($entry);                     // Delete file
        }
      }
    }
    closedir($handle);
}
// ====================================================



// Random file number
$random = rand(100, 999);

$page1 = $_POST['page1'];   // Here are the values, sent via ajax, to fill the template.
$page2 = $_POST['page2'];

// Instantiate mpdf
require_once __DIR__ . '/vendor/autoload.php';
$mpdf = new mPDF( __DIR__ . '/vendor/mpdf/mpdf/tmp');


// GET PDF templates from external PHP
// ==============================================================
// REF: http://stackoverflow.com/a/2445332/2159528
// ==============================================================
$postdata = http_build_query(
  array(
    "page1" => $page1,
    "page2" => $page2
  )
);
$opts = array('http' =>
  array(
    'method'  => 'POST',
    'header'  => 'Content-type: application/x-www-form-urlencoded',
    'content' => $postdata
  )
);
$context  = stream_context_create($opts);
// ==============================================================


$STYLE .=  file_get_contents("smolov.css", false, $context);
$PAGE_1 .=  file_get_contents($baseAddr . "pdf_page1.php", false, $context);
$PAGE_2 .=  file_get_contents($baseAddr . "pdf_page2.php", false, $context);

$mpdf->AddPage('P');
// Write style.
$mpdf->WriteHTML($STYLE,1);

// Write page 1.
$mpdf->WriteHTML($PAGE_1,2);


$mpdf->AddPage('P');
// Write page 1.
$mpdf->WriteHTML($PAGE_2,2);


// Create the pdf on server
$file =  "training-" . $random . ".pdf";

$mpdf->Output(__DIR__ . "/" . $file,"F");

// Send filename to ajax success.
echo $file;
?>

Just to avoid the "What have you tried so far?" comments:
I searched those keywords in many combinaisons, but didn't found the setting that would need to be changed:

  • php
  • php.ini
  • request
  • header
  • content-type
  • application
  • HTTP
  • file_get_contents
  • HTTP/1.1 406 Not Acceptable

Solution

  • Maaaaany thanks to @Rasclatt for the priceless help! Here is a working cURL code, as an alternative to file_get_contents() (I do not quite understand it yet... But proven functional!):

    function curl_get_contents($url, $fields, $fields_url_enc){
        # Start curl
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_HEADER, 0);
        # Required to get data back
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        # Notes that request is sending a POST
        curl_setopt($ch,CURLOPT_POST, count($fields));
        # Send the post data
        curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_url_enc);
        # Send a fake user agent to simulate a browser hit
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11) AppleWebKit/601.1.56 (KHTML, like Gecko) Version/9.0 Safari/601.1.56');
        # Set the endpoint
        curl_setopt($ch, CURLOPT_URL, $url);
        # Execute the call and get the data back from the hit
        $data = curl_exec($ch);
        # Close the connection
        curl_close($ch);
        # Send back data
        return $data;
    }
    # Store post data
    $fields = array(
      'page1' => $_POST['page1'],
      'page2' => $_POST['page2']
    );
    # Create query string as noted in the curl manual
    $fields_url_enc = http_build_query($fields);
    # Request to page 1, sending post data
    $PAGE_1 .=  curl_get_contents($baseAddr . "pdf_page1.php", $fields, $fields_url_enc);
    # Request to page 2, sending post data
    $PAGE_2 .=  curl_get_contents($baseAddr . "pdf_page2.php", $fields, $fields_url_enc);