Here is setup which reproduces this problem. Also exists in 6.2.
Server:
Apache with mod_php serving following content:
———cut options.php——————
<?php
if (isset($_SERVER['HTTP_X_FORWARDED_PORT'])) {
http_response_code(200);
echo 'OK';
}
else {
http_response_code(403);
echo 'Bad call';
}
——————————————————————————————————
Relayd:
http protocol http_relay {
tcp { nodelay, sack, backlog 1024 }
match header append "X-Forwarded-For" value "$REMOTE_ADDR"
match header set "X-Forwarded-By" value "$SERVER_ADDR:$SERVER_PORT"
match header set "X-Forwarded-Port" value "80"
match header set "Keep-Alive" value "$TIMEOUT"
match request header remove "Proxy"
}
table <apache> { 1.2.3.4 }
relay web_test {
listen on 5.6.7.8 port 80
protocol http_relay
forward to <apache> port 80 mode loadbalance check tcp
}
Client:
Runs php from CLI
file to run:
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://5.6.7.8/options.php');
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "OPTIONS");
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_exec($ch);
echo PHP_EOL;
curl_setopt($ch, CURLOPT_URL, 'http://5.6.7.8/options.php');
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_exec($ch);
echo PHP_EOL;
curl_setopt($ch, CURLOPT_URL, 'http://5.6.7.8');
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_exec($ch);
echo PHP_EOL;
With rev. Before 1.58 of relay_http.c following can be observed:
relay web_test, session 1 (1 active), 0, 172.17.2.21 -> 172.16.1.30:80, done,
OPTIONS GET GET
With the rev. current for 6.2:
relay web_test, session 1 (1 active), 0, 172.17.2.21 -> 172.16.1.30:80, done,
OPTIONS
//mxb
> 22 okt. 2017 kl. 21:02 skrev Maxim Bourmistrov <[email protected]>:
>
>
>> 22 okt. 2017 kl. 20:16 skrev Maxim Bourmistrov <[email protected]>:
>>
>> Hey,
>> with rev 1.58 OPTIONS in relay_http.c got broken
>> or at least logic inside relay_read_http().
>> Quick fix it to cre->toread=0 and break, but this is probably not what
>> should be there.
>>
>> In my test case, from the client side I do an OPTIONS request, followed by a
>> couple of GET.
>> GET in the middle never gets catched and thus breaks intended usage.
>>
>> I’m doing a simple printf() debugging here to catch.
>>
>> cre->toread = strtonum(value, 0, LLONG_MAX, &errstr);
>> printf("------ to read %lld\n", cre->toread);
>>
>>
>> case HTTP_METHOD_GET:
>> printf("GOT GET to read: %lld\n", cre->toread);
>>
>> case HTTP_METHOD_OPTIONS:
>> printf("GOT OPT to read: %lld\n", cre->toread);
>>
>>
>> The output with those in place from ’relayd -d’:
>>
>> host 10.6.128.38, check http code (1ms,http code ok), state up -> up,
>> availability 100.00%
>> GOT OPT to read: -2
>> ------ to read 0
>> ------ to read 214
>> relay test_api_tls, session 1 (1 active), 0, 176.10.170.140 ->
>> 10.6.128.20:80, done, OPTIONS
>> GOT GET to read: -2
>> ------ to read 214
>> relay test_api_tls, session 2 (1 active), 0, 176.10.170.140 ->
>> 10.6.128.36:80, done, GET
>> ^Chce exiting, pid 96033
>>
>> //mxb
>>
>
> With cre->toread=0 I catch it all
>
> relay test_api_tls, session 1 (1 active), 0, 176.10.170.140 ->
> 10.6.128.20:80, done, OPTIONS GET
> relay test_api_tls, session 2 (1 active), 0, 176.10.170.140 ->
> 10.6.128.36:80, done, GET
>
> //mxb
>