Skip to content
Permalink
Browse files

Fixed content-type bug

  • Loading branch information...
stelin committed May 24, 2019
1 parent 7c2318d commit 22cf706cef9dba5aca2cb7e1185bda545f292ccd
@@ -163,7 +163,7 @@ public function send(): void
{
// Is send file
if ($this->filePath) {
$this->coResponse->header('Content-Type', $this->fileType);
$this->coResponse->header(ContentType::KEY, $this->fileType);
$this->coResponse->sendfile($this->filePath);
return;
}
@@ -206,6 +206,10 @@ public function quickSend(Response $response = null): void
*/
private function prepare(): Response
{
if(empty($this->format)){
return $this;
}
$formatter = $this->formatters[$this->format] ?? null;
if ($formatter && $formatter instanceof ResponseFormatterInterface) {
@@ -305,12 +309,12 @@ public function getAttributes(): array
* This method obviates the need for a hasAttribute() method, as it allows
* specifying a default value to return if the attribute is not found.
*
* @see getAttributes()
*
* @param string $name The attribute name.
* @param mixed $default Default value to return if the attribute does not exist.
*
* @return mixed
* @see getAttributes()
*
*/
public function getAttribute($name, $default = null)
{
@@ -325,12 +329,12 @@ public function getAttribute($name, $default = null)
* immutability of the message, and MUST return an instance that has the
* updated attribute.
*
* @see getAttributes()
*
* @param string $name The attribute name.
* @param mixed $value The value of the attribute.
*
* @return static|self
* @see getAttributes()
*
*/
public function withAttribute($name, $value)
{
@@ -401,9 +405,11 @@ public function withStatus($code, $reasonPhrase = '')
*/
public function withContentType(string $type, string $charset = ''): self
{
$value = $type . ($charset ? ", charset={$charset}" : '');
if (!empty($charset)) {
$this->charset = $charset;
}
return $this->withHeader('Content-Type', $value);
return $this->withHeader(ContentType::KEY, $type);
}
/**
@@ -6,6 +6,7 @@
use function current;
use function strpos;
use Swoft\Bean\Annotation\Mapping\Bean;
use Swoft\Http\Message\ContentType;
use Swoft\Http\Message\Contract\ResponseFormatterInterface;
use Swoft\Http\Message\Response;
@@ -38,27 +39,56 @@ class AcceptResponseFormatter implements ResponseFormatterInterface
*/
public function format(Response $response): Response
{
$format = '';
$request = context()->getRequest();
$accepts = $request->getHeader('accept');
$responeContentType = $response->getHeaderLine(ContentType::KEY);
// Format by user response content type
if (!empty($responeContentType)) {
$format = $this->getResponseFormat($responeContentType);
if (!empty($format)) {
$response->setFormat($format);
} else {
$response->setFormat('');
}
return $response;
}
// Fix empty bug
if(empty($accepts)){
if (empty($accepts)) {
return $response;
}
// Accept type to format, default is json
$acceptType = current($accepts);
foreach ($this->formats as $contentType => $formatType) {
if (strpos($acceptType, $contentType) === 0) {
$format = $formatType;
break;
}
}
$format = $this->getResponseFormat($acceptType);
if (!empty($format)) {
$response->setFormat($format);
}
return $response;
}
/**
* Match format from all formats
*
* @param string $responseContentType
*
* @return string
*/
private function getResponseFormat(string $responseContentType): string
{
$format = '';
foreach ($this->formats as $contentType => $formatType) {
if (strpos($responseContentType, $contentType) === 0) {
$format = $formatType;
break;
}
}
return $format;
}
}
@@ -0,0 +1,61 @@
<?php declare(strict_types=1);
namespace SwoftTest\Http\Server\Testing\Controller;
use ReflectionException;
use Swoft\Bean\Exception\ContainerException;
use Swoft\Http\Message\ContentType;
use Swoft\Http\Message\Response;
use Swoft\Http\Server\Annotation\Mapping\Controller;
use Swoft\Http\Server\Annotation\Mapping\RequestMapping;
/**
* Class ContentTypeController
*
* @since 2.0
*
* @Controller(prefix="ct")
*/
class ContentTypeController
{
/**
* @RequestMapping()
*
* @param Response $response
*
* @return Response
* @throws ReflectionException
* @throws ContainerException
*/
public function userCt(Response $response): Response
{
return $response->withContentType('image/jpeg')->withContent('imag data content');
}
/**
* @RequestMapping()
*
* @param Response $response
*
* @return Response
* @throws ReflectionException
* @throws ContainerException
*/
public function userCt2(Response $response): Response
{
return $response->withContentType(ContentType::XML)->withContent('xml data content');
}
/**
* @RequestMapping()
*
* @param Response $response
*
* @return array
*/
public function userCt3(Response $response): array
{
return ['key' => 'data'];
}
}
@@ -0,0 +1,64 @@
<?php declare(strict_types=1);
namespace SwoftTest\Http\Server\Unit;
use Swoft\Http\Message\ContentType;
/**
* Class ContentTypeTest
*
* @since 2.0
*/
class ContentTypeTest extends TestCase
{
public function testUserCt()
{
$headers = [
'accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
];
$response = $this->mockServer->request('POST', '/ct/userCt', [], $headers);
$response->assertEqualHeader(ContentType::KEY, 'image/jpeg');
$response->assertEqualContent('imag data content');
}
public function testUserCt2()
{
$headers = [
'accept' => ContentType::XML,
];
$response = $this->mockServer->request('POST', '/ct/userCt2', [], $headers);
$response->assertEqualHeader(ContentType::KEY, ContentType::XML);
$response->assertEqualContent('xml data content');
$headers = [
];
}
public function testUserCt3()
{
$headers = [
'accept' => ContentType::XML,
];
$response = $this->mockServer->request('POST', '/ct/userCt3', [], $headers);
$response->assertEqualHeader(ContentType::KEY, ContentType::XML);
$response->assertEqualContent("<xml><key><![CDATA[data]]></key></xml>");
$headers = [
];
$response = $this->mockServer->request('POST', '/ct/userCt3', [], $headers);
$response->assertEqualHeader(ContentType::KEY, ContentType::JSON);
$response->assertEqualJson(['key' => 'data']);
}
}

0 comments on commit 22cf706

Please sign in to comment.
You can’t perform that action at this time.