Skip to content

Commit

Permalink
Squashed 'src/http-server/' changes from f54584ce..4b3176b2
Browse files Browse the repository at this point in the history
4b3176b2 Upstream travis ci config (#160)
42be799f 修复Json Validator会失效的BUG (#153)
d1db1cf1 修复执行php bin/swoft stop命令时master进程异常未退出的问题,以及停止失败后,pid文件被删除的问题 (#134)
649e67a4 Validator增加Json格式支持 (#122)

git-subtree-dir: src/http-server
git-subtree-split: 4b3176b2d43dba4a3f7db5ad754c017ab1d8d294
  • Loading branch information
huangzhhui committed Aug 8, 2018
1 parent 5071dbf commit 73e71e9
Show file tree
Hide file tree
Showing 9 changed files with 285 additions and 17 deletions.
6 changes: 5 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ language: php
php:
- 7.0
- 7.1
- 7.2

services:
- mysql
Expand All @@ -12,9 +13,12 @@ before_install:

install:
- wget https://github.com/redis/hiredis/archive/v0.13.3.tar.gz -O hiredis.tar.gz && mkdir -p hiredis && tar -xf hiredis.tar.gz -C hiredis --strip-components=1 && cd hiredis && sudo make -j$(nproc) && sudo make install && sudo ldconfig && cd ..
- pecl install -f swoole-2.0.12
- echo 'no' | pecl install -f redis
- wget https://github.com/swoole/swoole-src/archive/v4.0.2.tar.gz -O swoole.tar.gz && mkdir -p swoole && tar -xf swoole.tar.gz -C swoole --strip-components=1 && rm swoole.tar.gz && cd swoole && phpize && ./configure --enable-async-redis && make -j$(nproc) && make install && cd -
- echo "extension = swoole.so" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini

before_script:
- phpenv config-rm xdebug.ini
- composer update

script: composer test
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,14 @@
},
"autoload-dev": {
"psr-4": {
"SwoftTest\\HttpServer\\": "test/Cases"
"SwoftTest\\HttpServer\\": "test/Cases",
"SwoftTest\\Testing\\": "test/Testing"
}
},
"repositories": [
{
"type": "composer",
"url": "https://packagist.phpcomposer.com"
"url": "https://packagist.laravel-china.org"
}
],
"require-dev": {
Expand Down
3 changes: 2 additions & 1 deletion src/Command/ServerCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,6 @@ public function stop()
$serverStatus = $httpServer->getServerSetting();
$pidFile = $serverStatus['pfile'];

@unlink($pidFile);
\output()->writeln(sprintf('<info>Swoft %s is stopping ...</info>', input()->getScript()));

$result = $httpServer->stop();
Expand All @@ -131,6 +130,8 @@ public function stop()
if (!$result) {
\output()->writeln(sprintf('<error>Swoft %s stop fail</error>', input()->getScript()), true, true);
}
//删除pid文件
@unlink($pidFile);

output()->writeln(sprintf('<success>Swoft %s stop success!</success>', input()->getScript()));
}
Expand Down
28 changes: 23 additions & 5 deletions src/Validator/HttpValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@

use Swoft\Bean\Annotation\Bean;
use Swoft\Bean\Annotation\ValidatorFrom;
use Swoft\Helper\ArrayHelper;
use Swoft\Helper\JsonHelper;
use Swoft\Helper\StringHelper;
use Swoft\Http\Message\Server\Request;
use Swoft\Http\Message\Stream\SwooleStream;
use Swoft\Validator\AbstractValidator;

/**
Expand Down Expand Up @@ -53,10 +57,18 @@ private function validateField($request, array $matches, string $type, array $va
{
$get = $request->getQueryParams();
$post = $request->getParsedBody();
$contentType = $request->getHeader('content-type');
$isPostJson = false;

if (isset($contentType[0]) && StringHelper::startsWith($contentType[0], 'application/json')) {
$isPostJson = true;
$post = $request->json();
}

foreach ($validatorAry as $name => $info) {
$default = array_pop($info['params']);
if ($type === ValidatorFrom::GET) {
if (! isset($get[$name])) {
if (!isset($get[$name])) {
$request = $request->addQueryParam($name, $default);
$this->doValidation($name, $default, $info);
continue;
Expand All @@ -66,16 +78,22 @@ private function validateField($request, array $matches, string $type, array $va
continue;
}
if ($type === ValidatorFrom::POST && \is_array($post)) {
if (! isset($post[$name])) {
$request = $request->addParserBody($name, $default);
if (! ArrayHelper::has($post, $name)) {
ArrayHelper::set($post, $name, $default);
if ($isPostJson) {
$request = $request->withBody(new SwooleStream(JsonHelper::encode($post)));
} else {
$request = $request->addParserBody($name, $default);
}

$this->doValidation($name, $default, $info);
continue;
}
$this->doValidation($name, $post[$name], $info);
$this->doValidation($name, ArrayHelper::get($post, $name), $info);
continue;
}
if ($type === ValidatorFrom::PATH) {
if (! isset($matches[$name])) {
if (!isset($matches[$name])) {
continue;
}
$this->doValidation($name, $matches[$name], $info);
Expand Down
176 changes: 170 additions & 6 deletions test/Cases/AbstractTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,179 @@
namespace SwoftTest\HttpServer;

use PHPUnit\Framework\TestCase;
use Swoft\App;
use Swoft\Helper\ArrayHelper;
use Swoft\Testing\SwooleRequest as TestSwooleRequest;
use Swoft\Testing\SwooleResponse as TestSwooleResponse;
use Swoft\Http\Message\Testing\Web\Request;
use Swoft\Http\Message\Testing\Web\Response;

/**
* @uses AbstractTestCase
* @version 2017年11月03日
* @author huangzhhui <[email protected]>
* @copyright Copyright 2010-2017 Swoft software
* @license PHP Version 7.x {@link http://www.php.net/license/3_0.txt}
* Class AbstractTestCase
*
* @package Swoft\Test\Cases
*/
abstract class AbstractTestCase extends TestCase
class AbstractTestCase extends TestCase
{
const ACCEPT_VIEW = 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8';

const ACCEPT_JSON = 'application/json';

const ACCEPT_RAW = 'text/plain';

/**
* Send a mock request
*
* @param string $method
* @param string $uri
* @param array $parameters
* @param string $accept
* @param array $headers
* @param string $rawContent
* @return bool|\Swoft\Http\Message\Testing\Web\Response
*/
public function request(
string $method,
string $uri,
array $parameters = [],
string $accept = self::ACCEPT_JSON,
array $headers = [],
string $rawContent = ''
) {
$method = strtoupper($method);
$swooleResponse = new TestSwooleResponse();
$swooleRequest = new TestSwooleRequest();

$this->buildMockRequest($method, $uri, $parameters, $accept, $swooleRequest, $headers);

$swooleRequest->setRawContent($rawContent);

$request = Request::loadFromSwooleRequest($swooleRequest);
$response = new Response($swooleResponse);

/** @var \Swoft\Http\Server\ServerDispatcher $dispatcher */
$dispatcher = App::getBean('serverDispatcher');
return $dispatcher->dispatch($request, $response);
}

/**
* Send a mock json request
*
* @param string $method
* @param string $uri
* @param array $parameters
* @param array $headers
* @param string $rawContent
* @return bool|\Swoft\Http\Message\Testing\Web\Response
*/
public function json(
string $method,
string $uri,
array $parameters = [],
array $headers = [],
string $rawContent = ''
) {
return $this->request($method, $uri, $parameters, self::ACCEPT_JSON, $headers, $rawContent);
}

/**
* Send a mock view request
*
* @param string $method
* @param string $uri
* @param array $parameters
* @param array $headers
* @param string $rawContent
* @return bool|\Swoft\Http\Message\Testing\Web\Response
*/
public function view(
string $method,
string $uri,
array $parameters = [],
array $headers = [],
string $rawContent = ''
) {
return $this->request($method, $uri, $parameters, self::ACCEPT_VIEW, $headers, $rawContent);
}

/**
* Send a mock raw content request
*
* @param string $method
* @param string $uri
* @param array $parameters
* @param array $headers
* @param string $rawContent
* @return bool|\Swoft\Http\Message\Testing\Web\Response
*/
public function raw(
string $method,
string $uri,
array $parameters = [],
array $headers = [],
string $rawContent = ''
) {
return $this->request($method, $uri, $parameters, self::ACCEPT_RAW, $headers, $rawContent);
}

/**
* @param string $method
* @param string $uri
* @param array $parameters
* @param string $accept
* @param \Swoole\Http\Request $swooleRequest
* @param array $headers
*/
protected function buildMockRequest(
string $method,
string $uri,
array $parameters,
string $accept,
&$swooleRequest,
array $headers = []
) {
$urlAry = parse_url($uri);
$urlParams = [];
if (isset($urlAry['query'])) {
parse_str($urlAry['query'], $urlParams);
}
$defaultHeaders = [
'host' => '127.0.0.1',
'connection' => 'keep-alive',
'cache-control' => 'max-age=0',
'user-agent' => 'PHPUnit',
'upgrade-insecure-requests' => '1',
'accept' => $accept,
'dnt' => '1',
'accept-encoding' => 'gzip, deflate, br',
'accept-language' => 'zh-CN,zh;q=0.8,en;q=0.6,it-IT;q=0.4,it;q=0.2',
];

$swooleRequest->fd = 1;
$swooleRequest->header = ArrayHelper::merge($headers, $defaultHeaders);
$swooleRequest->server = [
'request_method' => $method,
'request_uri' => $uri,
'path_info' => '/',
'request_time' => microtime(),
'request_time_float' => microtime(true),
'server_port' => 80,
'remote_port' => 54235,
'remote_addr' => '10.0.2.2',
'master_time' => microtime(),
'server_protocol' => 'HTTP/1.1',
'server_software' => 'swoole-http-server',
];

if ($method == 'GET') {
$swooleRequest->get = $parameters;
} elseif ($method == 'POST') {
$swooleRequest->post = $parameters;
}

if (! empty($urlParams)) {
$get = empty($swooleRequest->get) ? [] : $swooleRequest->get;
$swooleRequest->get = array_merge($urlParams, $get);
}
}
}
35 changes: 35 additions & 0 deletions test/Cases/ValidatorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace SwoftTest\HttpServer;

use Swoft\Helper\JsonHelper;

class ValidatorTest extends AbstractTestCase
{
public function testDemo()
{
$headers = [
'Content-Type' => 'application/json'
];
$raw = JsonHelper::encode([
'test' => [
'id' => 1
]
]);
$res = $this->raw('POST', '/validator/json', [], $headers, $raw)->getBody()->getContents();
$this->assertEquals('[1,"limx"]', $res);

$headers = [
'Content-Type' => 'application/json;charset=UTF-8'
];
$raw = JsonHelper::encode([
'test' => [
'id' => 1
]
]);
$res = $this->raw('POST', '/validator/json', [], $headers, $raw)->getBody()->getContents();
$this->assertEquals('[1,"limx"]', $res);
}


}
30 changes: 30 additions & 0 deletions test/Testing/Controllers/ValidatorController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php
namespace SwoftTest\Testing\Controllers;

use Swoft\Http\Message\Server\Request;
use Swoft\Http\Server\Bean\Annotation\Controller;
use Swoft\Http\Server\Bean\Annotation\RequestMapping;
use Swoft\Http\Server\Bean\Annotation\RequestMethod;
use Swoft\Bean\Annotation\Number;
use Swoft\Bean\Annotation\Strings;
use Swoft\Http\Message\Server\Response;

/**
* Class ValidatorController
* @Controller(prefix="/validator")
*/
class ValidatorController
{
/**
* @Number(name="test.id", max=10)
* @Strings(name="test.name", default="limx")
* @RequestMapping(route="json", method=RequestMethod::POST)
*/
public function json(Request $request, Response $response)
{
$id = $request->json('test.id');
$name = $request->json('test.name');

return $response->json([$id, $name]);
}
}
16 changes: 15 additions & 1 deletion test/config/beans/base.php
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
<?php

return [];
use Swoft\Http\Server\Parser\RequestParser;
use Swoft\Http\Server\Router\HandlerMapping;
use Swoft\Http\Server\ServerDispatcher;

return [
'serverDispatcher' => [
'class' => ServerDispatcher::class,
],
'httpRouter' => [
'class' => HandlerMapping::class,
],
'requestParser' => [
'class' => RequestParser::class,
],
];
Loading

0 comments on commit 73e71e9

Please sign in to comment.