Skip to content

Add Content-type plugin to set content-type header automatically #85

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

Merged
merged 9 commits into from
Aug 5, 2017

Conversation

kpn13
Copy link
Contributor

@kpn13 kpn13 commented Jul 21, 2017

Q A
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Related tickets mentioned in #82
Documentation php-http/documentation#204
License MIT

What's in this PR?

Add a new plugin which allow to detect JSON and XML content in body request and automatically set the right content-type header.

Why?

Set the content-type header is often unpleasing and detect whether the content is JSON or XML is relatively simple so it could save time.

Example Usage

$contentTypePlugin = new ContentTypePlugin();

$pluginClient = new PluginClient(
    HttpClientDiscovery::find(),
    [$contentTypePlugin]
);

Checklist

  • Updated CHANGELOG.md to describe BC breaks / deprecations | new feature | bugfix
  • [x ] Documentation pull request created (if not simply a bugfix)

function it_adds_xml_content_type_header(RequestInterface $request)
{
$request->hasHeader('Content-Type')->shouldBeCalled()->willReturn(false);
$request->getBody()->shouldBeCalled()->willReturn('<foo>bar</foo>');
Copy link
Member

Choose a reason for hiding this comment

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

Can you use a real stream implementation instead of a string ?

I think this test case will fail with a stream implementation as there is no rewind

private function isJson($stream)
{
json_decode($stream);

Copy link
Member

Choose a reason for hiding this comment

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

We should rewind the stream here

private function isXml($stream)
{
libxml_use_internal_errors(true);

Copy link
Member

Choose a reason for hiding this comment

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

We should rewind the stream here

* {@inheritdoc}
*/
public function handleRequest(RequestInterface $request, callable $next, callable $first)
{
Copy link
Member

Choose a reason for hiding this comment

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

We should avoid content type detection if stream is not rewindable

*
* @author Karim Pinchon <[email protected]>
*/
final class ContentTypePlugin implements Plugin
Copy link
Member

Choose a reason for hiding this comment

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

May be nice to add some options to this plugin to avoid detection on too large stream, or stream with a null size

$request = $request->withHeader('Content-Type', 'application/xml');

return $next($request);
}
Copy link
Member

Choose a reason for hiding this comment

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

Some content type that can be added to check (but not necessarly in this PR) :

  • Image types by using a library image (should be optional IMO)
  • Binary type by checking if there is a null character (\0) in the stream (that's how git does to detect binary vs text)
  • Text type (inverse of the binary type, imo the default content type we want to add to the stream)

*/
public function handleRequest(RequestInterface $request, callable $next, callable $first)
{
if (!$request->hasHeader('Content-Type')) {
Copy link
Member

Choose a reason for hiding this comment

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

We should early return here if the body size of the stream is equal to 0

*/
private function isXml($stream)
{
libxml_use_internal_errors(true);
Copy link
Member

Choose a reason for hiding this comment

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

Should we reset to the original value?

return $next($request);
}

if ($this->skipDetection && $streamSize >= $this->sizeLimit) {
Copy link
Member

Choose a reason for hiding this comment

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

What if $streamSize == null?

@kpn13
Copy link
Contributor Author

kpn13 commented Jul 24, 2017 via email

return $next($request);
}

if (0 == $streamSize) {
Copy link
Member

Choose a reason for hiding this comment

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

We should use strict comparison and then do an extra one for checking if null.

Copy link
Member

Choose a reason for hiding this comment

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

Not here, as we skip every stream that has a size equal to null, don't we want to skip only thoses with skipDetection and null size ?

I mean if stream is rewindable, but we cannot determine it's size but still want to auto detect the content type why skipping this ?

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 agree, I made it too quickly.

Copy link
Member

@joelwurtz joelwurtz left a comment

Choose a reason for hiding this comment

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

👍 LGTM

Last review @Nyholm ?

Copy link
Member

@Nyholm Nyholm left a comment

Choose a reason for hiding this comment

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

Awesome. Thank you

@Nyholm Nyholm merged commit 600ea9a into php-http:master Aug 5, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants