Skip to content

Commit 7438b25

Browse files
authored
Merge pull request #38 from line/fix/#35
Append `Content-Length: 0` to request header when body of POST is empty
2 parents a15f237 + b47c680 commit 7438b25

File tree

6 files changed

+142
-4
lines changed

6 files changed

+142
-4
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ composer.phar
55
/docs/
66
*.iml
77
vendor/
8+
devtool/req_mirror

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ language: php
22
php:
33
- '5.6'
44
- '7.0'
5-
install: composer update
5+
install:
6+
- ./devtool/download_req_mirror.sh
7+
- composer update
68
script: ./vendor/bin/phpunit ./tests
79
sudo: false
810

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
COMPOSER_BIN = ./vendor/bin
22

3-
.PHONY: default test doc phpcs phpmd check
3+
.PHONY: default test doc phpcs phpmd check install-devtool
44

55
default: check
66

@@ -26,3 +26,6 @@ copyright:
2626

2727
check: test copyright phpcs phpmd
2828

29+
install-devtool:
30+
bash ./devtool/download_req_mirror.sh
31+

devtool/download_req_mirror.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/bash
2+
3+
set -eu
4+
5+
VER='0.0.1'
6+
OS="$(tr '[A-Z]' '[a-z]' <<<$(uname))"
7+
ARCH="$(tr '[A-Z]' '[a-z]' <<<$(arch))"
8+
9+
if [ ${ARCH} = 'i386' ] ; then
10+
ARCH='386'
11+
elif [ ${ARCH} = 'x86_64' ] ; then
12+
ARCH='amd64'
13+
fi
14+
15+
BIN_URL="https://github.com/moznion/req_mirror/releases/download/${VER}/req_mirror_${OS}_${ARCH}_${VER}"
16+
BIN="$(pwd)/$(git rev-parse --show-cdup)/devtool/req_mirror"
17+
18+
curl --fail --location --output ${BIN} ${BIN_URL}
19+
20+
chmod 755 ${BIN}
21+

src/LINEBot/HTTPClient/CurlHTTPClient.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,13 @@ private function sendRequest($method, $url, array $additionalHeader, array $reqB
9595
CURLOPT_HEADER => true,
9696
];
9797

98-
if ($method === 'POST' && !empty($reqBody)) {
99-
$options[CURLOPT_POSTFIELDS] = json_encode($reqBody);
98+
if ($method === 'POST') {
99+
if (empty($reqBody)) {
100+
// Rel: https://github.com/line/line-bot-sdk-php/issues/35
101+
$options[CURLOPT_HTTPHEADER][] = 'Content-Length: 0';
102+
} else {
103+
$options[CURLOPT_POSTFIELDS] = json_encode($reqBody);
104+
}
100105
}
101106

102107
$curl->setoptArray($options);
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?php
2+
3+
/**
4+
* Copyright 2016 LINE Corporation
5+
*
6+
* LINE Corporation licenses this file to you under the Apache License,
7+
* version 2.0 (the "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at:
9+
*
10+
* https://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15+
* License for the specific language governing permissions and limitations
16+
* under the License.
17+
*/
18+
19+
namespace LINE\Tests\LINEBot\HTTPClient;
20+
21+
use LINE\LINEBot\Constant\Meta;
22+
use LINE\LINEBot\HTTPClient\CurlHTTPClient;
23+
24+
class CurlHTTPClientTest extends \PHPUnit_Framework_TestCase
25+
{
26+
private static $reqMirrorPath = __DIR__ . '/../../../devtool/req_mirror';
27+
private static $reqMirrorPort;
28+
private static $reqMirrorPID;
29+
30+
public static function setUpBeforeClass()
31+
{
32+
if (file_exists(CurlHTTPClientTest::$reqMirrorPath)) {
33+
if (empty(CurlHTTPClientTest::$reqMirrorPort)) {
34+
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
35+
socket_bind($sock, '127.0.0.1', 0);
36+
socket_getsockname($sock, $address, CurlHTTPClientTest::$reqMirrorPort);
37+
socket_close($sock);
38+
}
39+
40+
if (empty(CurlHTTPClientTest::$reqMirrorPID)) {
41+
$out = [];
42+
$cmd = sprintf(
43+
'nohup %s --port %d > /dev/null & echo $!',
44+
CurlHTTPClientTest::$reqMirrorPath,
45+
CurlHTTPClientTest::$reqMirrorPort
46+
);
47+
exec($cmd, $out);
48+
CurlHTTPClientTest::$reqMirrorPID = $out[0];
49+
sleep(1); // XXX
50+
}
51+
}
52+
}
53+
54+
public static function tearDownAfterClass()
55+
{
56+
if (!empty(CurlHTTPClientTest::$reqMirrorPID)) {
57+
posix_kill(CurlHTTPClientTest::$reqMirrorPID, SIGKILL);
58+
}
59+
}
60+
61+
protected function setUp()
62+
{
63+
if (!file_exists(CurlHTTPClientTest::$reqMirrorPath) || empty(CurlHTTPClientTest::$reqMirrorPID)) {
64+
$this->fail('req_mirror server is not available. Please try to execute `make install-devtool`');
65+
}
66+
}
67+
68+
public function testGet()
69+
{
70+
$curl = new CurlHTTPClient("channel-token");
71+
$res = $curl->get('127.0.0.1:' . CurlHTTPClientTest::$reqMirrorPort . '/foo/bar?buz=qux');
72+
$body = $res->getJSONDecodedBody();
73+
74+
$this->assertEquals('GET', $body['Method']);
75+
$this->assertEquals('/foo/bar', $body['URL']['Path']);
76+
$this->assertEquals('buz=qux', $body['URL']['RawQuery']);
77+
$this->assertEquals('Bearer channel-token', $body['Header']['Authorization'][0]);
78+
$this->assertEquals('LINE-BotSDK-PHP/' . Meta::VERSION, $body['Header']['User-Agent'][0]);
79+
}
80+
81+
public function testPost()
82+
{
83+
$curl = new CurlHTTPClient("channel-token");
84+
$res = $curl->post('127.0.0.1:' . CurlHTTPClientTest::$reqMirrorPort, ['foo' => 'bar']);
85+
$body = $res->getJSONDecodedBody();
86+
$this->assertEquals('POST', $body['Method']);
87+
$this->assertEquals('/', $body['URL']['Path']);
88+
$this->assertEquals('{"foo":"bar"}', $body['Body']);
89+
$this->assertEquals(13, $body['Header']['Content-Length'][0]);
90+
$this->assertEquals('Bearer channel-token', $body['Header']['Authorization'][0]);
91+
$this->assertEquals('LINE-BotSDK-PHP/' . Meta::VERSION, $body['Header']['User-Agent'][0]);
92+
}
93+
94+
public function testPostWithEmptyBody()
95+
{
96+
$curl = new CurlHTTPClient("channel-token");
97+
$res = $curl->post('127.0.0.1:' . CurlHTTPClientTest::$reqMirrorPort, []);
98+
$body = $res->getJSONDecodedBody();
99+
$this->assertEquals('POST', $body['Method']);
100+
$this->assertEquals('/', $body['URL']['Path']);
101+
$this->assertEquals('', $body['Body']);
102+
$this->assertEquals(0, $body['Header']['Content-Length'][0]);
103+
$this->assertEquals('Bearer channel-token', $body['Header']['Authorization'][0]);
104+
$this->assertEquals('LINE-BotSDK-PHP/' . Meta::VERSION, $body['Header']['User-Agent'][0]);
105+
}
106+
}

0 commit comments

Comments
 (0)