-
-
Notifications
You must be signed in to change notification settings - Fork 167
Streaming body parser: Form Urlencoded #202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
97ade3d
09857c7
2d18657
920e6f7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| <?php | ||
|
|
||
| namespace React\Http\StreamingBodyParser; | ||
|
|
||
| use Evenement\EventEmitter; | ||
| use Psr\Http\Message\RequestInterface; | ||
| use React\Http\HttpBodyStream; | ||
|
|
||
| final class FormUrlencodedParser extends EventEmitter | ||
| { | ||
| /** | ||
| * @var RequestInterface | ||
| */ | ||
| private $request; | ||
|
|
||
| /** | ||
| * @var HttpBodyStream | ||
| * | ||
| * @internal | ||
| */ | ||
| public $body; | ||
|
|
||
| /** | ||
| * @var string | ||
| * | ||
| * @internal | ||
| */ | ||
| public $buffer = ''; | ||
|
||
|
|
||
| /** | ||
| * @param RequestInterface $request | ||
| */ | ||
| public function __construct(RequestInterface $request) | ||
| { | ||
| $this->request = $request; | ||
| $this->body = $this->request->getBody(); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe check here if
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. WDYT? Since the class isn't internal, it isn't guaranteed that
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm thinking a check on if body is a |
||
| $this->body->on('data', array($this, 'onData')); | ||
| $that = $this; | ||
| $this->body->on('end', function () use ($that) { | ||
| $that->body->removeAllListeners(); | ||
| $that->parse($that->buffer); | ||
| $that->emit('end'); | ||
| }); | ||
| } | ||
|
|
||
| /** | ||
| * @internal | ||
| */ | ||
| public function onData($data) | ||
| { | ||
| $this->buffer .= $data; | ||
|
|
||
| $pos = strrpos($this->buffer, '&'); | ||
| if ($pos === false) { | ||
| return; | ||
| } | ||
|
|
||
| $buffer = substr($this->buffer, 0, $pos); | ||
| $this->buffer = substr($this->buffer, $pos + 1); | ||
|
|
||
| $this->parse($buffer); | ||
| } | ||
|
|
||
| /** | ||
| * @internal | ||
| */ | ||
| public function parse($buffer) | ||
|
||
| { | ||
| foreach (explode('&', $buffer) as $chunk) { | ||
| $this->emit( | ||
| 'post', | ||
| explode('=', rawurldecode($chunk)) | ||
|
||
| ); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| <?php | ||
|
|
||
| namespace React\Tests\Http\StreamingBodyParser; | ||
|
|
||
| use React\Http\HttpBodyStream; | ||
| use React\Http\StreamingBodyParser\FormUrlencodedParser; | ||
| use React\Stream\ThroughStream; | ||
| use React\Tests\Http\TestCase; | ||
| use RingCentral\Psr7\Request; | ||
|
|
||
| class FormUrlencodedParserTest extends TestCase | ||
| { | ||
| public function testParse() | ||
| { | ||
| $post = array(); | ||
| $stream = new ThroughStream(); | ||
| $request = new Request('POST', 'http://example.com/', array(), new HttpBodyStream($stream, 0)); | ||
| $parser = new FormUrlencodedParser($request); | ||
| $parser->on('post', function ($key, $value) use (&$post) { | ||
| $post[] = array($key, $value); | ||
| }); | ||
| $stream->emit('data', array('user=single&user2=second&us')); | ||
| $this->assertEquals( | ||
| array( | ||
| array('user', 'single'), | ||
| array('user2', 'second'), | ||
| ), | ||
| $post | ||
| ); | ||
| $stream->emit('data', array('ers%5B%5D=first%20in%20array&users%5B%5D=second%20in%20array')); | ||
| $this->assertEquals( | ||
| array( | ||
| array('user', 'single'), | ||
| array('user2', 'second'), | ||
| array('users[]', 'first in array'), | ||
| ), | ||
| $post | ||
| ); | ||
| $stream->end(); | ||
| $this->assertEquals( | ||
| array( | ||
| array('user', 'single'), | ||
| array('user2', 'second'), | ||
| array('users[]', 'first in array'), | ||
| array('users[]', 'second in array'), | ||
| ), | ||
| $post | ||
| ); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
private?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope because of PHP 5.3 here https://github.com/WyriHaximus/http/blob/97ade3db7e4b1fe079cff9a6643e61975e179b59/src/StreamingBodyParser/FormUrlencodedParser.php#L39-L43 or I could make a public
onEndmethod, mark it private and make everything that shouldn't bepublicprivate.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you're correct. My bad 🤗
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll look into refactoring it a bit anyway 👍