Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions DependencyInjection/HttpBatchConfiguration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare( strict_types=1 );


namespace Ideasoft\HttpBatchBundle\DependencyInjection;


use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

class HttpBatchConfiguration implements ConfigurationInterface {


public function getConfigTreeBuilder() : TreeBuilder {

$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root( 'http_batch' );

// @formatter:off
$rootNode
->children()
->integerNode( 'max_calls_in_a_request' )
->info( 'Limits the amount of calls in a single batch request' )
->defaultValue( 100 )
->min( 1 )
->end()
->end();
// @formatter:on

return $treeBuilder;

} // getConfigTreeBuilder


} // HttpBatchConfiguration
31 changes: 31 additions & 0 deletions DependencyInjection/HttpBatchExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Ideasoft\HttpBatchBundle\DependencyInjection;

use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

class HttpBatchExtension extends Extension {


public function load( array $configs, ContainerBuilder $container ) {

$loader = new YamlFileLoader(
$container,
new FileLocator( __DIR__ . '/../Resources/config' )
);

$loader->load( 'services.yml' );

$configuration = new HttpBatchConfiguration();

$config = $this->processConfiguration( $configuration, $configs );

$container->getDefinition( 'http_batch.handler' )
->replaceArgument( '$max_calls', $config[ 'max_calls_in_a_request' ] );

} // load

} // HttpBatchExtension
309 changes: 309 additions & 0 deletions HTTP/ContentParser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,309 @@
<?php


namespace Ideasoft\HttpBatchBundle\HTTP;


/**
* Class ContentParser
* Handles a input stream with http messages
*
* @see https://gist.github.com/jas-/5c3fdc26fedd11cb9fb5#file-class-stream-php
* @see https://stackoverflow.com/questions/5483851/manually-parse-raw-multipart-form-data-data-with-php
*
* @package Ideasoft\HttpBatchBundle\HTTP
*/
class ContentParser
{


/**
* @abstract Raw input stream
*/
protected $input;

/**
* @param string $content_type
* @param string $content
* @param array $data stream
*
* @throws \HttpHeaderException
*/
private function __construct( $content_type, $content, array &$data )
{

$this->input = $content;

if ( strpos( $content_type, 'boundary=' ) !== false ) {
$boundary = $this->boundary( $content_type );
}

$blocks = $this->split( $boundary );

$data = $this->blocks( $blocks );

return $data;

} // __construct

/**
* @param string $content_type
* @param string $content
*
* @return array
* @throws \HttpHeaderException
*/
public static function parse( $content_type, $content )
{

$params = [];

if ( strpos( $content_type, 'application/x-www-form-urlencoded' ) !== false ) {
parse_str( $content, $params );
}
else {
new self( $content_type, $content, $params );
if ( array_key_exists( 'post', $params ) ) {
$params = array_pop($params);
}
else {
$params = [];
} // if else
} // if else

return $params;
}

/**
* @param string $contentType
*
* @return array
* @throws \HttpHeaderException
*/
private function boundary( $contentType )
{

if ( !$contentType ) {
throw new \HttpHeaderException( "Content-type can not be found in header" );
} // if
$contentTypeData = explode( ";", $contentType );

foreach ( $contentTypeData as $data ) {
$contentTypePart = explode( "=", $data );
if ( sizeof( $contentTypePart ) == 2 && trim( $contentTypePart[ 0 ] ) == "boundary" ) {
$boundary = trim( $contentTypePart[ 1 ] );
break;
} // if
} // foreach

if ( isset( $boundary ) ) {
return $boundary;
}
else {
throw new \HttpHeaderException( "Boundary can not be found." );
} // if

} // boundary

/**
* @param $boundary string
*
* @return array
*/
private function split( $boundary )
{

$result = preg_split( "/-+$boundary/", $this->input );
array_pop( $result );

return $result;

} // split

/**
* @param $array array
*
* @return array
*/
private function blocks( $array )
{

$results = [
'post' => [],
// 'file' => [],
];

foreach ( $array as $key => $value ) {
if ( empty( $value ) ) {
continue;
} // if

$block = $this->decide( $value );

if ( count( $block[ 'post' ] ) > 0 ) {
array_push( $results[ 'post' ], $block[ 'post' ] );
} // if

// if ( count( $block[ 'file' ] ) > 0 ) {
// array_push( $results[ 'file' ], $block[ 'file' ] );
// } // if
} // foreach

return $this->merge( $results );

} // blocks

/**
* @param $string string
*
* @return array
*/
private function decide( $string )
{

// if ( strpos( $string, 'application/octet-stream' ) !== false ) {
// return [
// 'post' => $this->file( $string ),
// 'file' => [],
// ];
// } // if

// if ( strpos( $string, 'filename' ) !== false ) {
// return [
// 'post' => [],
// 'file' => $this->file_stream( $string ),
// ];
// } // if

return [
'post' => $this->post( $string ),
// 'file' => [],
];

} // decide

/**
* @param $string
*
* @return array
*/
// private function file( $string ) {
//
// preg_match( '/name=\"([^\"]*)\".*stream[\n|\r]+([^\n\r].*)?$/s', $string, $match );
//
// return [
// $match[ 1 ] => ( ! empty( $match[ 2 ] ) ? $match[ 2 ] : '' ),
// ];
//
// } // file

/**
* @param $string
*
* @return array
*/
// private function file_stream( $string ) {
//
// $data = [];
//
// preg_match( '/name=\"([^\"]*)\"; filename=\"([^\"]*)\"[\n|\r]+([^\n\r].*)?\r$/s', $string, $match );
// preg_match( '/Content-Type: (.*)?/', $match[ 3 ], $mime );
//
// $image = preg_replace( '/Content-Type: (.*)[^\n\r]/', '', $match[ 3 ] );
//
// $path = sys_get_temp_dir() . '/php' . substr( sha1( rand() ), 0, 6 );
//
// $err = file_put_contents( $path, ltrim( $image ) );
//
// if ( preg_match( '/^(.*)\[\]$/i', $match[ 1 ], $tmp ) ) {
// $index = $tmp[ 1 ];
// } else {
// $index = $match[ 1 ];
// } // if
//
// $data[ $index ][ 'name' ][] = $match[ 2 ];
// $data[ $index ][ 'type' ][] = $mime[ 1 ];
// $data[ $index ][ 'tmp_name' ][] = $path;
// $data[ $index ][ 'error' ][] = ( $err === false ) ? $err : 0;
// $data[ $index ][ 'size' ][] = filesize( $path );
//
// return $data;
//
// } // file_stream

/**
* @param $string
*
* @return array
*/
private function post( $string )
{

$data = [];

preg_match( '/name=\"([^\"]*)\"(?>\r{2}|\n{2}|(?>\r\n){2})(.*)$/s', trim( $string ), $match );

if ( preg_match( '/^(.*)\[\]$/i', $match[ 1 ], $tmp ) ) {
$data[ $tmp[ 1 ] ][] = ( !empty( $match[ 2 ] ) ? $match[ 2 ] : '' );
}
else {
$data[ $match[ 1 ] ] = ( !empty( $match[ 2 ] ) ? $match[ 2 ] : '' );
} // if

return $data;

} // post

/**
* @param $array array
*
* Ugly ugly ugly
*
* @return array
*/
private function merge( $array )
{

$results = [
'post' => [],
// 'file' => [],
];

if ( count( $array[ 'post' ] ) > 0 ) {
foreach ( $array[ 'post' ] as $key => $value ) {
foreach ( $value as $k => $v ) {
if ( is_array( $v ) ) {
foreach ( $v as $kk => $vv ) {
$results[ 'post' ][ $k ][] = $vv;
} // foreach
}
else {
$results[ 'post' ][ $k ] = $v;
} // if
} // foeach
} // foeach
} // if

// if ( count( $array[ 'file' ] ) > 0 ) {
// foreach ( $array[ 'file' ] as $key => $value ) {
// foreach ( $value as $k => $v ) {
// if ( is_array( $v ) ) {
// foreach ( $v as $kk => $vv ) {
// if ( is_array( $vv ) && ( count( $vv ) === 1 ) ) {
// $results[ 'file' ][ $k ][ $kk ] = $vv[ 0 ];
// } else {
// $results[ 'file' ][ $k ][ $kk ][] = $vv[ 0 ];
// } // if
// } // foreach
// } else {
// $results[ 'file' ][ $k ][ $key ] = $v;
// } // if
// } // foreach
// } // foreach
// } // if

return $results;

} // merge

} // ContentParser
Loading