未正确接收cURL标头

Overview

I'm trying to send an XML file via cURL.

Everything is working except for the headers, which aren't being sent correctly.

Why are they not being received?


Code

test.php

$xml = file_get_contents("test.xml");

//These are the CUSTOM HEADERS being set in an array for later:
$data = array(
    'x-meta-feed-type: Latest',
    'x-meta-feed-parameters: feed params',
    'x-meta-default-filename: '.time().'.xml',
    'x-meta-game-id: f790722',
    'x-meta-competition-id: c420',
    'x-meta-season-id: 2014',
    'x-meta-gamesystem-id: SUD_CL',
    'x-meta-matchday: 7',
    'x-meta-away-team-id: t2578',
    'x-meta-home-team-id: t764',
    'x-meta-game-status: 11',
    'x-meta-language: en',
    'x-meta-production-server: local',
    'x-meta-production-server-timestamp: '.time(),
    'x-meta-production-server-module: 1',
    ' x-meta-mime-type: text/xml',
    'encoding: UTF-8'
);

//set URL
$url = 'http://www.example.com/receive.php';

// Get the curl session object
$session = curl_init($url);

// set url to post to
curl_setopt($session, CURLOPT_URL,$url);

// Tell curl to use HTTP POST;
curl_setopt($session, CURLOPT_POST, true);
curl_setopt($session, CURLOPT_HTTPHEADER, $data);

// Tell curl that this is the body of the POST
curl_setopt($session, CURLOPT_POSTFIELDS, $xml);

// Tell curl not to return headers, and return the response
curl_setopt($session, CURLOPT_HEADER, true);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
curl_setopt($session, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);

// allow redirects
curl_setopt($session, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($session);
if (curl_errno($session)) {
    print "Error: " . curl_error($session);
} else {
    // Show me the result 
    echo $response;
    curl_close($session);
}
curl_close($session);

receive.php

$headers = apache_request_headers();

$post_data = file_get_contents('php://input');

$posts = array (
    'feedType' => isset($headers['x-meta-feed-type']) ? $headers['x-meta-feed-type'] : '',
    'feedParameters' => isset($headers['x-meta-feed-parameters']) ? $headers['x-meta-feed-parameters'] : '',
    'defaultFilename' => isset($headers['x-meta-default-filename']) ? $headers['x-meta-default-filename'] : '',
    'deliveryType' => isset($headers['x-meta-game-id']) ? $headers['x-meta-game-id'] : '',
    'messageDigest' => md5($post_data),
    'competitionId' => isset($headers['x-meta-competition-id']) ? $headers['x-meta-competition-id'] : '',
    'seasonId' => isset($headers['x-meta-season-id']) ? $headers['x-meta-season-id'] : '',
    'gameId' => isset($headers['x-meta-game-id']) ? $headers['x-meta-game-id'] : '',
    'gameSystemId' => isset($headers['x-meta-gamesystem-id']) ? $headers['x-meta-gamesystem-id'] : '',
    'matchday' => isset($headers['x-meta-matchday']) ? $headers['x-meta-matchday'] : '',
    'awayTeamId' => isset($headers['x-meta-away-team-id'])?$headers['x-meta-away-team-id']:'',
    'homeTeamId' => isset($headers['x-meta-home-team-id']) ? $headers['x-meta-home-team-id'] : '',
    'gameStatus' => isset($headers['x-meta-game-status']) ? $headers['x-meta-game-status'] : '',
    'language' => isset($headers['x-meta-language']) ? $headers['x-meta-language'] : '',
    'productionServer' => isset($headers['x-meta-production-server']) ? $headers['x-meta-production-server'] : '',
    'productionServerTimeStamp' => isset($headers['x-meta-production-server-timestamp']) ? $headers['x-meta-production-server-timestamp'] : '',
    'productionServerModule' => isset($headers['x-meta-production-server-module']) ? $headers['x-meta-production-server-module'] : '',
    'mimeType' => 'text/xml',
    'encoding' => isset($headers['x-meta-encoding']) ? $headers['x-meta-encoding'] : '',
    'content' => $post_data
);

exit(print_r($posts));

Output

HTTP/1.1 100 Continue

HTTP/1.1 200 OK
Date: Mon, 05 Oct 2015 11:13:20 GMT
Server: Apache
X-Powered-By: PHP/5.4.45-0+deb7u1
Vary: User-Agent,Accept-Encoding
Transfer-Encoding: chunked
Content-Type: text/html

Array
(
    [feedType] => 
    [feedParameters] => 
    [defaultFilename] => 
    [deliveryType] => 
    [messageDigest] => 144ce144c73a12ea51a03ac1ef1256e5
    [competitionId] => 
    [seasonId] => 
    [gameId] => 
    [gameSystemId] => 
    [matchday] => 
    [awayTeamId] => 
    [homeTeamId] => 
    [gameStatus] => 
    [language] => 
    [productionServer] => 
    [productionServerTimeStamp] => 
    [productionServerModule] => 
    [mimeType] => text/xml
    [encoding] => 
    [content] => File Content
) 1

If I use var_dump on the $headers object (retrieved via apache_request_headers), I see that all the header tags have had their first letters capitalised:

HTTP/1.1 100 Continue

HTTP/1.1 200 OK
Date: Mon, 05 Oct 2015 11:30:20 GMT
Server: Apache
X-Powered-By: PHP/5.4.45-0+deb7u1
Vary: User-Agent,Accept-Encoding
Transfer-Encoding: chunked
Content-Type: text/html

array(24) {
  ["Connection"]=>
  string(5) "close"
  ["Expect"]=>
  string(12) "100-continue"
  ["Content-Type"]=>
  string(33) "application/x-www-form-urlencoded"
  ["Content-Length"]=>
  string(5) "90166"
  ["Encoding"]=>
  string(5) "UTF-8"
  ["X-Meta-Mime-Type"]=>
  string(8) "text/xml"
  ["X-Meta-Production-Server-Module"]=>
  string(1) "1"
  ["X-Meta-Production-Server-Timestamp"]=>
  string(10) "1444044620"
  ["X-Meta-Production-Server"]=>
  string(6) "server"
  ["X-Meta-Language"]=>
  string(2) "en"
  ["X-Meta-Game-Status"]=>
  string(2) "11"
  ["X-Meta-Home-Team-Id"]=>
  string(4) "t764"
  ["X-Meta-Away-Team-Id"]=>
  string(5) "t2578"
  ["X-Meta-Matchday"]=>
  string(1) "7"
  ["X-Meta-Gamesystem-Id"]=>
  string(6) "SUD_CL"
  ["X-Meta-Season-Id"]=>
  string(4) "2014"
  ["X-Meta-Competition-Id"]=>
  string(4) "c420"
  ["X-Meta-Game-Id"]=>
  string(7) "f790722"
  ["X-Meta-Default-Filename"]=>
  string(26) "opta-1444044620-bIb24r.xml"
  ["X-Meta-Feed-Parameters"]=>
  string(11) "feed params"
  ["X-Meta-Feed-Type"]=>
  string(6) "Latest"
  ["Accept"]=>
  string(3) "*/*"
  ["Host"]=>
  string(19) "example.com"
  ["User-Agent"]=>
  string(109) "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36"
}

While this is strange - and I'm curious as to why this happens, as the headers were not capitalised when sent - the solution is to simply change the receiving page to check for the capitalised custom headers as they are case-sensitive.

Add header Content-Type to application/xml or text/xml in header $data as you are sending xml data in post.

$data = array(
    'x-meta-feed-type: Latest',
    'x-meta-feed-parameters: feed params',
    'x-meta-default-filename: '.time().'.xml',
    'x-meta-game-id: f790722',
    'x-meta-competition-id: c420',
    'x-meta-season-id: 2014',
    'x-meta-gamesystem-id: SUD_CL',
    'x-meta-matchday: 7',
    'x-meta-away-team-id: t2578',
    'x-meta-home-team-id: t764',
    'x-meta-game-status: 11',
    'x-meta-language: en',
    'x-meta-production-server: local',
    'x-meta-production-server-timestamp: '.time(),
    'x-meta-production-server-module: 1',
    ' x-meta-mime-type: text/xml',
    'encoding: UTF-8',
    'Content-Type : application/xml'
);