Created
December 14, 2012 08:09
-
-
Save chlab/4283560 to your computer and use it in GitHub Desktop.
Manually parse raw HTTP data with PHP
More information: http://www.chlab.ch/blog/archives/php/manually-parse-raw-http-data-php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Parse raw HTTP request data | |
* | |
* Pass in $a_data as an array. This is done by reference to avoid copying | |
* the data around too much. | |
* | |
* Any files found in the request will be added by their field name to the | |
* $data['files'] array. | |
* | |
* @param array Empty array to fill with data | |
* @return array Associative array of request data | |
*/ | |
function parse_raw_http_request(array &$a_data) | |
{ | |
// read incoming data | |
$input = file_get_contents('php://input'); | |
// grab multipart boundary from content type header | |
preg_match('/boundary=(.*)$/', $_SERVER['CONTENT_TYPE'], $matches); | |
// content type is probably regular form-encoded | |
if (!count($matches)) | |
{ | |
// we expect regular puts to containt a query string containing data | |
parse_str(urldecode($input), $a_data); | |
return $a_data; | |
} | |
$boundary = $matches[1]; | |
// split content by boundary and get rid of last -- element | |
$a_blocks = preg_split("/-+$boundary/", $input); | |
array_pop($a_blocks); | |
// loop data blocks | |
foreach ($a_blocks as $id => $block) | |
{ | |
if (empty($block)) | |
continue; | |
// you'll have to var_dump $block to understand this and maybe replace \n or \r with a visibile char | |
// parse uploaded files | |
if (strpos($block, 'application/octet-stream') !== FALSE) | |
{ | |
// match "name", then everything after "stream" (optional) except for prepending newlines | |
preg_match("/name=\"([^\"]*)\".*stream[\n|\r]+([^\n\r].*)?$/s", $block, $matches); | |
$a_data['files'][$matches[1]] = $matches[2]; | |
} | |
// parse all other fields | |
else | |
{ | |
// match "name" and optional value in between newline sequences | |
preg_match('/name=\"([^\"]*)\"[\n|\r]+([^\n\r].*)?\r$/s', $block, $matches); | |
$a_data[$matches[1]] = $matches[2]; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment