Skip to content
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

Add the ability to define a custom request header size if you need bigger headers #217

Conversation

christoph-kluge
Copy link
Contributor

This PR is a follow up of the discussion in #214. This allows us to configure the server with a max_header_size and pass it down to the RequestHeaderParser.

Question which I asked my self during implementation:

  • Do we want to fallback silently on invalid parameter usage?
  • Do we want to fail early on invalid parameter usage (i.e. fail on boot before the first request arrives)

@jsor
Copy link
Member

jsor commented Sep 8, 2017

  • Do we want to fallback silently on invalid parameter usage?
  • Do we want to fail early on invalid parameter usage (i.e. fail on boot before the first request arrives)

I'd say, fail early in the Server constructor.

{
$this->localSocketUri = $localSocketUri;
$this->remoteSocketUri = $remoteSocketUri;
$this->bufferMaxSize = is_integer($bufferMaxSize) ? $bufferMaxSize : 4096;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should error out if it's not an integer. Just set the default value right in the parameter default.


private $localSocketUri;
private $remoteSocketUri;

public function __construct($localSocketUri = null, $remoteSocketUri = null)
public function __construct($localSocketUri = null, $remoteSocketUri = null, $bufferMaxSize = null)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO it should be called $maxHeaderSize or $maxSize, the buffer might be larger than the headers are if there's a lot of data incoming at the same time.

$this->socket->emit('connection', array($this->connection));

$data = "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\nX-DATA: ";
$data .= str_repeat('A', 4097 - strlen($data)) . "\r\n\r\n";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why 4097 here? I'd expect $maxSize - strlen($data) there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was expecting that the default value is not throwing the overflow anymore. Your example makes more sense. I will adopt and check the other overflow tests to simply rely on those 3 test-cases:

  • check the default overflow $defaultValue + 1
  • check a custom header-size-value fits $maxSize - strlen($data)
  • check a custom header-size will overflow $maxSize + 1 - strlen($data)

@jsor
Copy link
Member

jsor commented Sep 8, 2017

Could fix the indention to 4 spaces to be consistent with the rest, for example here, here and in the new test methods?

@jsor
Copy link
Member

jsor commented Sep 8, 2017

There's a conflict with master now. Can you resolve it?

@christoph-kluge christoph-kluge force-pushed the custom-request-header-size branch from 29b693b to 3296b7e Compare September 8, 2017 22:04
@christoph-kluge
Copy link
Contributor Author

Just recognized it and pushed a new rebased version :)

Copy link
Member

@jsor jsor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@WyriHaximus WyriHaximus added this to the v0.8.0 milestone Sep 9, 2017
@WyriHaximus
Copy link
Member

@christoph-kluge could you fix the conflicts with README.md?

@christoph-kluge
Copy link
Contributor Author

@WyriHaximus done :)

@WyriHaximus
Copy link
Member

@christoph-kluge great! I'll give @clue a nudge 😎

Copy link
Member

@clue clue left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@christoph-kluge Thanks for filing this high quality PR along with tests and documentation, much appreciated! 👍 I think you're addressing a very relevant issue here and I'd argue that the current default is too small anyway.

Functionally the changes LGTM, however I'll still have to vote against this for now. Let me explain:

Given the current abstractions, I think it makes perfect sense to add this as a property to the RequestHeaderParser as per this PR 👍

Unfortunately however, this class is currently hard-coded into the Server instance. To address this, this PR currently adds another indirection and introduces the concept of "options". I understand why this is done and see this as a possible solution, but I'd like to point out this violates DRY, SRP and SSOT, plus I don't see how this would evolve for future parameters ("options"). I agree that this would properly make perfect sense in a higher-level abstraction, but this library is currently quite low-level.

As an alternative, I would suggest optionally injecting the RequestHeaderParser into the Server so that only this class is responsible for holding this parameter. This will involve a slightly bigger refactoring because this class is currently stateful (this is something I've already had to start looking into on for #216).

Given that I've started working on refactoring this for #216, I would suggest completing that task first and then looking into this PR again. If you're okay with this, I may also look into cherry-picking the relevant changes once this is ready. What do you think?

Either way, thanks for filing this PR and sparking this discussion, keep it coming! 👏

@christoph-kluge
Copy link
Contributor Author

@clue thanks for adding your feedback and feel free to cherry pick any changes :)

If you like I might also file another PR to support an HttpParserInterface as second parameter for the Server w/o BC breaks and then adopt this PR in order to get the option in place.

interface ReactHttpParserInterface {
  /** return a clean new instance */
  public function withConnection(Connection $conn) : self;
  public function feed($data);
}

@christoph-kluge
Copy link
Contributor Author

@clue ping :) After looking up the left overs for the 0.8 milestone I found out that #40 might be co-related to this topic.

Also It's a quite an interesting area of the server as I'm also working on a "Keepalive" PR which is related to the RequestHeaderParser.

@clue
Copy link
Member

clue commented Oct 13, 2017

@christoph-kluge Thanks for your friendly reminder :-) We are currently focusing our efforts on stabilizing a few things first and I assure you I will get back to this as soon as time permits 👍 This feature is definitely planned to be part of the upcoming v0.8.0 release :shipit:

@christoph-kluge
Copy link
Contributor Author

@clue thanks for you feedback! If you have more ideas/backgrounds according to that issue then I would be happy to hear. Otherwise I will try to tackle this issue again during the weekend.

@christoph-kluge christoph-kluge force-pushed the custom-request-header-size branch from 559ee5b to 760752e Compare October 14, 2017 21:37
@kelunik
Copy link

kelunik commented Oct 15, 2017

@clue: What's the next versions minimum requirement? Because I think there was a commit to the event loop repo that also requires 5.4.

@clue
Copy link
Member

clue commented Oct 15, 2017

@kelunik There are no plans to change the minimum required version for this component as per the roadmap (#120).

@kelunik
Copy link

kelunik commented Oct 15, 2017

@clue Ok, commented on reactphp/event-loop@8997565 then. :-)

@christoph-kluge
Copy link
Contributor Author

Hi @clue, I added two smaller PRs (#241 and #242) in order to discuss in separate and get stuff merged earlier. I tried to take care of #40 and #217 in order to get more close to the 0.8 milestone.

Another thing:

This will involve a slightly bigger refactoring because this class [RequestHeaderParser] is currently stateful.

I left this one open for now and would tackle this in another PR since I'm still working on the public API for that..

If I didn't missed anything I would be up for closing this PR in favor of the other created PRs.

@WyriHaximus
Copy link
Member

@christoph-kluge @clue what is the status for this PR and can conflicts be fixed?

@christoph-kluge
Copy link
Contributor Author

I will close this in favor of #241 and #242. Thanks for reminding @WyriHaximus 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants