/*
* Copyright 2017 LINE Corporation
*
* LINE Corporation licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.linecorp.armeria.client.thrift;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutionException;
import org.apache.thrift.TApplicationException;
import org.junit.Test;
import com.linecorp.armeria.client.Clients;
import com.linecorp.armeria.common.RpcResponse;
import com.linecorp.armeria.service.test.thrift.main.HelloService;
public class THttpClientBadSeqIdTest {
@Test(timeout = 10000L)
public void badSeqId() throws Exception {
try (ServerSocket ss = new ServerSocket(0)) {
final THttpClient client = Clients.newClient(
"ttext+h1c://127.0.0.1:" + ss.getLocalPort(), THttpClient.class);
final RpcResponse res = client.execute("/", HelloService.Iface.class, "hello", "trustin");
assertThat(res.isDone()).isFalse();
try (Socket s = ss.accept()) {
final InputStream sin = s.getInputStream();
final OutputStream sout = s.getOutputStream();
// Ensure the request is received before sending its response.
assertThat(sin.read()).isGreaterThanOrEqualTo(0);
// Send the TTEXT over HTTP/1 response with mismatching seqid.
final byte[] thriftTextResponse = ('{' +
" \"method\": \"hello\"," +
" \"type\": \"CALL\"," +
" \"seqid\": " + Integer.MIN_VALUE + ',' +
" \"args\": { \"success\": \"Hello, trustin!\" }" +
'}').getBytes(StandardCharsets.US_ASCII);
sout.write(("HTTP/1.1 200 OK\r\n" +
"Connection: close\r\n" +
"Content-Length: " + thriftTextResponse.length + "\r\n" +
"\r\n").getBytes(StandardCharsets.US_ASCII));
sout.write(thriftTextResponse);
// Wait until the client closes the connection thanks to 'connection: close'.
while (sin.read() >= 0) {
continue;
}
}
assertThatThrownBy(res::get)
.isInstanceOf(ExecutionException.class)
.hasCauseInstanceOf(TApplicationException.class)
.satisfies(cause -> assertThat(((TApplicationException) cause.getCause()).getType())
.isEqualTo(TApplicationException.BAD_SEQUENCE_ID));
}
}
}