9d7d3f
From 9b675516d5fb09a455d1f7b7aa98e253361bedf3 Mon Sep 17 00:00:00 2001
9d7d3f
From: Daniel Stenberg <daniel@haxx.se>
9d7d3f
Date: Fri, 8 Feb 2013 13:48:56 +0100
9d7d3f
Subject: [PATCH 1/2] DONE: consider callback-aborted transfers premature
9d7d3f
9d7d3f
This bug report properly identified that when doing SMTP and aborting
9d7d3f
the transfer with a callback, it must be considered aborted prematurely
9d7d3f
by the code to avoid QUIT etc to be attempted as that would cause a
9d7d3f
hang.
9d7d3f
9d7d3f
The new test case 1507 verifies this behavior.
9d7d3f
9d7d3f
Reported by: Patricia Muscalu
9d7d3f
Bug: http://curl.haxx.se/bug/view.cgi?id=1184
9d7d3f
9d7d3f
[upstream commit 72688317adcedb9508fd2189e6c6d3945e06a004]
9d7d3f
9d7d3f
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
9d7d3f
---
9d7d3f
 lib/url.c                  |    7 ++
9d7d3f
 tests/data/Makefile.am     |    3 +-
9d7d3f
 tests/data/Makefile.in     |    3 +-
9d7d3f
 tests/data/test1507        |   51 +++++++++++++
9d7d3f
 tests/libtest/Makefile.in  |   82 +++++++++++++++++++++-
9d7d3f
 tests/libtest/Makefile.inc |    6 ++-
9d7d3f
 tests/libtest/lib1507.c    |  167 ++++++++++++++++++++++++++++++++++++++++++++
9d7d3f
 7 files changed, 313 insertions(+), 6 deletions(-)
9d7d3f
 create mode 100644 tests/data/test1507
9d7d3f
 create mode 100644 tests/libtest/lib1507.c
9d7d3f
9d7d3f
diff --git a/lib/url.c b/lib/url.c
9d7d3f
index 52f7e27..a6375a2 100644
9d7d3f
--- a/lib/url.c
9d7d3f
+++ b/lib/url.c
9d7d3f
@@ -5222,6 +5222,13 @@ CURLcode Curl_done(struct connectdata **connp,
9d7d3f
     conn->dns_entry = NULL;
9d7d3f
   }
9d7d3f
 
9d7d3f
+  if(status == CURLE_ABORTED_BY_CALLBACK)
9d7d3f
+    /* When we're aborted due to a callback return code it basically have to
9d7d3f
+       be counted as premature as there is trouble ahead if we don't. We have
9d7d3f
+       many callbacks and protocols work differently, we could potentially do
9d7d3f
+       this more fine-grained in the future. */
9d7d3f
+    premature = TRUE;
9d7d3f
+
9d7d3f
   /* this calls the protocol-specific function pointer previously set */
9d7d3f
   if(conn->handler->done)
9d7d3f
     result = conn->handler->done(conn, status, premature);
9d7d3f
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
9d7d3f
index 3f6a047..805955c 100644
9d7d3f
--- a/tests/data/Makefile.am
9d7d3f
+++ b/tests/data/Makefile.am
9d7d3f
@@ -93,7 +93,8 @@ test1379 test1380 test1381 test1382 test1383 test1384 test1385 test1386 \
9d7d3f
 test1387 test1388 test1389 test1390 test1391 test1392 test1393 \
9d7d3f
 test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 \
9d7d3f
 test1408 test1409 test1410 test1411 test1412 test1413 \
9d7d3f
-test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1508 \
9d7d3f
+test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
9d7d3f
+test1508 \
9d7d3f
 test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
9d7d3f
 test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \
9d7d3f
 test2016 test2017 test2018 test2019 test2020 test2021 test2022 \
9d7d3f
diff --git a/tests/data/Makefile.in b/tests/data/Makefile.in
9d7d3f
index 71c9422..1e6d679 100644
9d7d3f
--- a/tests/data/Makefile.in
9d7d3f
+++ b/tests/data/Makefile.in
9d7d3f
@@ -357,7 +357,8 @@ test1379 test1380 test1381 test1382 test1383 test1384 test1385 test1386 \
9d7d3f
 test1387 test1388 test1389 test1390 test1391 test1392 test1393 \
9d7d3f
 test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 \
9d7d3f
 test1408 test1409 test1410 test1411 test1412 test1413 \
9d7d3f
-test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1508 \
9d7d3f
+test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
9d7d3f
+test1508 \
9d7d3f
 test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
9d7d3f
 test2008 test2009 test2010 test2011 test2012 test2013 test2014 test2015 \
9d7d3f
 test2016 test2017 test2018 test2019 test2020 test2021 test2022 \
9d7d3f
diff --git a/tests/data/test1507 b/tests/data/test1507
9d7d3f
new file mode 100644
9d7d3f
index 0000000..b66e71d
9d7d3f
--- /dev/null
9d7d3f
+++ b/tests/data/test1507
9d7d3f
@@ -0,0 +1,51 @@
9d7d3f
+<testcase>
9d7d3f
+<info>
9d7d3f
+<keywords>
9d7d3f
+SMTP
9d7d3f
+multi
9d7d3f
+</keywords>
9d7d3f
+</info>
9d7d3f
+
9d7d3f
+#
9d7d3f
+# Server-side
9d7d3f
+<reply>
9d7d3f
+</reply>
9d7d3f
+
9d7d3f
+#
9d7d3f
+# Client-side
9d7d3f
+<client>
9d7d3f
+<server>
9d7d3f
+smtp
9d7d3f
+</server>
9d7d3f
+<tool>
9d7d3f
+lib1507
9d7d3f
+</tool>
9d7d3f
+
9d7d3f
+# based on bug report #1184
9d7d3f
+ <name>
9d7d3f
+SMTP with multi interface and CURLE_ABORTED_BY_CALLBACK
9d7d3f
+ </name>
9d7d3f
+<stdin>
9d7d3f
+From: different
9d7d3f
+To: another
9d7d3f
+
9d7d3f
+body
9d7d3f
+</stdin>
9d7d3f
+ <command>
9d7d3f
+smtp://%HOSTIP:%SMTPPORT/user
9d7d3f
+</command>
9d7d3f
+</client>
9d7d3f
+
9d7d3f
+#
9d7d3f
+# Verify data after the test has been "shot"
9d7d3f
+<verify>
9d7d3f
+<protocol>
9d7d3f
+EHLO user
9d7d3f
+MAIL FROM:<1507-realuser@example.com>
9d7d3f
+RCPT TO:<1507-recipient@example.com>
9d7d3f
+DATA
9d7d3f
+</protocol>
9d7d3f
+<upload>
9d7d3f
+</upload>
9d7d3f
+</verify>
9d7d3f
+</testcase>
9d7d3f
diff --git a/tests/libtest/Makefile.in b/tests/libtest/Makefile.in
9d7d3f
index 7683c09..e6826c0 100644
9d7d3f
--- a/tests/libtest/Makefile.in
9d7d3f
+++ b/tests/libtest/Makefile.in
9d7d3f
@@ -85,7 +85,8 @@ noinst_PROGRAMS = chkhostname$(EXEEXT) libauthretry$(EXEEXT) \
9d7d3f
 	lib591$(EXEEXT) lib597$(EXEEXT) lib598$(EXEEXT) \
9d7d3f
 	lib599$(EXEEXT) lib1500$(EXEEXT) lib1501$(EXEEXT) \
9d7d3f
 	lib1502$(EXEEXT) lib1503$(EXEEXT) lib1504$(EXEEXT) \
9d7d3f
-	lib1505$(EXEEXT) lib1506$(EXEEXT) lib1508$(EXEEXT)
9d7d3f
+	lib1505$(EXEEXT) lib1506$(EXEEXT) lib1507$(EXEEXT) \
9d7d3f
+	lib1508$(EXEEXT)
9d7d3f
 subdir = tests/libtest
9d7d3f
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
9d7d3f
 am__aclocal_m4_deps = $(top_srcdir)/m4/curl-compilers.m4 \
9d7d3f
@@ -173,6 +174,13 @@ am_lib1506_OBJECTS = lib1506-lib1506.$(OBJEXT) $(am__objects_18) \
9d7d3f
 	$(am__objects_19) $(am__objects_20)
9d7d3f
 lib1506_OBJECTS = $(am_lib1506_OBJECTS)
9d7d3f
 lib1506_DEPENDENCIES = $(am__DEPENDENCIES_1)
9d7d3f
+am__objects_154 = lib1507-first.$(OBJEXT)
9d7d3f
+am__objects_155 = lib1507-testutil.$(OBJEXT)
9d7d3f
+am__objects_156 = lib1507-warnless.$(OBJEXT)
9d7d3f
+am_lib1507_OBJECTS = lib1507-lib1507.$(OBJEXT) $(am__objects_154) \
9d7d3f
+	$(am__objects_155) $(am__objects_156)
9d7d3f
+lib1507_OBJECTS = $(am_lib1507_OBJECTS)
9d7d3f
+lib1507_DEPENDENCIES = $(am__DEPENDENCIES_1)
9d7d3f
 am__objects_151 = lib1508-first.$(OBJEXT)
9d7d3f
 am__objects_152 = lib1508-testutil.$(OBJEXT)
9d7d3f
 am__objects_153 = lib1508-warnless.$(OBJEXT)
9d7d3f
@@ -639,7 +647,8 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
9d7d3f
 SOURCES = $(libhostname_la_SOURCES) $(chkhostname_SOURCES) \
9d7d3f
 	$(lib1500_SOURCES) $(lib1501_SOURCES) $(lib1502_SOURCES) \
9d7d3f
 	$(lib1503_SOURCES) $(lib1504_SOURCES) $(lib1505_SOURCES) \
9d7d3f
-	$(lib1506_SOURCES) $(lib1508_SOURCES) $(lib500_SOURCES) $(lib501_SOURCES) \
9d7d3f
+	$(lib1506_SOURCES) $(lib1507_SOURCES) $(lib1508_SOURCES) \
9d7d3f
+	$(lib500_SOURCES) $(lib501_SOURCES) \
9d7d3f
 	$(lib502_SOURCES) $(lib503_SOURCES) $(lib504_SOURCES) \
9d7d3f
 	$(lib505_SOURCES) $(lib506_SOURCES) $(lib507_SOURCES) \
9d7d3f
 	$(lib508_SOURCES) $(lib510_SOURCES) $(lib511_SOURCES) \
9d7d3f
@@ -669,7 +678,8 @@ SOURCES = $(libhostname_la_SOURCES) $(chkhostname_SOURCES) \
9d7d3f
 DIST_SOURCES = $(libhostname_la_SOURCES) $(chkhostname_SOURCES) \
9d7d3f
 	$(lib1500_SOURCES) $(lib1501_SOURCES) $(lib1502_SOURCES) \
9d7d3f
 	$(lib1503_SOURCES) $(lib1504_SOURCES) $(lib1505_SOURCES) \
9d7d3f
-	$(lib1506_SOURCES) $(lib1508_SOURCES) $(lib500_SOURCES) $(lib501_SOURCES)  \
9d7d3f
+	$(lib1506_SOURCES) $(lib1507_SOURCES) $(lib1508_SOURCES) \
9d7d3f
+	$(lib500_SOURCES) $(lib501_SOURCES)  \
9d7d3f
 	$(lib502_SOURCES) $(lib503_SOURCES) $(lib504_SOURCES) \
9d7d3f
 	$(lib505_SOURCES) $(lib506_SOURCES) $(lib507_SOURCES) \
9d7d3f
 	$(lib508_SOURCES) $(lib510_SOURCES) $(lib511_SOURCES) \
9d7d3f
@@ -1162,6 +1172,9 @@ lib1505_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1505
9d7d3f
 lib1506_SOURCES = lib1506.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
9d7d3f
 lib1506_LDADD = $(TESTUTIL_LIBS)
9d7d3f
 lib1506_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1506
9d7d3f
+lib1507_SOURCES = lib1507.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
9d7d3f
+lib1507_LDADD = $(TESTUTIL_LIBS)
9d7d3f
+lib1507_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1507
9d7d3f
 lib1508_SOURCES = lib1508.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
9d7d3f
 lib1508_LDADD = $(TESTUTIL_LIBS)
9d7d3f
 lib1508_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1508
9d7d3f
@@ -1263,6 +1276,9 @@ lib1505$(EXEEXT): $(lib1505_OBJECTS) $(lib1505_DEPENDENCIES) $(EXTRA_lib1505_DEP
9d7d3f
 lib1506$(EXEEXT): $(lib1506_OBJECTS) $(lib1506_DEPENDENCIES) $(EXTRA_lib1506_DEPENDENCIES) 
9d7d3f
 	@rm -f lib1506$(EXEEXT)
9d7d3f
 	$(LINK) $(lib1506_OBJECTS) $(lib1506_LDADD) $(LIBS)
9d7d3f
+lib1507$(EXEEXT): $(lib1507_OBJECTS) $(lib1507_DEPENDENCIES) $(EXTRA_lib1507_DEPENDENCIES) 
9d7d3f
+	@rm -f lib1507$(EXEEXT)
9d7d3f
+	$(LINK) $(lib1507_OBJECTS) $(lib1507_LDADD) $(LIBS)
9d7d3f
 lib1508$(EXEEXT): $(lib1508_OBJECTS) $(lib1508_DEPENDENCIES) $(EXTRA_lib1508_DEPENDENCIES) 
9d7d3f
 	@rm -f lib1508$(EXEEXT)
9d7d3f
 	$(LINK) $(lib1508_OBJECTS) $(lib1508_LDADD) $(LIBS)
9d7d3f
@@ -1533,6 +1549,10 @@ distclean-compile:
9d7d3f
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1506-lib1506.Po@am__quote@
9d7d3f
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1506-testutil.Po@am__quote@
9d7d3f
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1506-warnless.Po@am__quote@
9d7d3f
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1507-first.Po@am__quote@
9d7d3f
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1507-lib1507.Po@am__quote@
9d7d3f
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1507-testutil.Po@am__quote@
9d7d3f
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1507-warnless.Po@am__quote@
9d7d3f
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1508-first.Po@am__quote@
9d7d3f
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1508-lib1508.Po@am__quote@
9d7d3f
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lib1508-testutil.Po@am__quote@
9d7d3f
@@ -2180,6 +2200,62 @@ lib1506-warnless.obj: ../../lib/warnless.c
9d7d3f
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
9d7d3f
 @am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1506_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1506-warnless.obj `if test -f '../../lib/warnless.c'; then $(CYGPATH_W) '../../lib/warnless.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/warnless.c'; fi`
9d7d3f
 
9d7d3f
+lib1507-lib1507.o: lib1507.c
9d7d3f
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1507-lib1507.o -MD -MP -MF $(DEPDIR)/lib1507-lib1507.Tpo -c -o lib1507-lib1507.o `test -f 'lib1507.c' || echo '$(srcdir)/'`lib1507.c
9d7d3f
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/lib1507-lib1507.Tpo $(DEPDIR)/lib1507-lib1507.Po
9d7d3f
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='lib1507.c' object='lib1507-lib1507.o' libtool=no @AMDEPBACKSLASH@
9d7d3f
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
9d7d3f
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1507-lib1507.o `test -f 'lib1507.c' || echo '$(srcdir)/'`lib1507.c
9d7d3f
+
9d7d3f
+lib1507-lib1507.obj: lib1507.c
9d7d3f
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1507-lib1507.obj -MD -MP -MF $(DEPDIR)/lib1507-lib1507.Tpo -c -o lib1507-lib1507.obj `if test -f 'lib1507.c'; then $(CYGPATH_W) 'lib1507.c'; else $(CYGPATH_W) '$(srcdir)/lib1507.c'; fi`
9d7d3f
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/lib1507-lib1507.Tpo $(DEPDIR)/lib1507-lib1507.Po
9d7d3f
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='lib1507.c' object='lib1507-lib1507.obj' libtool=no @AMDEPBACKSLASH@
9d7d3f
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
9d7d3f
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1507-lib1507.obj `if test -f 'lib1507.c'; then $(CYGPATH_W) 'lib1507.c'; else $(CYGPATH_W) '$(srcdir)/lib1507.c'; fi`
9d7d3f
+
9d7d3f
+lib1507-first.o: first.c
9d7d3f
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1507-first.o -MD -MP -MF $(DEPDIR)/lib1507-first.Tpo -c -o lib1507-first.o `test -f 'first.c' || echo '$(srcdir)/'`first.c
9d7d3f
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/lib1507-first.Tpo $(DEPDIR)/lib1507-first.Po
9d7d3f
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='first.c' object='lib1507-first.o' libtool=no @AMDEPBACKSLASH@
9d7d3f
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
9d7d3f
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1507-first.o `test -f 'first.c' || echo '$(srcdir)/'`first.c
9d7d3f
+
9d7d3f
+lib1507-first.obj: first.c
9d7d3f
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1507-first.obj -MD -MP -MF $(DEPDIR)/lib1507-first.Tpo -c -o lib1507-first.obj `if test -f 'first.c'; then $(CYGPATH_W) 'first.c'; else $(CYGPATH_W) '$(srcdir)/first.c'; fi`
9d7d3f
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/lib1507-first.Tpo $(DEPDIR)/lib1507-first.Po
9d7d3f
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='first.c' object='lib1507-first.obj' libtool=no @AMDEPBACKSLASH@
9d7d3f
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
9d7d3f
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1507-first.obj `if test -f 'first.c'; then $(CYGPATH_W) 'first.c'; else $(CYGPATH_W) '$(srcdir)/first.c'; fi`
9d7d3f
+
9d7d3f
+lib1507-testutil.o: testutil.c
9d7d3f
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1507-testutil.o -MD -MP -MF $(DEPDIR)/lib1507-testutil.Tpo -c -o lib1507-testutil.o `test -f 'testutil.c' || echo '$(srcdir)/'`testutil.c
9d7d3f
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/lib1507-testutil.Tpo $(DEPDIR)/lib1507-testutil.Po
9d7d3f
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='testutil.c' object='lib1507-testutil.o' libtool=no @AMDEPBACKSLASH@
9d7d3f
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
9d7d3f
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1507-testutil.o `test -f 'testutil.c' || echo '$(srcdir)/'`testutil.c
9d7d3f
+
9d7d3f
+lib1507-testutil.obj: testutil.c
9d7d3f
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1507-testutil.obj -MD -MP -MF $(DEPDIR)/lib1507-testutil.Tpo -c -o lib1507-testutil.obj `if test -f 'testutil.c'; then $(CYGPATH_W) 'testutil.c'; else $(CYGPATH_W) '$(srcdir)/testutil.c'; fi`
9d7d3f
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/lib1507-testutil.Tpo $(DEPDIR)/lib1507-testutil.Po
9d7d3f
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='testutil.c' object='lib1507-testutil.obj' libtool=no @AMDEPBACKSLASH@
9d7d3f
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
9d7d3f
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1507-testutil.obj `if test -f 'testutil.c'; then $(CYGPATH_W) 'testutil.c'; else $(CYGPATH_W) '$(srcdir)/testutil.c'; fi`
9d7d3f
+
9d7d3f
+lib1507-warnless.o: ../../lib/warnless.c
9d7d3f
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1507-warnless.o -MD -MP -MF $(DEPDIR)/lib1507-warnless.Tpo -c -o lib1507-warnless.o `test -f '../../lib/warnless.c' || echo '$(srcdir)/'`../../lib/warnless.c
9d7d3f
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/lib1507-warnless.Tpo $(DEPDIR)/lib1507-warnless.Po
9d7d3f
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='../../lib/warnless.c' object='lib1507-warnless.o' libtool=no @AMDEPBACKSLASH@
9d7d3f
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
9d7d3f
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1507-warnless.o `test -f '../../lib/warnless.c' || echo '$(srcdir)/'`../../lib/warnless.c
9d7d3f
+
9d7d3f
+lib1507-warnless.obj: ../../lib/warnless.c
9d7d3f
+@am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1507-warnless.obj -MD -MP -MF $(DEPDIR)/lib1507-warnless.Tpo -c -o lib1507-warnless.obj `if test -f '../../lib/warnless.c'; then $(CYGPATH_W) '../../lib/warnless.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/warnless.c'; fi`
9d7d3f
+@am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/lib1507-warnless.Tpo $(DEPDIR)/lib1507-warnless.Po
9d7d3f
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='../../lib/warnless.c' object='lib1507-warnless.obj' libtool=no @AMDEPBACKSLASH@
9d7d3f
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
9d7d3f
+@am__fastdepCC_FALSE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1507_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o lib1507-warnless.obj `if test -f '../../lib/warnless.c'; then $(CYGPATH_W) '../../lib/warnless.c'; else $(CYGPATH_W) '$(srcdir)/../../lib/warnless.c'; fi`
9d7d3f
+
9d7d3f
 lib1508-lib1508.o: lib1508.c
9d7d3f
 @am__fastdepCC_TRUE@	$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(lib1508_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT lib1508-lib1508.o -MD -MP -MF $(DEPDIR)/lib1508-lib1508.Tpo -c -o lib1508-lib1508.o `test -f 'lib1508.c' || echo '$(srcdir)/'`lib1508.c
9d7d3f
 @am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/lib1508-lib1508.Tpo $(DEPDIR)/lib1508-lib1508.Po
9d7d3f
diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc
9d7d3f
index 8bf2be4..5e377d3 100644
9d7d3f
--- a/tests/libtest/Makefile.inc
9d7d3f
+++ b/tests/libtest/Makefile.inc
9d7d3f
@@ -23,7 +23,7 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect \
9d7d3f
                 lib582 lib583        lib585 lib586 lib587               \
9d7d3f
   lib590 lib591                                    lib597 lib598 lib599 \
9d7d3f
   \
9d7d3f
-  lib1500 lib1501 lib1502 lib1503 lib1504 lib1505 lib1506 lib1508
9d7d3f
+  lib1500 lib1501 lib1502 lib1503 lib1504 lib1505 lib1506 lib1507 lib1508
9d7d3f
 
9d7d3f
 chkhostname_SOURCES = chkhostname.c ../../lib/curl_gethostname.c
9d7d3f
 chkhostname_LDADD = @CURL_NETWORK_LIBS@
9d7d3f
@@ -313,6 +313,10 @@ lib1506_SOURCES = lib1506.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
9d7d3f
 lib1506_LDADD = $(TESTUTIL_LIBS)
9d7d3f
 lib1506_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1506
9d7d3f
 
9d7d3f
+lib1507_SOURCES = lib1507.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
9d7d3f
+lib1507_LDADD = $(TESTUTIL_LIBS)
9d7d3f
+lib1507_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1507
9d7d3f
+
9d7d3f
 lib1508_SOURCES = lib1508.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS)
9d7d3f
 lib1508_LDADD = $(TESTUTIL_LIBS)
9d7d3f
 lib1508_CPPFLAGS = $(AM_CPPFLAGS) -DLIB1508
9d7d3f
diff --git a/tests/libtest/lib1507.c b/tests/libtest/lib1507.c
9d7d3f
new file mode 100644
9d7d3f
index 0000000..7c4e6ed
9d7d3f
--- /dev/null
9d7d3f
+++ b/tests/libtest/lib1507.c
9d7d3f
@@ -0,0 +1,167 @@
9d7d3f
+/***************************************************************************
9d7d3f
+ *                                  _   _ ____  _
9d7d3f
+ *  Project                     ___| | | |  _ \| |
9d7d3f
+ *                             / __| | | | |_) | |
9d7d3f
+ *                            | (__| |_| |  _ <| |___
9d7d3f
+ *                             \___|\___/|_| \_\_____|
9d7d3f
+ *
9d7d3f
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
9d7d3f
+ *
9d7d3f
+ * This software is licensed as described in the file COPYING, which
9d7d3f
+ * you should have received as part of this distribution. The terms
9d7d3f
+ * are also available at http://curl.haxx.se/docs/copyright.html.
9d7d3f
+ *
9d7d3f
+ * You may opt to use, copy, modify, merge, publish, distribute and/or sell
9d7d3f
+ * copies of the Software, and permit persons to whom the Software is
9d7d3f
+ * furnished to do so, under the terms of the COPYING file.
9d7d3f
+ *
9d7d3f
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
9d7d3f
+ * KIND, either express or implied.
9d7d3f
+ *
9d7d3f
+ ***************************************************************************/
9d7d3f
+#include "test.h"
9d7d3f
+
9d7d3f
+#include "testutil.h"
9d7d3f
+#include "warnless.h"
9d7d3f
+#include "memdebug.h"
9d7d3f
+
9d7d3f
+/*
9d7d3f
+ * This is the list of basic details you need to tweak to get things right.
9d7d3f
+ */
9d7d3f
+#define USERNAME "user@example.com"
9d7d3f
+#define PASSWORD "123qwerty"
9d7d3f
+#define RECIPIENT "<1507-recipient@example.com>"
9d7d3f
+#define MAILFROM "<1507-realuser@example.com>"
9d7d3f
+
9d7d3f
+#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
9d7d3f
+
9d7d3f
+static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
9d7d3f
+{
9d7d3f
+  (void)ptr;
9d7d3f
+  (void)size;
9d7d3f
+  (void)nmemb;
9d7d3f
+  (void)userp;
9d7d3f
+  return CURL_READFUNC_ABORT;
9d7d3f
+}
9d7d3f
+
9d7d3f
+static struct timeval tvnow(void)
9d7d3f
+{
9d7d3f
+  /*
9d7d3f
+  ** time() returns the value of time in seconds since the Epoch.
9d7d3f
+  */
9d7d3f
+  struct timeval now;
9d7d3f
+  now.tv_sec = (long)time(NULL);
9d7d3f
+  now.tv_usec = 0;
9d7d3f
+  return now;
9d7d3f
+}
9d7d3f
+
9d7d3f
+static long tvdiff(struct timeval newer, struct timeval older)
9d7d3f
+{
9d7d3f
+  return (newer.tv_sec-older.tv_sec)*1000+
9d7d3f
+    (newer.tv_usec-older.tv_usec)/1000;
9d7d3f
+}
9d7d3f
+
9d7d3f
+int test(char *URL)
9d7d3f
+{
9d7d3f
+   CURL *curl;
9d7d3f
+   CURLM *mcurl;
9d7d3f
+   int still_running = 1;
9d7d3f
+   struct timeval mp_start;
9d7d3f
+   struct curl_slist* rcpt_list = NULL;
9d7d3f
+
9d7d3f
+   curl_global_init(CURL_GLOBAL_DEFAULT);
9d7d3f
+
9d7d3f
+   curl = curl_easy_init();
9d7d3f
+   if(!curl)
9d7d3f
+     return 1;
9d7d3f
+
9d7d3f
+   mcurl = curl_multi_init();
9d7d3f
+   if(!mcurl)
9d7d3f
+     return 2;
9d7d3f
+
9d7d3f
+   rcpt_list = curl_slist_append(rcpt_list, RECIPIENT);
9d7d3f
+   /* more addresses can be added here
9d7d3f
+      rcpt_list = curl_slist_append(rcpt_list, "<others@example.com>");
9d7d3f
+   */
9d7d3f
+
9d7d3f
+   curl_easy_setopt(curl, CURLOPT_URL, URL);
9d7d3f
+#if 0
9d7d3f
+   curl_easy_setopt(curl, CURLOPT_USERNAME, USERNAME);
9d7d3f
+   curl_easy_setopt(curl, CURLOPT_PASSWORD, PASSWORD);
9d7d3f
+#endif
9d7d3f
+   curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
9d7d3f
+   curl_easy_setopt(curl, CURLOPT_MAIL_FROM, MAILFROM);
9d7d3f
+   curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, rcpt_list);
9d7d3f
+   curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
9d7d3f
+   curl_multi_add_handle(mcurl, curl);
9d7d3f
+
9d7d3f
+   mp_start = tvnow();
9d7d3f
+
9d7d3f
+  /* we start some action by calling perform right away */
9d7d3f
+  curl_multi_perform(mcurl, &still_running);
9d7d3f
+
9d7d3f
+  while(still_running) {
9d7d3f
+    struct timeval timeout;
9d7d3f
+    int rc; /* select() return code */
9d7d3f
+
9d7d3f
+    fd_set fdread;
9d7d3f
+    fd_set fdwrite;
9d7d3f
+    fd_set fdexcep;
9d7d3f
+    int maxfd = -1;
9d7d3f
+
9d7d3f
+    long curl_timeo = -1;
9d7d3f
+
9d7d3f
+    FD_ZERO(&fdread);
9d7d3f
+    FD_ZERO(&fdwrite);
9d7d3f
+    FD_ZERO(&fdexcep);
9d7d3f
+
9d7d3f
+    /* set a suitable timeout to play around with */
9d7d3f
+    timeout.tv_sec = 1;
9d7d3f
+    timeout.tv_usec = 0;
9d7d3f
+
9d7d3f
+    curl_multi_timeout(mcurl, &curl_timeo);
9d7d3f
+    if(curl_timeo >= 0) {
9d7d3f
+      timeout.tv_sec = curl_timeo / 1000;
9d7d3f
+      if(timeout.tv_sec > 1)
9d7d3f
+        timeout.tv_sec = 1;
9d7d3f
+      else
9d7d3f
+        timeout.tv_usec = (curl_timeo % 1000) * 1000;
9d7d3f
+    }
9d7d3f
+
9d7d3f
+    /* get file descriptors from the transfers */
9d7d3f
+    curl_multi_fdset(mcurl, &fdread, &fdwrite, &fdexcep, &maxfd);
9d7d3f
+
9d7d3f
+    /* In a real-world program you OF COURSE check the return code of the
9d7d3f
+       function calls.  On success, the value of maxfd is guaranteed to be
9d7d3f
+       greater or equal than -1.  We call select(maxfd + 1, ...), specially in
9d7d3f
+       case of (maxfd == -1), we call select(0, ...), which is basically equal
9d7d3f
+       to sleep. */
9d7d3f
+
9d7d3f
+    rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
9d7d3f
+
9d7d3f
+    if (tvdiff(tvnow(), mp_start) > MULTI_PERFORM_HANG_TIMEOUT) {
9d7d3f
+      fprintf(stderr, "ABORTING TEST, since it seems "
9d7d3f
+              "that it would have run forever.\n");
9d7d3f
+      break;
9d7d3f
+    }
9d7d3f
+
9d7d3f
+    switch(rc) {
9d7d3f
+    case -1:
9d7d3f
+      /* select error */
9d7d3f
+      break;
9d7d3f
+    case 0: /* timeout */
9d7d3f
+    default: /* action */
9d7d3f
+      curl_multi_perform(mcurl, &still_running);
9d7d3f
+      break;
9d7d3f
+    }
9d7d3f
+  }
9d7d3f
+
9d7d3f
+  curl_slist_free_all(rcpt_list);
9d7d3f
+  curl_multi_remove_handle(mcurl, curl);
9d7d3f
+  curl_multi_cleanup(mcurl);
9d7d3f
+  curl_easy_cleanup(curl);
9d7d3f
+  curl_global_cleanup();
9d7d3f
+  return 0;
9d7d3f
+}
9d7d3f
+
9d7d3f
+
9d7d3f
-- 
9d7d3f
1.7.1
9d7d3f
9d7d3f
9d7d3f
From 55004df420d1e520d84fded41a4d16f36acee119 Mon Sep 17 00:00:00 2001
9d7d3f
From: Kamil Dudka <kdudka@redhat.com>
9d7d3f
Date: Mon, 9 Sep 2013 13:10:53 +0200
9d7d3f
Subject: [PATCH 2/2] url: handle abortion by read/write callbacks, too
9d7d3f
9d7d3f
Otherwise, the FTP protocol would unnecessarily hang 60 seconds if
9d7d3f
aborted in the CURLOPT_HEADERFUNCTION callback.
9d7d3f
9d7d3f
Reported by: Tomas Mlcoch
9d7d3f
Bug: https://bugzilla.redhat.com/1005686
9d7d3f
9d7d3f
[upstream commit c639d725a37c91fb49bb3a689cb2596fad3a0645]
9d7d3f
---
9d7d3f
 lib/url.c |    8 +++++++-
9d7d3f
 1 files changed, 7 insertions(+), 1 deletions(-)
9d7d3f
9d7d3f
diff --git a/lib/url.c b/lib/url.c
9d7d3f
index a6375a2..bddbd91 100644
9d7d3f
--- a/lib/url.c
9d7d3f
+++ b/lib/url.c
9d7d3f
@@ -5222,12 +5222,18 @@ CURLcode Curl_done(struct connectdata **connp,
9d7d3f
     conn->dns_entry = NULL;
9d7d3f
   }
9d7d3f
 
9d7d3f
-  if(status == CURLE_ABORTED_BY_CALLBACK)
9d7d3f
+  switch(status) {
9d7d3f
+  case CURLE_ABORTED_BY_CALLBACK:
9d7d3f
+  case CURLE_READ_ERROR:
9d7d3f
+  case CURLE_WRITE_ERROR:
9d7d3f
     /* When we're aborted due to a callback return code it basically have to
9d7d3f
        be counted as premature as there is trouble ahead if we don't. We have
9d7d3f
        many callbacks and protocols work differently, we could potentially do
9d7d3f
        this more fine-grained in the future. */
9d7d3f
     premature = TRUE;
9d7d3f
+  default:
9d7d3f
+    break;
9d7d3f
+  }
9d7d3f
 
9d7d3f
   /* this calls the protocol-specific function pointer previously set */
9d7d3f
   if(conn->handler->done)
9d7d3f
-- 
9d7d3f
1.7.1
9d7d3f