[
https://issues.apache.org/jira/browse/CAMEL-12830?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Önder Sezgin reassigned CAMEL-12830:
------------------------------------
Assignee: Önder Sezgin
> FTP producer stuck if timeout occurs just after connect
> -------------------------------------------------------
>
> Key: CAMEL-12830
> URL: https://issues.apache.org/jira/browse/CAMEL-12830
> Project: Camel
> Issue Type: Bug
> Components: camel-ftp
> Affects Versions: 2.22.1
> Reporter: Laurent Chiarello
> Assignee: Önder Sezgin
> Priority: Major
> Attachments: FtpOperations.patch, FtpSoTimeoutTest.java
>
>
> In our production systems, we had several threads stuck indefinitely while
> trying to send a file to an FtpEndpoint. We had both _connectTimeout_ and
> _soTimeout_ properties set so it surprised us a little bit.
> After digging a bit, we found that the scenario is quite simple to reproduce:
> this happens every time the {{FTPClient}} establishes the TCP connection with
> a server that does not respond anything.
> Here is a simplified view of what happens when establishing a connection
> using a {{FTPClient}}:
> {code:java}
> // within Socket Client
> public void connect(InetAddress host, int port) throws
> SocketException,IOException {
> _socket_.connect(new InetSocketAddress(host, port), connectTimeout);
> _connectAction_();
> }
> protected void _connectAction_() throws IOException {
> _socket_.setSoTimeout(_timeout_); // _timeout_ is the default timeout of
> the socket
> }
> // overridden within FTP
> protected void _connectAction_() {
> super._connectAction_();
> if (connectTimeout > 0) {
> int original = _socket_.getSoTimeout();
> _socket_.setSoTimeout(connectTimeout);
> try {
> __getReply();
> } finally {
> _socket_.setSoTimeout(original);
> }
> }
> }{code}
> A {{SocketTimeoutException}} can be thrown either during the initial socket
> _connect_ action, either during the ___getReply()_ where the FTPClient waits
> for the hello message from the server. Both are using _connectTimeout_,
> after which the original (default) timeout is restored. The _soTimeout_ we
> specified in the URI is configured by FTPOperations only when the connection
> is successful. In this case, the Socket is connected, but an exception is
> thrown afterwards and the _soTimeout_ is left at 0.
> Within Camel, when the RemoteFileProducer encounters an exception while
> processing an Exchange, it tries to disconnect the endpoint properly with a
> _logout_ followed by a _disconnect_.
> {code:java}
> // RemoteFileProducer
> public void handleFailedWrite(Exchange exchange, Exception exception) throws
> Exception {
> try {
> if (getOperations().isConnected()) { // <== in our case, this returns
> true because the socket is actually connected
> getOperations().disconnect();
> }
> } catch (...) {
> ...
> }
> }
> // FTPOperations
> protected void doDisconnect() throws GenericFileOperationFailedException {
> try {
> client.logout();
> } catch (IOException e) {
> throw new GenericFileOperationFailedException
> } finally {
> try {
> client.disconnect();
> } catch (IOException e) {
> throw new GenericFileOperationFailedException
> }
> }
> }{code}
> Unfortunately, at this point, the {{client.logout()}} sends the FTP {{QUIT}}
> command, then waits for the response still using the default timeout of the
> Socket. Since the misbehaving server/firewall never sent any form of
> response, the thread is left waiting forever.
> I attached a simple test case to illustrate the scenario, simply using a
> ServerSocket that never accepts any connection. Also included is an easy
> workaround that uses a custom FTPClient on which the _default timeout_ is
> set.
> A possible fix would be to always set the _default timeout_ on the socket,
> before connecting it.
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)