Accepting request 140295 from devel:libraries:c_c++
- added curl-ftp-prevent-the-multi-interface-from-blocking.patch in order to prevent the multi interface from blocking when using ftp and the remote end responds very slowly (sf#3579064) (forwarded request 140140 from gberh) OBS-URL: https://build.opensuse.org/request/show/140295 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/curl?expand=0&rev=75
This commit is contained in:
commit
e1dbbedfb5
407
curl-ftp-prevent-the-multi-interface-from-blocking.patch
Normal file
407
curl-ftp-prevent-the-multi-interface-from-blocking.patch
Normal file
@ -0,0 +1,407 @@
|
|||||||
|
From b2954e66e87be7414a4508f8167ca531e653bea8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Daniel Stenberg <daniel@haxx.se>
|
||||||
|
Date: Sun, 4 Nov 2012 18:22:48 +0100
|
||||||
|
Subject: [PATCH] FTP: prevent the multi interface from blocking
|
||||||
|
|
||||||
|
As pointed out in Bug report #3579064, curl_multi_perform() would
|
||||||
|
wrongly use a blocking mechanism internally for some commands which
|
||||||
|
could lead to for example a very long block if the LIST response never
|
||||||
|
showed.
|
||||||
|
|
||||||
|
The solution was to make sure to properly continue to use the multi
|
||||||
|
interface non-blocking state machine.
|
||||||
|
|
||||||
|
The new test 1501 verifies the fix.
|
||||||
|
|
||||||
|
Bug: http://curl.haxx.se/bug/view.cgi?id=3579064
|
||||||
|
Reported by: Guido Berhoerster
|
||||||
|
|
||||||
|
Index: curl-7.27.0/lib/ftp.c
|
||||||
|
===================================================================
|
||||||
|
--- curl-7.27.0.orig/lib/ftp.c
|
||||||
|
+++ curl-7.27.0/lib/ftp.c
|
||||||
|
@@ -650,11 +650,18 @@ static CURLcode ftp_readresp(curl_socket
|
||||||
|
if(ftpcode)
|
||||||
|
*ftpcode = code;
|
||||||
|
|
||||||
|
- if(421 == code)
|
||||||
|
+ if(421 == code) {
|
||||||
|
/* 421 means "Service not available, closing control connection." and FTP
|
||||||
|
* servers use it to signal that idle session timeout has been exceeded.
|
||||||
|
- * If we ignored the response, it could end up hanging in some cases. */
|
||||||
|
+ * If we ignored the response, it could end up hanging in some cases.
|
||||||
|
+ *
|
||||||
|
+ * This response code can come at any point so having it treated
|
||||||
|
+ * generically is a good idea.
|
||||||
|
+ */
|
||||||
|
+ infof(data, "We got a 421 - timeout!\n");
|
||||||
|
+ state(conn, FTP_STOP);
|
||||||
|
return CURLE_OPERATION_TIMEDOUT;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
@@ -2378,6 +2385,7 @@ static CURLcode ftp_state_stor_resp(stru
|
||||||
|
|
||||||
|
if(ftpcode>=400) {
|
||||||
|
failf(data, "Failed FTP upload: %0d", ftpcode);
|
||||||
|
+ state(conn, FTP_STOP);
|
||||||
|
/* oops, we never close the sockets! */
|
||||||
|
return CURLE_UPLOAD_FAILED;
|
||||||
|
}
|
||||||
|
@@ -2395,9 +2403,6 @@ static CURLcode ftp_state_stor_resp(stru
|
||||||
|
if(!connected) {
|
||||||
|
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||||
|
infof(data, "Data conn was not available immediately\n");
|
||||||
|
- /* as there's not necessarily an immediate action on the control
|
||||||
|
- connection now, we halt the state machine */
|
||||||
|
- state(conn, FTP_STOP);
|
||||||
|
ftpc->wait_data_conn = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -3647,6 +3652,8 @@ static CURLcode ftp_do_more(struct conne
|
||||||
|
/* the ftp struct is inited in ftp_connect() */
|
||||||
|
struct FTP *ftp = data->state.proto.ftp;
|
||||||
|
|
||||||
|
+ *complete = FALSE;
|
||||||
|
+
|
||||||
|
/* if the second connection isn't done yet, wait for it */
|
||||||
|
if(!conn->bits.tcpconnect[SECONDARYSOCKET]) {
|
||||||
|
result = Curl_is_connected(conn, SECONDARYSOCKET, &connected);
|
||||||
|
@@ -3659,6 +3666,18 @@ static CURLcode ftp_do_more(struct conne
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ if((data->state.used_interface == Curl_if_multi) &&
|
||||||
|
+ ftpc->state) {
|
||||||
|
+ /* multi interface and already in a state so skip the intial commands.
|
||||||
|
+ They are only done to kickstart the do_more state */
|
||||||
|
+ result = ftp_multi_statemach(conn, complete);
|
||||||
|
+
|
||||||
|
+ /* if we got an error or if we don't wait for a data connection return
|
||||||
|
+ immediately */
|
||||||
|
+ if(result || (ftpc->wait_data_conn != TRUE))
|
||||||
|
+ return result;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if(ftp->transfer <= FTPTRANSFER_INFO) {
|
||||||
|
/* a transfer is about to take place, or if not a file name was given
|
||||||
|
so we'll do a SIZE on it later and then we need the right TYPE first */
|
||||||
|
@@ -3712,7 +3731,13 @@ static CURLcode ftp_do_more(struct conne
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- result = ftp_easy_statemach(conn);
|
||||||
|
+ if(data->state.used_interface == Curl_if_multi) {
|
||||||
|
+ result = ftp_multi_statemach(conn, complete);
|
||||||
|
+
|
||||||
|
+ return result;
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ result = ftp_easy_statemach(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((result == CURLE_OK) && (ftp->transfer != FTPTRANSFER_BODY))
|
||||||
|
@@ -4386,20 +4411,21 @@ CURLcode ftp_parse_url_path(struct conne
|
||||||
|
static CURLcode ftp_dophase_done(struct connectdata *conn,
|
||||||
|
bool connected)
|
||||||
|
{
|
||||||
|
- CURLcode result = CURLE_OK;
|
||||||
|
struct FTP *ftp = conn->data->state.proto.ftp;
|
||||||
|
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||||
|
|
||||||
|
if(connected) {
|
||||||
|
bool completed;
|
||||||
|
- result = ftp_do_more(conn, &completed);
|
||||||
|
- }
|
||||||
|
+ CURLcode result = ftp_do_more(conn, &completed);
|
||||||
|
|
||||||
|
- if(result && (conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD)) {
|
||||||
|
- /* Failure detected, close the second socket if it was created already */
|
||||||
|
- Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
|
||||||
|
- conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
|
||||||
|
- return result;
|
||||||
|
+ if(result) {
|
||||||
|
+ if(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD) {
|
||||||
|
+ /* close the second socket if it was created already */
|
||||||
|
+ Curl_closesocket(conn, conn->sock[SECONDARYSOCKET]);
|
||||||
|
+ conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
|
||||||
|
+ }
|
||||||
|
+ return result;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ftp->transfer != FTPTRANSFER_BODY)
|
||||||
|
@@ -4411,7 +4437,7 @@ static CURLcode ftp_dophase_done(struct
|
||||||
|
|
||||||
|
ftpc->ctl_valid = TRUE; /* seems good */
|
||||||
|
|
||||||
|
- return result;
|
||||||
|
+ return CURLE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* called from multi.c while DOing */
|
||||||
|
Index: curl-7.27.0/lib/pingpong.c
|
||||||
|
===================================================================
|
||||||
|
--- curl-7.27.0.orig/lib/pingpong.c
|
||||||
|
+++ curl-7.27.0/lib/pingpong.c
|
||||||
|
@@ -5,7 +5,7 @@
|
||||||
|
* | (__| |_| | _ <| |___
|
||||||
|
* \___|\___/|_| \_\_____|
|
||||||
|
*
|
||||||
|
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
*
|
||||||
|
* This software is licensed as described in the file COPYING, which
|
||||||
|
* you should have received as part of this distribution. The terms
|
||||||
|
@@ -424,6 +424,9 @@ CURLcode Curl_pp_readresp(curl_socket_t
|
||||||
|
it may actually contain another end of response already! */
|
||||||
|
clipamount = gotbytes - i;
|
||||||
|
restart = TRUE;
|
||||||
|
+ DEBUGF(infof(data, "Curl_pp_readresp_ %d bytes of trailing "
|
||||||
|
+ "server response left\n",
|
||||||
|
+ (int)clipamount));
|
||||||
|
}
|
||||||
|
else if(keepon) {
|
||||||
|
|
||||||
|
Index: curl-7.27.0/tests/data/Makefile.am
|
||||||
|
===================================================================
|
||||||
|
--- curl-7.27.0.orig/tests/data/Makefile.am
|
||||||
|
+++ curl-7.27.0/tests/data/Makefile.am
|
||||||
|
@@ -93,6 +93,7 @@ test1379 test1380 test1381 test1382 test
|
||||||
|
test1387 test1388 test1389 test1390 test1391 test1392 test1393 \
|
||||||
|
test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 \
|
||||||
|
test1408 test1409 test1410 \
|
||||||
|
+test1501 \
|
||||||
|
test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
|
||||||
|
test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \
|
||||||
|
test2016 test2017 test2018 test2019 test2020 test2021 test2022
|
||||||
|
Index: curl-7.27.0/tests/data/test1501
|
||||||
|
===================================================================
|
||||||
|
--- /dev/null
|
||||||
|
+++ curl-7.27.0/tests/data/test1501
|
||||||
|
@@ -0,0 +1,53 @@
|
||||||
|
+<testcase>
|
||||||
|
+<info>
|
||||||
|
+<keywords>
|
||||||
|
+FTP
|
||||||
|
+RETR
|
||||||
|
+multi
|
||||||
|
+LIST
|
||||||
|
+</keywords>
|
||||||
|
+</info>
|
||||||
|
+
|
||||||
|
+# Server-side
|
||||||
|
+<reply>
|
||||||
|
+<data>
|
||||||
|
+</data>
|
||||||
|
+<servercmd>
|
||||||
|
+DELAY LIST 2
|
||||||
|
+DELAY TYPE 2
|
||||||
|
+</servercmd>
|
||||||
|
+</reply>
|
||||||
|
+
|
||||||
|
+# Client-side
|
||||||
|
+<client>
|
||||||
|
+<server>
|
||||||
|
+ftp
|
||||||
|
+</server>
|
||||||
|
+<tool>
|
||||||
|
+lib1501
|
||||||
|
+</tool>
|
||||||
|
+ <name>
|
||||||
|
+FTP with multi interface and slow LIST response
|
||||||
|
+ </name>
|
||||||
|
+ <command>
|
||||||
|
+ftp://%HOSTIP:%FTPPORT/1501/
|
||||||
|
+</command>
|
||||||
|
+</client>
|
||||||
|
+# Verify data after the test has been "shot"
|
||||||
|
+<verify>
|
||||||
|
+<errorcode>
|
||||||
|
+0
|
||||||
|
+</errorcode>
|
||||||
|
+<protocol>
|
||||||
|
+USER anonymous
|
||||||
|
+PASS ftp@example.com
|
||||||
|
+PWD
|
||||||
|
+CWD 1501
|
||||||
|
+EPSV
|
||||||
|
+TYPE A
|
||||||
|
+LIST
|
||||||
|
+QUIT
|
||||||
|
+</protocol>
|
||||||
|
+
|
||||||
|
+</verify>
|
||||||
|
+</testcase>
|
||||||
|
Index: curl-7.27.0/tests/data/test591
|
||||||
|
===================================================================
|
||||||
|
--- curl-7.27.0.orig/tests/data/test591
|
||||||
|
+++ curl-7.27.0/tests/data/test591
|
||||||
|
@@ -63,8 +63,9 @@ TYPE I
|
||||||
|
STOR 591
|
||||||
|
QUIT
|
||||||
|
</protocol>
|
||||||
|
+# CURLE_UPLOAD_FAILED = 25
|
||||||
|
<errorcode>
|
||||||
|
-10
|
||||||
|
+25
|
||||||
|
</errorcode>
|
||||||
|
<upload>
|
||||||
|
</upload>
|
||||||
|
Index: curl-7.27.0/tests/data/test592
|
||||||
|
===================================================================
|
||||||
|
--- curl-7.27.0.orig/tests/data/test592
|
||||||
|
+++ curl-7.27.0/tests/data/test592
|
||||||
|
@@ -52,6 +52,7 @@ Moooooooooooo for 592
|
||||||
|
s/^PORT (.*)/PORT/
|
||||||
|
s/^EPRT \|1\|(.*)/EPRT \|1\|/
|
||||||
|
</strippart>
|
||||||
|
+# a 421 response must prevent further commands from being sent
|
||||||
|
<protocol>
|
||||||
|
USER anonymous
|
||||||
|
PASS ftp@example.com
|
||||||
|
@@ -61,10 +62,10 @@ EPRT |1|
|
||||||
|
PORT
|
||||||
|
TYPE I
|
||||||
|
STOR 592
|
||||||
|
-QUIT
|
||||||
|
</protocol>
|
||||||
|
+# 28 == CURLE_OPERATION_TIMEDOUT
|
||||||
|
<errorcode>
|
||||||
|
-10
|
||||||
|
+28
|
||||||
|
</errorcode>
|
||||||
|
<upload>
|
||||||
|
</upload>
|
||||||
|
Index: curl-7.27.0/tests/libtest/lib1501.c
|
||||||
|
===================================================================
|
||||||
|
--- /dev/null
|
||||||
|
+++ curl-7.27.0/tests/libtest/lib1501.c
|
||||||
|
@@ -0,0 +1,126 @@
|
||||||
|
+/***************************************************************************
|
||||||
|
+ * _ _ ____ _
|
||||||
|
+ * Project ___| | | | _ \| |
|
||||||
|
+ * / __| | | | |_) | |
|
||||||
|
+ * | (__| |_| | _ <| |___
|
||||||
|
+ * \___|\___/|_| \_\_____|
|
||||||
|
+ *
|
||||||
|
+ * Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
|
+ *
|
||||||
|
+ * This software is licensed as described in the file COPYING, which
|
||||||
|
+ * you should have received as part of this distribution. The terms
|
||||||
|
+ * are also available at http://curl.haxx.se/docs/copyright.html.
|
||||||
|
+ *
|
||||||
|
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||||
|
+ * copies of the Software, and permit persons to whom the Software is
|
||||||
|
+ * furnished to do so, under the terms of the COPYING file.
|
||||||
|
+ *
|
||||||
|
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
+ * KIND, either express or implied.
|
||||||
|
+ *
|
||||||
|
+ ***************************************************************************/
|
||||||
|
+#include "test.h"
|
||||||
|
+
|
||||||
|
+#include <fcntl.h>
|
||||||
|
+
|
||||||
|
+#include "testutil.h"
|
||||||
|
+#include "warnless.h"
|
||||||
|
+#include "memdebug.h"
|
||||||
|
+
|
||||||
|
+#define TEST_HANG_TIMEOUT 30 * 1000
|
||||||
|
+
|
||||||
|
+/* 500 milliseconds allowed. An extreme number but lets be really conservative
|
||||||
|
+ to allow old and slow machines to run this test too */
|
||||||
|
+#define MAX_BLOCKED_TIME_US 500000
|
||||||
|
+
|
||||||
|
+/* return the number of microseconds between two time stamps */
|
||||||
|
+static int elapsed(struct timeval *before,
|
||||||
|
+ struct timeval *after)
|
||||||
|
+{
|
||||||
|
+ ssize_t result;
|
||||||
|
+
|
||||||
|
+ result = (after->tv_sec - before->tv_sec) * 1000000 +
|
||||||
|
+ after->tv_usec - before->tv_usec;
|
||||||
|
+ if (result < 0)
|
||||||
|
+ result = 0;
|
||||||
|
+
|
||||||
|
+ return curlx_sztosi(result);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+int test(char *URL)
|
||||||
|
+{
|
||||||
|
+ CURL *handle = NULL;
|
||||||
|
+ CURLM *mhandle = NULL;
|
||||||
|
+ int res = 0;
|
||||||
|
+ int still_running = 0;
|
||||||
|
+
|
||||||
|
+ start_test_timing();
|
||||||
|
+
|
||||||
|
+ global_init(CURL_GLOBAL_ALL);
|
||||||
|
+
|
||||||
|
+ easy_init(handle);
|
||||||
|
+
|
||||||
|
+ easy_setopt(handle, CURLOPT_URL, URL);
|
||||||
|
+ easy_setopt(handle, CURLOPT_VERBOSE, 1L);
|
||||||
|
+
|
||||||
|
+ multi_init(mhandle);
|
||||||
|
+
|
||||||
|
+ multi_add_handle(mhandle, handle);
|
||||||
|
+
|
||||||
|
+ multi_perform(mhandle, &still_running);
|
||||||
|
+
|
||||||
|
+ abort_on_test_timeout();
|
||||||
|
+
|
||||||
|
+ while(still_running) {
|
||||||
|
+ struct timeval timeout;
|
||||||
|
+ fd_set fdread;
|
||||||
|
+ fd_set fdwrite;
|
||||||
|
+ fd_set fdexcep;
|
||||||
|
+ int maxfd = -99;
|
||||||
|
+ struct timeval before;
|
||||||
|
+ struct timeval after;
|
||||||
|
+ int e;
|
||||||
|
+
|
||||||
|
+ timeout.tv_sec = 0;
|
||||||
|
+ timeout.tv_usec = 100000L; /* 100 ms */
|
||||||
|
+
|
||||||
|
+ FD_ZERO(&fdread);
|
||||||
|
+ FD_ZERO(&fdwrite);
|
||||||
|
+ FD_ZERO(&fdexcep);
|
||||||
|
+
|
||||||
|
+ multi_fdset(mhandle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||||
|
+
|
||||||
|
+ /* At this point, maxfd is guaranteed to be greater or equal than -1. */
|
||||||
|
+
|
||||||
|
+ select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||||
|
+
|
||||||
|
+ abort_on_test_timeout();
|
||||||
|
+
|
||||||
|
+ fprintf(stderr, "ping\n");
|
||||||
|
+ gettimeofday(&before, 0);
|
||||||
|
+
|
||||||
|
+ multi_perform(mhandle, &still_running);
|
||||||
|
+
|
||||||
|
+ abort_on_test_timeout();
|
||||||
|
+
|
||||||
|
+ gettimeofday(&after, 0);
|
||||||
|
+ e = elapsed(&before, &after);
|
||||||
|
+ fprintf(stderr, "pong = %d\n", e);
|
||||||
|
+
|
||||||
|
+ if(e > MAX_BLOCKED_TIME_US) {
|
||||||
|
+ res = 100;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+test_cleanup:
|
||||||
|
+
|
||||||
|
+ /* undocumented cleanup sequence - type UA */
|
||||||
|
+
|
||||||
|
+ curl_multi_cleanup(mhandle);
|
||||||
|
+ curl_easy_cleanup(handle);
|
||||||
|
+ curl_global_cleanup();
|
||||||
|
+
|
||||||
|
+ return res;
|
||||||
|
+}
|
@ -1,3 +1,10 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Sun Nov 4 19:57:33 UTC 2012 - gber@opensuse.org
|
||||||
|
|
||||||
|
- added curl-ftp-prevent-the-multi-interface-from-blocking.patch in
|
||||||
|
order to prevent the multi interface from blocking when using ftp
|
||||||
|
and the remote end responds very slowly (sf#3579064)
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Sun Jul 29 22:14:25 UTC 2012 - crrodriguez@opensuse.org
|
Sun Jul 29 22:14:25 UTC 2012 - crrodriguez@opensuse.org
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ Name: curl
|
|||||||
Version: 7.27.0
|
Version: 7.27.0
|
||||||
Release: 0
|
Release: 0
|
||||||
Summary: A Tool for Transferring Data from URLs
|
Summary: A Tool for Transferring Data from URLs
|
||||||
License: BSD-3-Clause ; MIT
|
License: BSD-3-Clause and MIT
|
||||||
Group: Productivity/Networking/Web/Utilities
|
Group: Productivity/Networking/Web/Utilities
|
||||||
Url: http://curl.haxx.se/
|
Url: http://curl.haxx.se/
|
||||||
Source: http://curl.haxx.se/download/%{name}-%{version}.tar.lzma
|
Source: http://curl.haxx.se/download/%{name}-%{version}.tar.lzma
|
||||||
@ -32,6 +32,8 @@ Source2: http://curl.haxx.se/download/%{name}-%{version}.tar.lzma.asc
|
|||||||
Source3: baselibs.conf
|
Source3: baselibs.conf
|
||||||
Patch: libcurl-ocloexec.patch
|
Patch: libcurl-ocloexec.patch
|
||||||
Patch1: dont-mess-with-rpmoptflags.diff
|
Patch1: dont-mess-with-rpmoptflags.diff
|
||||||
|
# PATCH-FIX-UPSTREAM curl-ftp-prevent-the-multi-interface-from-blocking.patch sf#3579064 gber@opensuse.org -- Prevent the multi interface from blocking when using ftp and the remote end responds very slowly (backported from upstream git)
|
||||||
|
Patch2: curl-ftp-prevent-the-multi-interface-from-blocking.patch
|
||||||
BuildRequires: libidn-devel
|
BuildRequires: libidn-devel
|
||||||
BuildRequires: libtool
|
BuildRequires: libtool
|
||||||
BuildRequires: lzma
|
BuildRequires: lzma
|
||||||
@ -91,6 +93,7 @@ user interaction or any kind of interactivity.
|
|||||||
%setup -q
|
%setup -q
|
||||||
%patch
|
%patch
|
||||||
%patch1
|
%patch1
|
||||||
|
%patch2 -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
autoreconf -fi
|
autoreconf -fi
|
||||||
|
Loading…
x
Reference in New Issue
Block a user