diff options
author | Daniel Stenberg <daniel@haxx.se> | 2012-12-11 23:31:45 +0100 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2012-12-11 23:31:45 +0100 |
commit | 50d7397ea54df79e403649d1e37d002eb52d268f (patch) | |
tree | 6b6eed95d3d4b69cd26e0b2377fa934d5ea99c09 /tests/libtest | |
parent | a3d6368c690b943e92082951e8c5fc3ef2d76c12 (diff) | |
parent | 4deb52831a071bc83cefb4871764281a5c32f902 (diff) | |
download | curl-multi-always.tar.gz |
Merge branch 'multi2' into multi-alwaysmulti-always
Diffstat (limited to 'tests/libtest')
92 files changed, 12643 insertions, 0 deletions
diff --git a/tests/libtest/.gitignore b/tests/libtest/.gitignore new file mode 100644 index 000000000..28e83c08d --- /dev/null +++ b/tests/libtest/.gitignore @@ -0,0 +1,5 @@ +chkhostname +lib5[0-9][0-9] +lib150[0-9] +libauthretry +libntlmconnect diff --git a/tests/libtest/CMakeLists.txt b/tests/libtest/CMakeLists.txt new file mode 100644 index 000000000..896686bd8 --- /dev/null +++ b/tests/libtest/CMakeLists.txt @@ -0,0 +1,121 @@ +set(TARGET_LABEL_PREFIX "Test ") + +function(SETUP_TEST TEST_NAME) # ARGN are the files in the test + add_executable( ${TEST_NAME} ${ARGN} ) + string(TOUPPER ${TEST_NAME} UPPER_TEST_NAME) + + include_directories( + ${CURL_SOURCE_DIR}/lib # To be able to reach "setup_once.h" + ${CURL_BINARY_DIR}/lib # To be able to reach "curl_config.h" + ${CURL_BINARY_DIR}/include # To be able to reach "curl/curlbuild.h" + ) + if(CURL_USE_ARES) + include_directories(${CARES_INCLUDE_DIR}) + endif() + setup_curl_dependencies(${TEST_NAME}) + target_link_libraries( ${TEST_NAME} libcurl ) + + set_target_properties(${TEST_NAME} + PROPERTIES COMPILE_DEFINITIONS ${UPPER_TEST_NAME}) + set_target_properties(${TEST_NAME} + PROPERTIES PROJECT_LABEL "${TARGET_LABEL_PREFIX}${TEST_NAME}") + + # Add the postfix to the executable since it is + # not added automatically as for modules and shared libraries + set_target_properties(${TEST_NAME} + PROPERTIES DEBUG_POSTFIX "${CMAKE_DEBUG_POSTFIX}") + + if(MSVC) + if(NOT BUILD_RELEASE_DEBUG_DIRS) + # Ugly workaround to remove the "/debug" or "/release" in each output + set_target_properties(${TEST_NAME} PROPERTIES PREFIX "../") + set_target_properties(${TEST_NAME} PROPERTIES IMPORT_PREFIX "../") + endif() + endif() + +endfunction() + + +transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") +include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake) + +foreach(TEST_NAME ${noinst_PROGRAMS}) + setup_test(${TEST_NAME} ${${TEST_NAME}_SOURCES}) +endforeach() + + +# # files used only in some libcurl test programs +# SET(TESTUTIL testutil.c testutil.h) + +# # these files are used in every single test program below +# SET(SUPPORTFILES first.c test.h) + +# # These are all libcurl test programs +# SET(noinst_PROGRAMS +# lib500 lib501 lib502 lib503 lib504 lib505 lib506 +# lib507 lib508 lib510 lib511 lib512 lib513 lib514 lib515 lib516 +# lib517 lib518 lib519 lib520 lib521 lib523 lib524 lib525 lib526 +# #lib527 +# #lib529 +# lib530 +# #lib532 +# lib533 lib536 lib537 lib540 lib541 lib542 lib543 +# lib544 +# #lib545 +# lib547 +# #lib548 +# lib549 lib552 lib553 lib554 lib555 lib556 +# lib539 lib557 +# lib560 +# ) + +# SET(noinst_PROGRAMS_USE_TESTUTIL +# lib502 lib503 lib504 +# lib507 +# lib525 lib526 lib527 +# lib529 +# lib530 +# lib532 +# lib533 lib536 +# lib555 +# ) + +# MACRO(ADD_TESTUTIL_IF_NECESSARY TEST_NAME) +# LIST(FIND noinst_PROGRAMS_USE_TESTUTIL ${TEST_NAME} USES_TESTUTIL) +# IF(NOT ${USES_TESTUTIL} EQUAL -1) +# LIST(APPEND SOURCE ${TESTUTIL}) # Need TestUtil +# ENDIF() +# ENDMACRO() + +# # General case +# FOREACH(TEST_NAME ${noinst_PROGRAMS}) +# SET(SOURCE "${TEST_NAME}.c" ${SUPPORTFILES}) +# ADD_TESTUTIL_IF_NECESSARY(${TEST_NAME}) +# SETUP_TEST(${TEST_NAME} ${SOURCE}) +# ENDFOREACH() + +# # Special cases +# SET(TEST_NAME lib527) +# SET(SOURCE "lib526.c" ${SUPPORTFILES}) +# ADD_TESTUTIL_IF_NECESSARY(${TEST_NAME}) +# SETUP_TEST(${TEST_NAME} ${SOURCE}) + +# SET(TEST_NAME lib529) +# SET(SOURCE "lib525.c" ${SUPPORTFILES}) +# ADD_TESTUTIL_IF_NECESSARY(${TEST_NAME}) +# SETUP_TEST(${TEST_NAME} ${SOURCE}) + +# SET(TEST_NAME lib532) +# SET(SOURCE "lib526.c" ${SUPPORTFILES}) +# ADD_TESTUTIL_IF_NECESSARY(${TEST_NAME}) +# SETUP_TEST(${TEST_NAME} ${SOURCE}) + +# SET(TEST_NAME lib545) +# SET(SOURCE "lib544.c" ${SUPPORTFILES}) +# ADD_TESTUTIL_IF_NECESSARY(${TEST_NAME}) +# SETUP_TEST(${TEST_NAME} ${SOURCE}) + +# SET(TEST_NAME lib548) +# SET(SOURCE "lib547.c" ${SUPPORTFILES}) +# ADD_TESTUTIL_IF_NECESSARY(${TEST_NAME}) +# SETUP_TEST(${TEST_NAME} ${SOURCE}) diff --git a/tests/libtest/Makefile.am b/tests/libtest/Makefile.am new file mode 100644 index 000000000..df13df111 --- /dev/null +++ b/tests/libtest/Makefile.am @@ -0,0 +1,108 @@ +#*************************************************************************** +# _ _ ____ _ +# 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. +# +########################################################################### +AUTOMAKE_OPTIONS = foreign nostdinc + +# Specify our include paths here, and do it relative to $(top_srcdir) and +# $(top_builddir), to ensure that these paths which belong to the library +# being currently built and tested are searched before the library which +# might possibly already be installed in the system. +# +# $(top_builddir)/include/curl for generated curlbuild.h included from curl.h +# $(top_builddir)/include for generated curlbuild.h included from lib/setup.h +# $(top_srcdir)/include is for libcurl's external include files +# $(top_builddir)/lib is for libcurl's generated lib/curl_config.h file +# $(top_srcdir)/lib is for libcurl's lib/setup.h and other "borrowed" files +# $(top_builddir)/ares is for in-tree c-ares's generated ares_build.h file +# $(top_srcdir)/ares is for in-tree c-ares's external include files + +if USE_EMBEDDED_ARES +AM_CPPFLAGS = -I$(top_builddir)/include/curl \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib \ + -I$(top_builddir)/ares \ + -I$(top_srcdir)/ares +else +AM_CPPFLAGS = -I$(top_builddir)/include/curl \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib +endif + +EXTRA_DIST = test75.pl test307.pl test610.pl test613.pl test1013.pl \ +test1022.pl Makefile.inc notexists.pl + +CFLAG_CURL_SYMBOL_HIDING = @CFLAG_CURL_SYMBOL_HIDING@ + +# Prevent LIBS from being used for all link targets +LIBS = $(BLANK_AT_MAKETIME) + +if USE_EXPLICIT_LIB_DEPS +SUPPORTFILES_LIBS = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@ +TESTUTIL_LIBS = $(top_builddir)/lib/libcurl.la @LIBCURL_LIBS@ +else +SUPPORTFILES_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_LIBS@ +TESTUTIL_LIBS = $(top_builddir)/lib/libcurl.la @CURL_NETWORK_AND_TIME_LIBS@ +endif + +# Dependencies (may need to be overriden) +LDADD = $(SUPPORTFILES_LIBS) +DEPENDENCIES = $(top_builddir)/lib/libcurl.la + +# Mostly for Windows build targets, when using static libcurl +if USE_CPPFLAG_CURL_STATICLIB +AM_CPPFLAGS += -DCURL_STATICLIB +endif + +# Makefile.inc provides the source defines (TESTUTIL, SUPPORTFILES, +# noinst_PROGRAMS, lib*_SOURCES, and lib*_CFLAGS) +include Makefile.inc + +# Preloading of libhostname allows host name overriding, +# this is used to make some tests machine independent. + +if BUILD_LIBHOSTNAME +noinst_LTLIBRARIES = libhostname.la +else +noinst_LTLIBRARIES = +endif + +if NO_UNDEFINED +# The -no-undefined flag is crucial to build fine on some platforms +UNDEF = -no-undefined +endif + +libhostname_la_SOURCES = sethostname.c sethostname.h + +libhostname_la_LIBADD = +libhostname_la_DEPENDENCIES = +libhostname_la_LDFLAGS = -module -avoid-version $(UNDEF) -rpath /nowhere + +if DOING_CURL_SYMBOL_HIDING +libhostname_la_CPPFLAGS = $(AM_CPPFLAGS) -DCURL_HIDDEN_SYMBOLS +libhostname_la_CFLAGS = $(AM_CFLAGS) $(CFLAG_CURL_SYMBOL_HIDING) +else +libhostname_la_CPPFLAGS = $(AM_CPPFLAGS) +libhostname_la_CFLAGS = $(AM_CFLAGS) +endif diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc new file mode 100644 index 000000000..c773d2b73 --- /dev/null +++ b/tests/libtest/Makefile.inc @@ -0,0 +1,224 @@ +# files used only in some libcurl test programs +TESTUTIL = testutil.c testutil.h + +# files used only in some libcurl test programs +TSTTRACE = testtrace.c testtrace.h + +# files used only in some libcurl test programs +WARNLESS = $(top_srcdir)/lib/warnless.c $(top_srcdir)/lib/warnless.h + +# these files are used in every single test program below +SUPPORTFILES = first.c test.h + +# These are all libcurl test programs +noinst_PROGRAMS = chkhostname \ + lib500 lib501 lib502 lib503 lib504 lib505 lib506 lib507 lib508 lib510 \ + lib511 lib512 lib513 lib514 lib515 lib516 lib517 lib518 lib519 lib520 \ + lib521 lib523 lib524 lib525 lib526 lib527 lib574 lib575 lib576 lib578 \ + lib579 lib529 lib530 lib532 lib533 lib536 lib537 lib540 lib541 lib542 \ + lib543 lib544 lib545 lib547 lib548 lib549 lib552 lib553 lib554 lib555 \ + lib556 lib539 lib557 lib560 lib562 lib564 lib565 lib566 lib567 lib568 \ + lib569 lib570 lib571 lib572 lib573 lib582 lib583 lib585 lib586 lib587 \ + lib590 lib591 lib597 lib598 lib599 libauthretry libntlmconnect \ + lib1500 lib1501 lib1502 + +chkhostname_SOURCES = chkhostname.c $(top_srcdir)/lib/curl_gethostname.c +chkhostname_LDADD = @CURL_NETWORK_LIBS@ +chkhostname_DEPENDENCIES = +chkhostname_CFLAGS = $(AM_CFLAGS) + +lib500_SOURCES = lib500.c $(SUPPORTFILES) $(TESTUTIL) $(TSTTRACE) +lib500_LDADD = $(TESTUTIL_LIBS) + +lib501_SOURCES = lib501.c $(SUPPORTFILES) + +lib502_SOURCES = lib502.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib502_LDADD = $(TESTUTIL_LIBS) + +lib503_SOURCES = lib503.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib503_LDADD = $(TESTUTIL_LIBS) + +lib504_SOURCES = lib504.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib504_LDADD = $(TESTUTIL_LIBS) + +lib505_SOURCES = lib505.c $(SUPPORTFILES) + +lib506_SOURCES = lib506.c $(SUPPORTFILES) + +lib507_SOURCES = lib507.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib507_LDADD = $(TESTUTIL_LIBS) + +lib508_SOURCES = lib508.c $(SUPPORTFILES) + +lib510_SOURCES = lib510.c $(SUPPORTFILES) + +lib511_SOURCES = lib511.c $(SUPPORTFILES) + +lib512_SOURCES = lib512.c $(SUPPORTFILES) + +lib513_SOURCES = lib513.c $(SUPPORTFILES) + +lib514_SOURCES = lib514.c $(SUPPORTFILES) + +lib515_SOURCES = lib515.c $(SUPPORTFILES) + +lib516_SOURCES = lib516.c $(SUPPORTFILES) + +lib517_SOURCES = lib517.c $(SUPPORTFILES) + +lib518_SOURCES = lib518.c $(SUPPORTFILES) $(WARNLESS) + +lib519_SOURCES = lib519.c $(SUPPORTFILES) + +lib520_SOURCES = lib520.c $(SUPPORTFILES) + +lib521_SOURCES = lib521.c $(SUPPORTFILES) + +lib523_SOURCES = lib523.c $(SUPPORTFILES) + +lib524_SOURCES = lib524.c $(SUPPORTFILES) + +lib525_SOURCES = lib525.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib525_LDADD = $(TESTUTIL_LIBS) + +lib526_SOURCES = lib526.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib526_LDADD = $(TESTUTIL_LIBS) +lib526_CPPFLAGS = $(AM_CPPFLAGS) -DLIB526 + +lib527_SOURCES = lib526.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib527_LDADD = $(TESTUTIL_LIBS) +lib527_CPPFLAGS = $(AM_CPPFLAGS) -DLIB527 + +lib529_SOURCES = lib525.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib529_LDADD = $(TESTUTIL_LIBS) +lib529_CPPFLAGS = $(AM_CPPFLAGS) -DLIB529 + +lib530_SOURCES = lib530.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib530_LDADD = $(TESTUTIL_LIBS) +lib530_CPPFLAGS = $(AM_CPPFLAGS) -DLIB530 + +lib532_SOURCES = lib526.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib532_LDADD = $(TESTUTIL_LIBS) +lib532_CPPFLAGS = $(AM_CPPFLAGS) -DLIB532 + +lib533_SOURCES = lib533.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib533_LDADD = $(TESTUTIL_LIBS) + +lib536_SOURCES = lib536.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib536_LDADD = $(TESTUTIL_LIBS) + +lib537_SOURCES = lib537.c $(SUPPORTFILES) $(WARNLESS) + +lib539_SOURCES = lib539.c $(SUPPORTFILES) + +lib540_SOURCES = lib540.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib540_LDADD = $(TESTUTIL_LIBS) + +lib541_SOURCES = lib541.c $(SUPPORTFILES) + +lib542_SOURCES = lib542.c $(SUPPORTFILES) + +lib543_SOURCES = lib543.c $(SUPPORTFILES) + +lib544_SOURCES = lib544.c $(SUPPORTFILES) + +lib545_SOURCES = lib544.c $(SUPPORTFILES) +lib545_CPPFLAGS = $(AM_CPPFLAGS) -DLIB545 + +lib547_SOURCES = lib547.c $(SUPPORTFILES) + +lib548_SOURCES = lib547.c $(SUPPORTFILES) +lib548_CPPFLAGS = $(AM_CPPFLAGS) -DLIB548 + +lib549_SOURCES = lib549.c $(SUPPORTFILES) + +lib555_SOURCES = lib555.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib555_LDADD = $(TESTUTIL_LIBS) + +lib552_SOURCES = lib552.c $(SUPPORTFILES) $(WARNLESS) + +lib553_SOURCES = lib553.c $(SUPPORTFILES) + +lib554_SOURCES = lib554.c $(SUPPORTFILES) + +lib556_SOURCES = lib556.c $(SUPPORTFILES) + +lib557_SOURCES = lib557.c $(SUPPORTFILES) + +lib560_SOURCES = lib560.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib560_LDADD = $(TESTUTIL_LIBS) + +lib574_SOURCES = lib574.c $(SUPPORTFILES) + +lib575_SOURCES = lib575.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib575_LDADD = $(TESTUTIL_LIBS) + +lib576_SOURCES = lib576.c $(SUPPORTFILES) + +lib562_SOURCES = lib562.c $(SUPPORTFILES) + +lib564_SOURCES = lib564.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib564_LDADD = $(TESTUTIL_LIBS) + +lib565_SOURCES = lib510.c $(SUPPORTFILES) +lib565_CPPFLAGS = $(AM_CPPFLAGS) -DLIB565 + +lib566_SOURCES = lib566.c $(SUPPORTFILES) + +lib567_SOURCES = lib567.c $(SUPPORTFILES) + +lib568_SOURCES = lib568.c $(SUPPORTFILES) + +lib569_SOURCES = lib569.c $(SUPPORTFILES) + +lib570_SOURCES = lib570.c $(SUPPORTFILES) + +lib571_SOURCES = lib571.c $(SUPPORTFILES) $(WARNLESS) + +lib572_SOURCES = lib572.c $(SUPPORTFILES) + +lib573_SOURCES = lib573.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) $(TSTTRACE) +lib573_LDADD = $(TESTUTIL_LIBS) + +lib578_SOURCES = lib578.c $(SUPPORTFILES) + +lib579_SOURCES = lib579.c $(SUPPORTFILES) + +lib582_SOURCES = lib582.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib582_LDADD = $(TESTUTIL_LIBS) + +lib583_SOURCES = lib583.c $(SUPPORTFILES) + +lib585_SOURCES = lib500.c $(SUPPORTFILES) $(TESTUTIL) $(TSTTRACE) +lib585_LDADD = $(TESTUTIL_LIBS) +lib585_CPPFLAGS = $(AM_CPPFLAGS) -DLIB585 + +lib586_SOURCES = lib586.c $(SUPPORTFILES) + +lib587_SOURCES = lib554.c $(SUPPORTFILES) +lib587_CPPFLAGS = $(AM_CPPFLAGS) -DLIB587 + +lib590_SOURCES = lib590.c $(SUPPORTFILES) + +lib591_SOURCES = lib591.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib591_LDADD = $(TESTUTIL_LIBS) + +lib597_SOURCES = lib597.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib597_LDADD = $(TESTUTIL_LIBS) + +lib598_SOURCES = lib598.c $(SUPPORTFILES) + +lib599_SOURCES = lib599.c $(SUPPORTFILES) + +lib1500_SOURCES = lib1500.c $(SUPPORTFILES) $(TESTUTIL) +lib1500_LDADD = $(TESTUTIL_LIBS) + +lib1501_SOURCES = lib1501.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib1501_LDADD = $(TESTUTIL_LIBS) + +lib1502_SOURCES = lib1502.c $(SUPPORTFILES) + +libauthretry_SOURCES = libauthretry.c $(SUPPORTFILES) + +libntlmconnect_SOURCES = libntlmconnect.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +libntlmconnect_LDADD = $(TESTUTIL_LIBS) diff --git a/tests/libtest/chkhostname.c b/tests/libtest/chkhostname.c new file mode 100644 index 000000000..a18c92e8f --- /dev/null +++ b/tests/libtest/chkhostname.c @@ -0,0 +1,47 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "setup.h" + +#include "curl_gethostname.h" + +#define HOSTNAME_MAX 1024 + +int main(int argc, char *argv[]) +{ + char buff[HOSTNAME_MAX]; + if (argc != 2) { + printf("Usage: %s EXPECTED_HOSTNAME\n", argv[0]); + return 1; + } + + if (Curl_gethostname(buff, HOSTNAME_MAX)) { + printf("Curl_gethostname() failed\n"); + return 1; + } + + /* compare the name returned by Curl_gethostname() with the expected one */ + if(strncmp(buff, argv[1], HOSTNAME_MAX)) { + printf("got unexpected host name back, LD_PRELOAD failed\n"); + return 1; + } + return 0; +} diff --git a/tests/libtest/first.c b/tests/libtest/first.c new file mode 100644 index 000000000..253acb21d --- /dev/null +++ b/tests/libtest/first.c @@ -0,0 +1,131 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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" + +#ifdef HAVE_LOCALE_H +#include <locale.h> /* for setlocale() */ +#endif + +#ifdef CURLDEBUG +# define MEMDEBUG_NODEFINES +# include "memdebug.h" +#endif + +int select_wrapper(int nfds, fd_set *rd, fd_set *wr, fd_set *exc, + struct timeval *tv) +{ + if(nfds < 0) { + SET_SOCKERRNO(EINVAL); + return -1; + } +#ifdef USE_WINSOCK + /* + * Winsock select() requires that at least one of the three fd_set + * pointers is not NULL and points to a non-empty fdset. IOW Winsock + * select() can not be used to sleep without a single fd_set. + */ + if(!nfds) { + Sleep(1000*tv->tv_sec + tv->tv_usec/1000); + return 0; + } +#endif + return select(nfds, rd, wr, exc, tv); +} + +char *libtest_arg2=NULL; +char *libtest_arg3=NULL; +int test_argc; +char **test_argv; + +struct timeval tv_test_start; /* for test timing */ + +#ifdef UNITTESTS +int unitfail; /* for unittests */ +#endif + +#ifdef CURLDEBUG +static void memory_tracking_init(void) +{ + char *env; + /* if CURL_MEMDEBUG is set, this starts memory tracking message logging */ + env = curl_getenv("CURL_MEMDEBUG"); + if(env) { + /* use the value as file name */ + char fname[CURL_MT_LOGFNAME_BUFSIZE]; + if(strlen(env) >= CURL_MT_LOGFNAME_BUFSIZE) + env[CURL_MT_LOGFNAME_BUFSIZE-1] = '\0'; + strcpy(fname, env); + curl_free(env); + curl_memdebug(fname); + /* this weird stuff here is to make curl_free() get called + before curl_memdebug() as otherwise memory tracking will + log a free() without an alloc! */ + } + /* if CURL_MEMLIMIT is set, this enables fail-on-alloc-number-N feature */ + env = curl_getenv("CURL_MEMLIMIT"); + if(env) { + char *endptr; + long num = strtol(env, &endptr, 10); + if((endptr != env) && (endptr == env + strlen(env)) && (num > 0)) + curl_memlimit(num); + curl_free(env); + } +} +#else +# define memory_tracking_init() Curl_nop_stmt +#endif + +int main(int argc, char **argv) +{ + char *URL; + + memory_tracking_init(); + + /* + * Setup proper locale from environment. This is needed to enable locale- + * specific behaviour by the C library in order to test for undesired side + * effects that could cause in libcurl. + */ +#ifdef HAVE_SETLOCALE + setlocale(LC_ALL, ""); +#endif + + if(argc< 2 ) { + fprintf(stderr, "Pass URL as argument please\n"); + return 1; + } + + test_argc = argc; + test_argv = argv; + + if(argc>2) + libtest_arg2=argv[2]; + + if(argc>3) + libtest_arg3=argv[3]; + + URL = argv[1]; /* provide this to the rest */ + + fprintf(stderr, "URL: %s\n", URL); + + return test(URL); +} diff --git a/tests/libtest/lib1500.c b/tests/libtest/lib1500.c new file mode 100644 index 000000000..784bdb2a2 --- /dev/null +++ b/tests/libtest/lib1500.c @@ -0,0 +1,95 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "testutil.h" +#include "warnless.h" +#include "memdebug.h" + +#define TEST_HANG_TIMEOUT 60 * 1000 + +int test(char *URL) +{ + CURL* curls = NULL; + CURLM* multi = NULL; + int still_running; + int i = -1; + int res = 0; + CURLMsg *msg; + + start_test_timing(); + + global_init(CURL_GLOBAL_ALL); + + multi_init(multi); + + easy_init(curls); + + easy_setopt(curls, CURLOPT_URL, URL); + easy_setopt(curls, CURLOPT_HEADER, 1L); + + multi_add_handle(multi, curls); + + multi_perform(multi, &still_running); + + abort_on_test_timeout(); + + while(still_running) { + int num; + res = curl_multi_wait(multi, NULL, 0, TEST_HANG_TIMEOUT, &num); + if (res != CURLM_OK) { + printf("curl_multi_wait() returned %d\n", res); + res = -1; + goto test_cleanup; + } + if (num != 1) { + printf("curl_multi_wait() returned on %d handle(s), expected 1\n", num); + res = -1; + goto test_cleanup; + } + + abort_on_test_timeout(); + + multi_perform(multi, &still_running); + + abort_on_test_timeout(); + } + + msg = curl_multi_info_read(multi, &still_running); + if(msg) + /* this should now contain a result code from the easy handle, + get it */ + i = msg->data.result; + +test_cleanup: + + /* undocumented cleanup sequence - type UA */ + + curl_multi_cleanup(multi); + curl_easy_cleanup(curls); + curl_global_cleanup(); + + if(res) + i = res; + + return i; /* return the final return code */ +} diff --git a/tests/libtest/lib1501.c b/tests/libtest/lib1501.c new file mode 100644 index 000000000..01a382e82 --- /dev/null +++ b/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"); + before = tutil_tvnow(); + + multi_perform(mhandle, &still_running); + + abort_on_test_timeout(); + + after = tutil_tvnow(); + 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; +} diff --git a/tests/libtest/lib1502.c b/tests/libtest/lib1502.c new file mode 100644 index 000000000..bb008f17c --- /dev/null +++ b/tests/libtest/lib1502.c @@ -0,0 +1,143 @@ +/*************************************************************************** + * _ _ ____ _ + * 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. + * + ***************************************************************************/ +/* + * Test case converted from bug report #3575448, identifying a memory leak in + * the CURLOPT_RESOLVE handling with the multi interface. + */ + +#include "test.h" + +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif + +#include <stdio.h> +#include <string.h> + +/* somewhat unix-specific */ +#include <sys/time.h> +#include <unistd.h> + +int test(char *URL) +{ + CURL *ehandle; + CURLM *multi_handle; + char redirect[160]; + CURLcode result = CURLE_NOT_BUILT_IN; + int still_running; /* keep number of running handles */ + + CURLMsg *msg; /* for picking up messages with the transfer status */ + int msgs_left; /* how many messages are left */ + + /* DNS cache injection */ + struct curl_slist *dns_cache_list; + + sprintf(redirect, "google.com:%s:%s", libtest_arg2, libtest_arg3); + + fprintf(stderr, "Redirect: %s\n", redirect); + + dns_cache_list = curl_slist_append(NULL, redirect); + + /* Allocate one CURL handle per transfer */ + ehandle = curl_easy_init(); + + /* set the options (I left out a few, you'll get the point anyway) */ + curl_easy_setopt(ehandle, CURLOPT_URL, URL); + curl_easy_setopt(ehandle, CURLOPT_HEADER, 1L); + + curl_easy_setopt(ehandle, CURLOPT_RESOLVE, dns_cache_list); + + /* init a multi stack */ + multi_handle = curl_multi_init(); + + /* add the individual transfers */ + curl_multi_add_handle(multi_handle, ehandle); + + /* we start some action by calling perform right away */ + curl_multi_perform(multi_handle, &still_running); + + do { + struct timeval timeout; + int rc; /* select() return code */ + + fd_set fdread; + fd_set fdwrite; + fd_set fdexcep; + int maxfd = -1; + + long curl_timeo = -1; + + FD_ZERO(&fdread); + FD_ZERO(&fdwrite); + FD_ZERO(&fdexcep); + + /* set a suitable timeout to play around with */ + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + curl_multi_timeout(multi_handle, &curl_timeo); + if(curl_timeo >= 0) { + int itimeout = (curl_timeo > (long)INT_MAX) ? INT_MAX : (int)curl_timeo; + timeout.tv_sec = itimeout / 1000; + if(timeout.tv_sec > 1) + timeout.tv_sec = 1; + else + timeout.tv_usec = (itimeout % 1000) * 1000; + } + + /* get file descriptors from the transfers */ + curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd); + + /* In a real-world program you OF COURSE check the return code of the + function calls. On success, the value of maxfd is guaranteed to be + greater or equal than -1. We call select(maxfd + 1, ...), specially in + case of (maxfd == -1), we call select(0, ...), which is basically equal + to sleep. */ + + rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout); + + switch(rc) { + case -1: + /* select error */ + break; + case 0: /* timeout */ + default: /* action */ + curl_multi_perform(multi_handle, &still_running); + break; + } + } while(still_running); + + /* See how the transfers went */ + while ((msg = curl_multi_info_read(multi_handle, &msgs_left))) { + if (msg->msg == CURLMSG_DONE) + result = msg->data.result; + } + + curl_multi_cleanup(multi_handle); + + /* Free the CURL handles */ + curl_easy_cleanup(ehandle); + + curl_slist_free_all(dns_cache_list); + + return (int)result; +} diff --git a/tests/libtest/lib500.c b/tests/libtest/lib500.c new file mode 100644 index 000000000..dda1d7f42 --- /dev/null +++ b/tests/libtest/lib500.c @@ -0,0 +1,141 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "testtrace.h" +#include "memdebug.h" + +#ifdef LIB585 + +static int counter; + +static curl_socket_t tst_opensocket(void *clientp, + curlsocktype purpose, + struct curl_sockaddr *addr) +{ + (void)clientp; + (void)purpose; + printf("[OPEN] counter: %d\n", ++counter); + return socket(addr->family, addr->socktype, addr->protocol); +} + +static int tst_closesocket(void *clientp, curl_socket_t sock) +{ + (void)clientp; + printf("[CLOSE] counter: %d\n", counter--); + return sclose(sock); +} + +static void setupcallbacks(CURL *curl) +{ + curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, tst_opensocket); + curl_easy_setopt(curl, CURLOPT_CLOSESOCKETFUNCTION, tst_closesocket); + counter = 0; +} + +#else +#define setupcallbacks(x) Curl_nop_stmt +#endif + + +int test(char *URL) +{ + CURLcode res; + CURL *curl; + char *ipstr=NULL; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_HEADER, 1L); + + libtest_debug_config.nohex = 1; + libtest_debug_config.tracetime = 1; + test_setopt(curl, CURLOPT_DEBUGDATA, &libtest_debug_config); + test_setopt(curl, CURLOPT_DEBUGFUNCTION, libtest_debug_cb); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + if(libtest_arg3 && !strcmp(libtest_arg3, "activeftp")) + test_setopt(curl, CURLOPT_FTPPORT, "-"); + + setupcallbacks(curl); + + res = curl_easy_perform(curl); + + if(!res) { + FILE *moo; + res = curl_easy_getinfo(curl, CURLINFO_PRIMARY_IP, &ipstr); + moo = fopen(libtest_arg2, "wb"); + if(moo) { + double time_namelookup; + double time_connect; + double time_pretransfer; + double time_starttransfer; + double time_total; + fprintf(moo, "IP: %s\n", ipstr); + curl_easy_getinfo(curl, CURLINFO_NAMELOOKUP_TIME, &time_namelookup); + curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME, &time_connect); + curl_easy_getinfo(curl, CURLINFO_PRETRANSFER_TIME, &time_pretransfer); + curl_easy_getinfo(curl, CURLINFO_STARTTRANSFER_TIME, + &time_starttransfer); + curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &time_total); + + /* since the timing will always vary we only compare relative differences + between these 5 times */ + if(time_namelookup >= time_connect) { + fprintf(moo, "namelookup vs connect: %f %f\n", + time_namelookup, time_connect); + } + if(time_connect >= time_pretransfer) { + fprintf(moo, "connect vs pretransfer: %f %f\n", + time_connect, time_pretransfer); + } + if(time_pretransfer >= time_starttransfer) { + fprintf(moo, "pretransfer vs starttransfer: %f %f\n", + time_pretransfer, time_starttransfer); + } + if(time_starttransfer >= time_total) { + fprintf(moo, "starttransfer vs total: %f %f\n", + time_starttransfer, time_total); + } + + fclose(moo); + } + } + +test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} + diff --git a/tests/libtest/lib501.c b/tests/libtest/lib501.c new file mode 100644 index 000000000..26275f977 --- /dev/null +++ b/tests/libtest/lib501.c @@ -0,0 +1,55 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +int test(char *URL) +{ + CURLcode res; + CURL *curl; + + (void)URL; /* we don't use this */ + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_HEADER, 1L); + + res = curl_easy_perform(curl); + +test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} + diff --git a/tests/libtest/lib502.c b/tests/libtest/lib502.c new file mode 100644 index 000000000..554583ae2 --- /dev/null +++ b/tests/libtest/lib502.c @@ -0,0 +1,92 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "testutil.h" +#include "warnless.h" +#include "memdebug.h" + +#define TEST_HANG_TIMEOUT 60 * 1000 + +/* + * Get a single URL without select(). + */ + +int test(char *URL) +{ + CURL *c = NULL; + CURLM *m = NULL; + int res = 0; + int running; + + start_test_timing(); + + global_init(CURL_GLOBAL_ALL); + + easy_init(c); + + easy_setopt(c, CURLOPT_URL, URL); + + multi_init(m); + + multi_add_handle(m, c); + + for(;;) { + struct timeval timeout; + fd_set fdread, fdwrite, fdexcep; + int maxfd = -99; + + timeout.tv_sec = 0; + timeout.tv_usec = 100000L; /* 100 ms */ + + multi_perform(m, &running); + + abort_on_test_timeout(); + + if(!running) + break; /* done */ + + FD_ZERO(&fdread); + FD_ZERO(&fdwrite); + FD_ZERO(&fdexcep); + + multi_fdset(m, &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(); + } + +test_cleanup: + + /* proper cleanup sequence - type PA */ + + curl_multi_remove_handle(m, c); + curl_multi_cleanup(m); + curl_easy_cleanup(c); + curl_global_cleanup(); + + return res; +} + diff --git a/tests/libtest/lib503.c b/tests/libtest/lib503.c new file mode 100644 index 000000000..50277f7d3 --- /dev/null +++ b/tests/libtest/lib503.c @@ -0,0 +1,102 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "testutil.h" +#include "warnless.h" +#include "memdebug.h" + +#define TEST_HANG_TIMEOUT 60 * 1000 + +/* + * Source code in here hugely as reported in bug report 651460 by + * Christopher R. Palmer. + * + * Use multi interface to get HTTPS document over proxy, and provide + * auth info. + */ + +int test(char *URL) +{ + CURL *c = NULL; + CURLM *m = NULL; + int res = 0; + int running; + + start_test_timing(); + + global_init(CURL_GLOBAL_ALL); + + easy_init(c); + + easy_setopt(c, CURLOPT_PROXY, libtest_arg2); /* set in first.c */ + easy_setopt(c, CURLOPT_URL, URL); + easy_setopt(c, CURLOPT_USERPWD, "test:ing"); + easy_setopt(c, CURLOPT_PROXYUSERPWD, "test:ing"); + easy_setopt(c, CURLOPT_HTTPPROXYTUNNEL, 1L); + easy_setopt(c, CURLOPT_HEADER, 1L); + easy_setopt(c, CURLOPT_VERBOSE, 1L); + + multi_init(m); + + multi_add_handle(m, c); + + for(;;) { + struct timeval interval; + fd_set rd, wr, exc; + int maxfd = -99; + + interval.tv_sec = 1; + interval.tv_usec = 0; + + multi_perform(m, &running); + + abort_on_test_timeout(); + + if(!running) + break; /* done */ + + FD_ZERO(&rd); + FD_ZERO(&wr); + FD_ZERO(&exc); + + multi_fdset(m, &rd, &wr, &exc, &maxfd); + + /* At this point, maxfd is guaranteed to be greater or equal than -1. */ + + select_test(maxfd+1, &rd, &wr, &exc, &interval); + + abort_on_test_timeout(); + } + +test_cleanup: + + /* proper cleanup sequence - type PA */ + + curl_multi_remove_handle(m, c); + curl_multi_cleanup(m); + curl_easy_cleanup(c); + curl_global_cleanup(); + + return res; +} + diff --git a/tests/libtest/lib504.c b/tests/libtest/lib504.c new file mode 100644 index 000000000..358fc98dc --- /dev/null +++ b/tests/libtest/lib504.c @@ -0,0 +1,114 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "testutil.h" +#include "warnless.h" +#include "memdebug.h" + +#define TEST_HANG_TIMEOUT 60 * 1000 + +/* + * Source code in here hugely as reported in bug report 651464 by + * Christopher R. Palmer. + * + * Use multi interface to get document over proxy with bad port number. + * This caused the interface to "hang" in libcurl 7.10.2. + */ +int test(char *URL) +{ + CURL *c = NULL; + int res = 0; + CURLM *m = NULL; + fd_set rd, wr, exc; + int running; + + start_test_timing(); + + global_init(CURL_GLOBAL_ALL); + + easy_init(c); + + /* The point here is that there must not be anything running on the given + proxy port */ + if (libtest_arg2) + easy_setopt(c, CURLOPT_PROXY, libtest_arg2); + easy_setopt(c, CURLOPT_URL, URL); + easy_setopt(c, CURLOPT_VERBOSE, 1L); + + multi_init(m); + + multi_add_handle(m, c); + + for(;;) { + struct timeval interval; + int maxfd = -99; + + interval.tv_sec = 1; + interval.tv_usec = 0; + + fprintf(stderr, "curl_multi_perform()\n"); + + multi_perform(m, &running); + + abort_on_test_timeout(); + + if(!running) { + /* This is where this code is expected to reach */ + int numleft; + CURLMsg *msg = curl_multi_info_read(m, &numleft); + fprintf(stderr, "Expected: not running\n"); + if(msg && !numleft) + res = TEST_ERR_SUCCESS; /* this is where we should be */ + else + res = TEST_ERR_FAILURE; /* not correct */ + break; /* done */ + } + fprintf(stderr, "running == %d\n", running); + + FD_ZERO(&rd); + FD_ZERO(&wr); + FD_ZERO(&exc); + + fprintf(stderr, "curl_multi_fdset()\n"); + + multi_fdset(m, &rd, &wr, &exc, &maxfd); + + /* At this point, maxfd is guaranteed to be greater or equal than -1. */ + + select_test(maxfd+1, &rd, &wr, &exc, &interval); + + abort_on_test_timeout(); + } + +test_cleanup: + + /* proper cleanup sequence - type PA */ + + curl_multi_remove_handle(m, c); + curl_multi_cleanup(m); + curl_easy_cleanup(c); + curl_global_cleanup(); + + return res; +} + diff --git a/tests/libtest/lib505.c b/tests/libtest/lib505.c new file mode 100644 index 000000000..394131ebe --- /dev/null +++ b/tests/libtest/lib505.c @@ -0,0 +1,157 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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" + +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif + +#include "memdebug.h" + +/* + * This example shows an FTP upload, with a rename of the file just after + * a successful upload. + * + * Example based on source code provided by Erick Nuwendam. Thanks! + */ + +int test(char *URL) +{ + CURL *curl; + CURLcode res = CURLE_OK; + FILE *hd_src ; + int hd ; + struct_stat file_info; + struct curl_slist *hl; + int error; + + struct curl_slist *headerlist=NULL; + const char *buf_1 = "RNFR 505"; + const char *buf_2 = "RNTO 505-forreal"; + + if (!libtest_arg2) { + fprintf(stderr, "Usage: <url> <file-to-upload>\n"); + return -1; + } + + hd_src = fopen(libtest_arg2, "rb"); + if(NULL == hd_src) { + error = ERRNO; + fprintf(stderr, "fopen() failed with error: %d %s\n", + error, strerror(error)); + fprintf(stderr, "Error opening file: %s\n", libtest_arg2); + return -2; /* if this happens things are major weird */ + } + + /* get the file size of the local file */ + hd = fstat(fileno(hd_src), &file_info); + if(hd == -1) { + /* can't open file, bail out */ + error = ERRNO; + fprintf(stderr, "fstat() failed with error: %d %s\n", + error, strerror(error)); + fprintf(stderr, "ERROR: cannot open file %s\n", libtest_arg2); + fclose(hd_src); + return -1; + } + + if(! file_info.st_size) { + fprintf(stderr, "ERROR: file %s has zero size!\n", libtest_arg2); + fclose(hd_src); + return -4; + } + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + fclose(hd_src); + return TEST_ERR_MAJOR_BAD; + } + + /* get a curl handle */ + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + fclose(hd_src); + return TEST_ERR_MAJOR_BAD; + } + + /* build a list of commands to pass to libcurl */ + + if ((hl = curl_slist_append(headerlist, buf_1)) == NULL) { + fprintf(stderr, "curl_slist_append() failed\n"); + curl_easy_cleanup(curl); + curl_global_cleanup(); + fclose(hd_src); + return TEST_ERR_MAJOR_BAD; + } + if ((headerlist = curl_slist_append(hl, buf_2)) == NULL) { + fprintf(stderr, "curl_slist_append() failed\n"); + curl_slist_free_all(hl); + curl_easy_cleanup(curl); + curl_global_cleanup(); + fclose(hd_src); + return TEST_ERR_MAJOR_BAD; + } + headerlist = hl; + + /* enable uploading */ + test_setopt(curl, CURLOPT_UPLOAD, 1L); + + /* enable verbose */ + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + /* specify target */ + test_setopt(curl,CURLOPT_URL, URL); + + /* pass in that last of FTP commands to run after the transfer */ + test_setopt(curl, CURLOPT_POSTQUOTE, headerlist); + + /* now specify which file to upload */ + test_setopt(curl, CURLOPT_INFILE, hd_src); + + /* and give the size of the upload (optional) */ + test_setopt(curl, CURLOPT_INFILESIZE_LARGE, + (curl_off_t)file_info.st_size); + + /* Now run off and do what you've been told! */ + res = curl_easy_perform(curl); + +test_cleanup: + + /* clean up the FTP commands list */ + curl_slist_free_all(headerlist); + + /* close the local file */ + fclose(hd_src); + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib506.c b/tests/libtest/lib506.c new file mode 100644 index 000000000..4477eaa50 --- /dev/null +++ b/tests/libtest/lib506.c @@ -0,0 +1,277 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 <curl/mprintf.h> + +#include "memdebug.h" + +static const char *HOSTHEADER = "Host: www.host.foo.com"; +static const char *JAR = "log/jar506"; +#define THREADS 2 + +/* struct containing data of a thread */ +struct Tdata { + CURLSH *share; + char *url; +}; + +struct userdata { + char *text; + int counter; +}; + +/* lock callback */ +static void my_lock(CURL *handle, curl_lock_data data, curl_lock_access laccess, + void *useptr ) +{ + const char *what; + struct userdata *user = (struct userdata *)useptr; + + (void)handle; + (void)laccess; + + switch ( data ) { + case CURL_LOCK_DATA_SHARE: + what = "share"; + break; + case CURL_LOCK_DATA_DNS: + what = "dns"; + break; + case CURL_LOCK_DATA_COOKIE: + what = "cookie"; + break; + default: + fprintf(stderr, "lock: no such data: %d\n", (int)data); + return; + } + printf("lock: %-6s [%s]: %d\n", what, user->text, user->counter); + user->counter++; +} + +/* unlock callback */ +static void my_unlock(CURL *handle, curl_lock_data data, void *useptr ) +{ + const char *what; + struct userdata *user = (struct userdata *)useptr; + (void)handle; + switch ( data ) { + case CURL_LOCK_DATA_SHARE: + what = "share"; + break; + case CURL_LOCK_DATA_DNS: + what = "dns"; + break; + case CURL_LOCK_DATA_COOKIE: + what = "cookie"; + break; + default: + fprintf(stderr, "unlock: no such data: %d\n", (int)data); + return; + } + printf("unlock: %-6s [%s]: %d\n", what, user->text, user->counter); + user->counter++; +} + + +/* build host entry */ +static struct curl_slist *sethost(struct curl_slist *headers) +{ + (void)headers; + return curl_slist_append(NULL, HOSTHEADER ); +} + + +/* the dummy thread function */ +static void *fire(void *ptr) +{ + CURLcode code; + struct curl_slist *headers; + struct Tdata *tdata = (struct Tdata*)ptr; + CURL *curl; + int i=0; + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + return NULL; + } + + headers = sethost(NULL); + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl, CURLOPT_URL, tdata->url); + printf( "CURLOPT_SHARE\n" ); + curl_easy_setopt(curl, CURLOPT_SHARE, tdata->share); + + printf( "PERFORM\n" ); + code = curl_easy_perform(curl); + if( code != CURLE_OK ) { + fprintf(stderr, "perform url '%s' repeat %d failed, curlcode %d\n", + tdata->url, i, (int)code); + } + + printf( "CLEANUP\n" ); + curl_easy_cleanup(curl); + curl_slist_free_all(headers); + + return NULL; +} + + +/* build request url */ +static char *suburl(const char *base, int i) +{ + return curl_maprintf("%s%.4d", base, i); +} + + +/* test function */ +int test(char *URL) +{ + int res; + CURLSHcode scode = CURLSHE_OK; + char *url; + struct Tdata tdata; + CURL *curl; + CURLSH *share; + struct curl_slist *headers; + int i; + struct userdata user; + + user.text = (char *)"Pigs in space"; + user.counter = 0; + + printf( "GLOBAL_INIT\n" ); + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + /* prepare share */ + printf( "SHARE_INIT\n" ); + if ((share = curl_share_init()) == NULL) { + fprintf(stderr, "curl_share_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + if ( CURLSHE_OK == scode ) { + printf( "CURLSHOPT_LOCKFUNC\n" ); + scode = curl_share_setopt( share, CURLSHOPT_LOCKFUNC, my_lock); + } + if ( CURLSHE_OK == scode ) { + printf( "CURLSHOPT_UNLOCKFUNC\n" ); + scode = curl_share_setopt( share, CURLSHOPT_UNLOCKFUNC, my_unlock); + } + if ( CURLSHE_OK == scode ) { + printf( "CURLSHOPT_USERDATA\n" ); + scode = curl_share_setopt( share, CURLSHOPT_USERDATA, &user); + } + if ( CURLSHE_OK == scode ) { + printf( "CURL_LOCK_DATA_COOKIE\n" ); + scode = curl_share_setopt( share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE); + } + if ( CURLSHE_OK == scode ) { + printf( "CURL_LOCK_DATA_DNS\n" ); + scode = curl_share_setopt( share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS); + } + + if ( CURLSHE_OK != scode ) { + fprintf(stderr, "curl_share_setopt() failed\n"); + curl_share_cleanup(share); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + + res = 0; + + /* start treads */ + for (i=1; i<=THREADS; i++ ) { + + /* set thread data */ + tdata.url = suburl( URL, i ); /* must be curl_free()d */ + tdata.share = share; + + /* simulate thread, direct call of "thread" function */ + printf( "*** run %d\n",i ); + fire( &tdata ); + + curl_free( tdata.url ); + + } + + + /* fetch a another one and save cookies */ + printf( "*** run %d\n", i ); + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_share_cleanup(share); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + url = suburl( URL, i ); + headers = sethost( NULL ); + test_setopt( curl, CURLOPT_HTTPHEADER, headers ); + test_setopt( curl, CURLOPT_URL, url ); + printf( "CURLOPT_SHARE\n" ); + test_setopt( curl, CURLOPT_SHARE, share ); + printf( "CURLOPT_COOKIEJAR\n" ); + test_setopt( curl, CURLOPT_COOKIEJAR, JAR ); + + printf( "PERFORM\n" ); + curl_easy_perform( curl ); + + /* try to free share, expect to fail because share is in use*/ + printf( "try SHARE_CLEANUP...\n" ); + scode = curl_share_cleanup( share ); + if ( scode==CURLSHE_OK ) + { + fprintf(stderr, "curl_share_cleanup succeed but error expected\n"); + share = NULL; + } else { + printf( "SHARE_CLEANUP failed, correct\n" ); + } + +test_cleanup: + + /* clean up last handle */ + printf( "CLEANUP\n" ); + curl_easy_cleanup( curl ); + curl_slist_free_all( headers ); + + curl_free(url); + + /* free share */ + printf( "SHARE_CLEANUP\n" ); + scode = curl_share_cleanup( share ); + if ( scode!=CURLSHE_OK ) + fprintf(stderr, "curl_share_cleanup failed, code errno %d\n", + (int)scode); + + printf( "GLOBAL_CLEANUP\n" ); + curl_global_cleanup(); + + return res; +} + diff --git a/tests/libtest/lib507.c b/tests/libtest/lib507.c new file mode 100644 index 000000000..87c21defb --- /dev/null +++ b/tests/libtest/lib507.c @@ -0,0 +1,100 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "testutil.h" +#include "warnless.h" +#include "memdebug.h" + +#define TEST_HANG_TIMEOUT 60 * 1000 + +int test(char *URL) +{ + CURL* curls = NULL; + CURLM* multi = NULL; + int still_running; + int i = -1; + int res = 0; + CURLMsg *msg; + + start_test_timing(); + + global_init(CURL_GLOBAL_ALL); + + multi_init(multi); + + easy_init(curls); + + easy_setopt(curls, CURLOPT_URL, URL); + easy_setopt(curls, CURLOPT_HEADER, 1L); + + multi_add_handle(multi, curls); + + multi_perform(multi, &still_running); + + abort_on_test_timeout(); + + while(still_running) { + struct timeval timeout; + fd_set fdread; + fd_set fdwrite; + fd_set fdexcep; + int maxfd = -99; + + FD_ZERO(&fdread); + FD_ZERO(&fdwrite); + FD_ZERO(&fdexcep); + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + multi_fdset(multi, &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(); + + multi_perform(multi, &still_running); + + abort_on_test_timeout(); + } + + msg = curl_multi_info_read(multi, &still_running); + if(msg) + /* this should now contain a result code from the easy handle, + get it */ + i = msg->data.result; + +test_cleanup: + + /* undocumented cleanup sequence - type UA */ + + curl_multi_cleanup(multi); + curl_easy_cleanup(curls); + curl_global_cleanup(); + + if(res) + i = res; + + return i; /* return the final return code */ +} diff --git a/tests/libtest/lib508.c b/tests/libtest/lib508.c new file mode 100644 index 000000000..1aca064e9 --- /dev/null +++ b/tests/libtest/lib508.c @@ -0,0 +1,107 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +static char data[]="this is what we post to the silly web server\n"; + +struct WriteThis { + char *readptr; + size_t sizeleft; +}; + +static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp) +{ + struct WriteThis *pooh = (struct WriteThis *)userp; + + if(size*nmemb < 1) + return 0; + + if(pooh->sizeleft) { + *(char *)ptr = pooh->readptr[0]; /* copy one single byte */ + pooh->readptr++; /* advance pointer */ + pooh->sizeleft--; /* less data left */ + return 1; /* we return 1 byte at a time! */ + } + + return 0; /* no more data left to deliver */ +} + +int test(char *URL) +{ + CURL *curl; + CURLcode res=CURLE_OK; + + struct WriteThis pooh; + + pooh.readptr = data; + pooh.sizeleft = strlen(data); + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + /* First set the URL that is about to receive our POST. */ + test_setopt(curl, CURLOPT_URL, URL); + + /* Now specify we want to POST data */ + test_setopt(curl, CURLOPT_POST, 1L); + +#ifdef CURL_DOES_CONVERSIONS + /* Convert the POST data to ASCII */ + test_setopt(curl, CURLOPT_TRANSFERTEXT, 1L); +#endif + + /* Set the expected POST size */ + test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)pooh.sizeleft); + + /* we want to use our own read function */ + test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + + /* pointer to pass to our read function */ + test_setopt(curl, CURLOPT_INFILE, &pooh); + + /* get verbose debug output please */ + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + /* include headers in the output */ + test_setopt(curl, CURLOPT_HEADER, 1L); + + /* Perform the request, res will get the return code */ + res = curl_easy_perform(curl); + +test_cleanup: + + /* always cleanup */ + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib510.c b/tests/libtest/lib510.c new file mode 100644 index 000000000..8278631c1 --- /dev/null +++ b/tests/libtest/lib510.c @@ -0,0 +1,130 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "memdebug.h" + +static const char *post[]={ + "one", + "two", + "three", + "and a final longer crap: four", + NULL +}; + + +struct WriteThis { + int counter; +}; + +static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp) +{ + struct WriteThis *pooh = (struct WriteThis *)userp; + const char *data; + + if(size*nmemb < 1) + return 0; + + data = post[pooh->counter]; + + if(data) { + size_t len = strlen(data); + memcpy(ptr, data, len); + pooh->counter++; /* advance pointer */ + return len; + } + return 0; /* no more data left to deliver */ +} + +int test(char *URL) +{ + CURL *curl; + CURLcode res=CURLE_OK; + struct curl_slist *slist = NULL; + struct WriteThis pooh; + pooh.counter = 0; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + slist = curl_slist_append(slist, "Transfer-Encoding: chunked"); + if (slist == NULL) { + fprintf(stderr, "curl_slist_append() failed\n"); + curl_easy_cleanup(curl); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + /* First set the URL that is about to receive our POST. */ + test_setopt(curl, CURLOPT_URL, URL); + + /* Now specify we want to POST data */ + test_setopt(curl, CURLOPT_POST, 1L); + +#ifdef CURL_DOES_CONVERSIONS + /* Convert the POST data to ASCII */ + test_setopt(curl, CURLOPT_TRANSFERTEXT, 1L); +#endif + + /* we want to use our own read function */ + test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + + /* pointer to pass to our read function */ + test_setopt(curl, CURLOPT_INFILE, &pooh); + + /* get verbose debug output please */ + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + /* include headers in the output */ + test_setopt(curl, CURLOPT_HEADER, 1L); + + /* enforce chunked transfer by setting the header */ + test_setopt(curl, CURLOPT_HTTPHEADER, slist); + +#ifdef LIB565 + test_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_DIGEST); + test_setopt(curl, CURLOPT_USERPWD, "foo:bar"); +#endif + + /* Perform the request, res will get the return code */ + res = curl_easy_perform(curl); + +test_cleanup: + + /* clean up the headers list */ + if(slist) + curl_slist_free_all(slist); + + /* always cleanup */ + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib511.c b/tests/libtest/lib511.c new file mode 100644 index 000000000..6be2d2f76 --- /dev/null +++ b/tests/libtest/lib511.c @@ -0,0 +1,55 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +int test(char *URL) +{ + CURLcode res; + CURL *curl; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_FILETIME, 1L); + test_setopt(curl, CURLOPT_NOBODY, 1L); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + res = curl_easy_perform(curl); + +test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} diff --git a/tests/libtest/lib512.c b/tests/libtest/lib512.c new file mode 100644 index 000000000..19da18b4f --- /dev/null +++ b/tests/libtest/lib512.c @@ -0,0 +1,77 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +/* Test case code based on source in a bug report filed by James Bursa on + 28 Apr 2004 */ + +int test(char *URL) +{ + CURLcode code; + CURL *curl; + CURL *curl2; + int rc = 99; + + code = curl_global_init(CURL_GLOBAL_ALL); + if(code == CURLE_OK) { + + curl = curl_easy_init(); + if(curl) { + + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(curl, CURLOPT_HEADER, 1L); + + curl2 = curl_easy_duphandle(curl); + if(curl2) { + + code = curl_easy_setopt(curl2, CURLOPT_URL, URL); + if(code == CURLE_OK) { + + code = curl_easy_perform(curl2); + if(code == CURLE_OK) + rc = 0; + else + rc = 1; + } + else + rc = 2; + + curl_easy_cleanup(curl2); + } + else + rc = 3; + + curl_easy_cleanup(curl); + } + else + rc = 4; + + curl_global_cleanup(); + } + else + rc = 5; + + return rc; +} + diff --git a/tests/libtest/lib513.c b/tests/libtest/lib513.c new file mode 100644 index 000000000..c013ac258 --- /dev/null +++ b/tests/libtest/lib513.c @@ -0,0 +1,82 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp) +{ + (void)ptr; + (void)size; + (void)nmemb; + (void)userp; + return CURL_READFUNC_ABORT; +} + +int test(char *URL) +{ + CURL *curl; + CURLcode res=CURLE_OK; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + /* First set the URL that is about to receive our POST. */ + test_setopt(curl, CURLOPT_URL, URL); + + /* Now specify we want to POST data */ + test_setopt(curl, CURLOPT_POST, 1L); + + /* Set the expected POST size */ + test_setopt(curl, CURLOPT_POSTFIELDSIZE, 1L); + + /* we want to use our own read function */ + test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + + /* pointer to pass to our read function */ + test_setopt(curl, CURLOPT_INFILE, NULL); + + /* get verbose debug output please */ + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + /* include headers in the output */ + test_setopt(curl, CURLOPT_HEADER, 1L); + + /* Perform the request, res will get the return code */ + res = curl_easy_perform(curl); + +test_cleanup: + + /* always cleanup */ + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} diff --git a/tests/libtest/lib514.c b/tests/libtest/lib514.c new file mode 100644 index 000000000..953e90dff --- /dev/null +++ b/tests/libtest/lib514.c @@ -0,0 +1,78 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +int test(char *URL) +{ + CURL *curl; + CURLcode res=CURLE_OK; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + /* First set the URL that is about to receive our POST. */ + test_setopt(curl, CURLOPT_URL, URL); + + /* Based on a bug report by Niels van Tongeren on June 29, 2004: + + A weird situation occurs when request 1 is a POST request and the request + 2 is a HEAD request. For the POST request we set the CURLOPT_POSTFIELDS, + CURLOPT_POSTFIELDSIZE and CURLOPT_POST options. For the HEAD request we + set the CURLOPT_NOBODY option to '1'. + + */ + + test_setopt(curl, CURLOPT_POSTFIELDS, "moo"); + test_setopt(curl, CURLOPT_POSTFIELDSIZE, 3L); + test_setopt(curl, CURLOPT_POST, 1L); + + /* this is where transfer 1 would take place, but skip that and change + options right away instead */ + + test_setopt(curl, CURLOPT_NOBODY, 1L); + + test_setopt(curl, CURLOPT_VERBOSE, 1L); /* show verbose for debug */ + test_setopt(curl, CURLOPT_HEADER, 1L); /* include header */ + + /* Now, we should be making a fine HEAD request */ + + /* Perform the request 2, res will get the return code */ + res = curl_easy_perform(curl); + +test_cleanup: + + /* always cleanup */ + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} diff --git a/tests/libtest/lib515.c b/tests/libtest/lib515.c new file mode 100644 index 000000000..4e96c4a8d --- /dev/null +++ b/tests/libtest/lib515.c @@ -0,0 +1,59 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +int test(char *URL) +{ + CURL *curl; + CURLcode res=CURLE_OK; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + /* First set the URL that is about to receive our POST. */ + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_POSTFIELDS, NULL); + test_setopt(curl, CURLOPT_POSTFIELDSIZE, 0L); + test_setopt(curl, CURLOPT_VERBOSE, 1L); /* show verbose for debug */ + test_setopt(curl, CURLOPT_HEADER, 1L); /* include header */ + + /* Now, we should be making a zero byte POST request */ + res = curl_easy_perform(curl); + +test_cleanup: + + /* always cleanup */ + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} diff --git a/tests/libtest/lib516.c b/tests/libtest/lib516.c new file mode 100644 index 000000000..a9590948d --- /dev/null +++ b/tests/libtest/lib516.c @@ -0,0 +1,58 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +int test(char *URL) +{ + CURL *curl; + CURLcode res=CURLE_OK; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + /* First set the URL that is about to receive our POST. */ + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_HTTPPOST, NULL); + test_setopt(curl, CURLOPT_VERBOSE, 1L); /* show verbose for debug */ + test_setopt(curl, CURLOPT_HEADER, 1L); /* include header */ + + /* Now, we should be making a zero byte POST request */ + res = curl_easy_perform(curl); + +test_cleanup: + + /* always cleanup */ + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} diff --git a/tests/libtest/lib517.c b/tests/libtest/lib517.c new file mode 100644 index 000000000..ba49ec41e --- /dev/null +++ b/tests/libtest/lib517.c @@ -0,0 +1,133 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +static const char * const dates[]={ + "Sun, 06 Nov 1994 08:49:37 GMT", + "Sunday, 06-Nov-94 08:49:37 GMT", + "Sun Nov 6 08:49:37 1994", + "06 Nov 1994 08:49:37 GMT", + "06-Nov-94 08:49:37 GMT", + "Nov 6 08:49:37 1994", + "06 Nov 1994 08:49:37", + "06-Nov-94 08:49:37", + "1994 Nov 6 08:49:37", + "GMT 08:49:37 06-Nov-94 Sunday", + "94 6 Nov 08:49:37", + "1994 Nov 6", + "06-Nov-94", + "Sun Nov 6 94", + "1994.Nov.6", + "Sun/Nov/6/94/GMT", + "Sun, 06 Nov 1994 08:49:37 CET", + "06 Nov 1994 08:49:37 EST", + "Sun, 12 Sep 2004 15:05:58 -0700", + "Sat, 11 Sep 2004 21:32:11 +0200", + "20040912 15:05:58 -0700", + "20040911 +0200", + "Thu, 01-Jan-1970 00:59:59 GMT", + "Thu, 01-Jan-1970 01:00:00 GMT", +/* "2094 Nov 6", See ../data/test517 for details */ + "Sat, 15-Apr-17 21:01:22 GMT", + "Thu, 19-Apr-2007 16:00:00 GMT", + "Wed, 25 Apr 2007 21:02:13 GMT", + "Thu, 19/Apr\\2007 16:00:00 GMT", + "Fri, 1 Jan 2010 01:01:50 GMT", + "Wednesday, 1-Jan-2003 00:00:00 GMT", + ", 1-Jan-2003 00:00:00 GMT", + " 1-Jan-2003 00:00:00 GMT", + "1-Jan-2003 00:00:00 GMT", + "Wed,18-Apr-07 22:50:12 GMT", + "WillyWonka , 18-Apr-07 22:50:12 GMT", + "WillyWonka , 18-Apr-07 22:50:12", + "WillyWonka , 18-apr-07 22:50:12", + "Mon, 18-Apr-1977 22:50:13 GMT", + "Mon, 18-Apr-77 22:50:13 GMT", + "\"Sat, 15-Apr-17\\\"21:01:22\\\"GMT\"", + "Partyday, 18- April-07 22:50:12", + "Partyday, 18 - Apri-07 22:50:12", + "Wednes, 1-Januar-2003 00:00:00 GMT", + "Sat, 15-Apr-17 21:01:22", + "Sat, 15-Apr-17 21:01:22 GMT-2", + "Sat, 15-Apr-17 21:01:22 GMT BLAH", + "Sat, 15-Apr-17 21:01:22 GMT-0400", + "Sat, 15-Apr-17 21:01:22 GMT-0400 (EDT)", + "Sat, 15-Apr-17 21:01:22 DST", + "Sat, 15-Apr-17 21:01:22 -0400", + "Sat, 15-Apr-17 21:01:22 (hello there)", + "Sat, 15-Apr-17 21:01:22 11:22:33", + "Sat, 15-Apr-17 ::00 21:01:22", + "Sat, 15-Apr-17 boink:z 21:01:22", + "Sat, 15-Apr-17 91:22:33 21:01:22", + "Thu Apr 18 22:50:12 2007 GMT", + "22:50:12 Thu Apr 18 2007 GMT", + "Thu 22:50:12 Apr 18 2007 GMT", + "Thu Apr 22:50:12 18 2007 GMT", + "Thu Apr 18 22:50:12 2007 GMT", + "Thu Apr 18 2007 22:50:12 GMT", + "Thu Apr 18 2007 GMT 22:50:12", + "Sat, 15-Apr-17 21:01:22 GMT", + "15-Sat, Apr-17 21:01:22 GMT", + "15-Sat, Apr 21:01:22 GMT 17", + "15-Sat, Apr 21:01:22 GMT 2017", + "15 Apr 21:01:22 2017", + "15 17 Apr 21:01:22", + "Apr 15 17 21:01:22", + "Apr 15 21:01:22 17", + "2017 April 15 21:01:22", + "15 April 2017 21:01:22", + "98 April 17 21:01:22", + "Thu, 012-Aug-2008 20:49:07 GMT", +#if 0 + /* leaving out these strings since they differ between 32 and 64 bit + archs and the test suite has no good way to support two different outputs + like that */ + "Thu, 12-Aug-31841 20:49:07 GMT", + "Thu, 12-Aug-9999999999 20:49:07 GMT", +#endif + "Thu, 999999999999-Aug-2007 20:49:07 GMT", + "Thu, 12-Aug-2007 20:61:99999999999 GMT", + "IAintNoDateFool", + "Thu Apr 18 22:50 2007 GMT", /* without seconds */ + "20110623 12:34:56", + "20110632 12:34:56", + "20110623 56:34:56", + "20111323 12:34:56", + "20110623 12:34:79", + "Wed, 31 Dec 2008 23:59:60 GMT", /* leap second */ + NULL +}; + +int test(char *URL) +{ + int i; + + (void)URL; /* not used */ + + for(i=0; dates[i]; i++) { + printf("%d: %s => %ld\n", i, dates[i], (long)curl_getdate(dates[i], NULL)); + } + + return 0; +} diff --git a/tests/libtest/lib518.c b/tests/libtest/lib518.c new file mode 100644 index 000000000..23f7f17c6 --- /dev/null +++ b/tests/libtest/lib518.c @@ -0,0 +1,516 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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" + +#ifdef HAVE_SYS_RESOURCE_H +#include <sys/resource.h> +#endif +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif + +#include "warnless.h" +#include "memdebug.h" + +#ifndef FD_SETSIZE +#error "this test requires FD_SETSIZE" +#endif + +#define SAFETY_MARGIN (16) +#define NUM_OPEN (FD_SETSIZE + 10) +#define NUM_NEEDED (NUM_OPEN + SAFETY_MARGIN) + +#if defined(WIN32) || defined(_WIN32) || defined(MSDOS) +#define DEV_NULL "NUL" +#else +#define DEV_NULL "/dev/null" +#endif + +#if defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) + +static int *fd = NULL; +static struct rlimit num_open; +static char msgbuff[256]; + +static void store_errmsg(const char *msg, int err) +{ + if (!err) + sprintf(msgbuff, "%s", msg); + else + sprintf(msgbuff, "%s, errno %d, %s", msg, err, strerror(err)); +} + +static void close_file_descriptors(void) +{ + for (num_open.rlim_cur = 0; + num_open.rlim_cur < num_open.rlim_max; + num_open.rlim_cur++) + if (fd[num_open.rlim_cur] > 0) + close(fd[num_open.rlim_cur]); + free(fd); + fd = NULL; +} + +static int fopen_works(void) +{ + FILE *fpa[3]; + int i; + int ret = 1; + + for (i = 0; i < 3; i++) { + fpa[i] = NULL; + } + for (i = 0; i < 3; i++) { + fpa[i] = fopen(DEV_NULL, "r"); + if (fpa[i] == NULL) { + store_errmsg("fopen() failed", ERRNO); + fprintf(stderr, "%s\n", msgbuff); + ret = 0; + break; + } + } + for (i = 0; i < 3; i++) { + if (fpa[i] != NULL) + fclose(fpa[i]); + } + return ret; +} + +static int rlimit(int keep_open) +{ + int nitems, i; + int *memchunk = NULL; + char *fmt; + struct rlimit rl; + char strbuff[256]; + char strbuff1[81]; + char strbuff2[81]; + char fmt_u[] = "%u"; + char fmt_lu[] = "%lu"; +#ifdef HAVE_LONGLONG + char fmt_llu[] = "%llu"; + + if (sizeof(rl.rlim_max) > sizeof(long)) + fmt = fmt_llu; + else +#endif + fmt = (sizeof(rl.rlim_max) < sizeof(long))?fmt_u:fmt_lu; + + /* get initial open file limits */ + + if (getrlimit(RLIMIT_NOFILE, &rl) != 0) { + store_errmsg("getrlimit() failed", ERRNO); + fprintf(stderr, "%s\n", msgbuff); + return -1; + } + + /* show initial open file limits */ + +#ifdef RLIM_INFINITY + if (rl.rlim_cur == RLIM_INFINITY) + strcpy(strbuff, "INFINITY"); + else +#endif + sprintf(strbuff, fmt, rl.rlim_cur); + fprintf(stderr, "initial soft limit: %s\n", strbuff); + +#ifdef RLIM_INFINITY + if (rl.rlim_max == RLIM_INFINITY) + strcpy(strbuff, "INFINITY"); + else +#endif + sprintf(strbuff, fmt, rl.rlim_max); + fprintf(stderr, "initial hard limit: %s\n", strbuff); + + /* show our constants */ + + fprintf(stderr, "test518 FD_SETSIZE: %d\n", FD_SETSIZE); + fprintf(stderr, "test518 NUM_OPEN : %d\n", NUM_OPEN); + fprintf(stderr, "test518 NUM_NEEDED: %d\n", NUM_NEEDED); + + /* + * if soft limit and hard limit are different we ask the + * system to raise soft limit all the way up to the hard + * limit. Due to some other system limit the soft limit + * might not be raised up to the hard limit. So from this + * point the resulting soft limit is our limit. Trying to + * open more than soft limit file descriptors will fail. + */ + + if (rl.rlim_cur != rl.rlim_max) { + +#ifdef OPEN_MAX + if ((rl.rlim_cur > 0) && + (rl.rlim_cur < OPEN_MAX)) { + fprintf(stderr, "raising soft limit up to OPEN_MAX\n"); + rl.rlim_cur = OPEN_MAX; + if (setrlimit(RLIMIT_NOFILE, &rl) != 0) { + /* on failure don't abort just issue a warning */ + store_errmsg("setrlimit() failed", ERRNO); + fprintf(stderr, "%s\n", msgbuff); + msgbuff[0] = '\0'; + } + } +#endif + + fprintf(stderr, "raising soft limit up to hard limit\n"); + rl.rlim_cur = rl.rlim_max; + if (setrlimit(RLIMIT_NOFILE, &rl) != 0) { + /* on failure don't abort just issue a warning */ + store_errmsg("setrlimit() failed", ERRNO); + fprintf(stderr, "%s\n", msgbuff); + msgbuff[0] = '\0'; + } + + /* get current open file limits */ + + if (getrlimit(RLIMIT_NOFILE, &rl) != 0) { + store_errmsg("getrlimit() failed", ERRNO); + fprintf(stderr, "%s\n", msgbuff); + return -3; + } + + /* show current open file limits */ + +#ifdef RLIM_INFINITY + if (rl.rlim_cur == RLIM_INFINITY) + strcpy(strbuff, "INFINITY"); + else +#endif + sprintf(strbuff, fmt, rl.rlim_cur); + fprintf(stderr, "current soft limit: %s\n", strbuff); + +#ifdef RLIM_INFINITY + if (rl.rlim_max == RLIM_INFINITY) + strcpy(strbuff, "INFINITY"); + else +#endif + sprintf(strbuff, fmt, rl.rlim_max); + fprintf(stderr, "current hard limit: %s\n", strbuff); + + } /* (rl.rlim_cur != rl.rlim_max) */ + + /* + * test 518 is all about testing libcurl functionality + * when more than FD_SETSIZE file descriptors are open. + * This means that if for any reason we are not able to + * open more than FD_SETSIZE file descriptors then test + * 518 should not be run. + */ + + /* + * verify that soft limit is higher than NUM_NEEDED, + * which is the number of file descriptors we would + * try to open plus SAFETY_MARGIN to not exhaust the + * file descriptor pool + */ + + num_open.rlim_cur = NUM_NEEDED; + + if ((rl.rlim_cur > 0) && +#ifdef RLIM_INFINITY + (rl.rlim_cur != RLIM_INFINITY) && +#endif + (rl.rlim_cur <= num_open.rlim_cur)) { + sprintf(strbuff2, fmt, rl.rlim_cur); + sprintf(strbuff1, fmt, num_open.rlim_cur); + sprintf(strbuff, "fds needed %s > system limit %s", + strbuff1, strbuff2); + store_errmsg(strbuff, 0); + fprintf(stderr, "%s\n", msgbuff); + return -4; + } + + /* + * reserve a chunk of memory before opening file descriptors to + * avoid a low memory condition once the file descriptors are + * open. System conditions that could make the test fail should + * be addressed in the precheck phase. This chunk of memory shall + * be always free()ed before exiting the rlimit() function so + * that it becomes available to the test. + */ + + for (nitems = i = 1; nitems <= i; i *= 2) + nitems = i; + if (nitems > 0x7fff) + nitems = 0x40000; + do { + num_open.rlim_max = sizeof(*memchunk) * (size_t)nitems; + sprintf(strbuff, fmt, num_open.rlim_max); + fprintf(stderr, "allocating memchunk %s byte array\n", strbuff); + memchunk = malloc(sizeof(*memchunk) * (size_t)nitems); + if (!memchunk) { + fprintf(stderr, "memchunk, malloc() failed\n"); + nitems /= 2; + } + } while (nitems && !memchunk); + if (!memchunk) { + store_errmsg("memchunk, malloc() failed", ERRNO); + fprintf(stderr, "%s\n", msgbuff); + return -5; + } + + /* initialize it to fight lazy allocation */ + + fprintf(stderr, "initializing memchunk array\n"); + + for (i = 0; i < nitems; i++) + memchunk[i] = -1; + + /* set the number of file descriptors we will try to open */ + + num_open.rlim_max = NUM_OPEN; + + /* verify that we won't overflow size_t in malloc() */ + + if ((size_t)(num_open.rlim_max) > ((size_t)-1) / sizeof(*fd)) { + sprintf(strbuff1, fmt, num_open.rlim_max); + sprintf(strbuff, "unable to allocate an array for %s " + "file descriptors, would overflow size_t", strbuff1); + store_errmsg(strbuff, 0); + fprintf(stderr, "%s\n", msgbuff); + free(memchunk); + return -6; + } + + /* allocate array for file descriptors */ + + sprintf(strbuff, fmt, num_open.rlim_max); + fprintf(stderr, "allocating array for %s file descriptors\n", strbuff); + + fd = malloc(sizeof(*fd) * (size_t)(num_open.rlim_max)); + if (!fd) { + store_errmsg("fd, malloc() failed", ERRNO); + fprintf(stderr, "%s\n", msgbuff); + free(memchunk); + return -7; + } + + /* initialize it to fight lazy allocation */ + + fprintf(stderr, "initializing fd array\n"); + + for (num_open.rlim_cur = 0; + num_open.rlim_cur < num_open.rlim_max; + num_open.rlim_cur++) + fd[num_open.rlim_cur] = -1; + + sprintf(strbuff, fmt, num_open.rlim_max); + fprintf(stderr, "trying to open %s file descriptors\n", strbuff); + + /* open a dummy descriptor */ + + fd[0] = open(DEV_NULL, O_RDONLY); + if (fd[0] < 0) { + sprintf(strbuff, "opening of %s failed", DEV_NULL); + store_errmsg(strbuff, ERRNO); + fprintf(stderr, "%s\n", msgbuff); + free(fd); + fd = NULL; + free(memchunk); + return -8; + } + + /* create a bunch of file descriptors */ + + for (num_open.rlim_cur = 1; + num_open.rlim_cur < num_open.rlim_max; + num_open.rlim_cur++) { + + fd[num_open.rlim_cur] = dup(fd[0]); + + if (fd[num_open.rlim_cur] < 0) { + + fd[num_open.rlim_cur] = -1; + + sprintf(strbuff1, fmt, num_open.rlim_cur); + sprintf(strbuff, "dup() attempt %s failed", strbuff1); + fprintf(stderr, "%s\n", strbuff); + + sprintf(strbuff1, fmt, num_open.rlim_cur); + sprintf(strbuff, "fds system limit seems close to %s", strbuff1); + fprintf(stderr, "%s\n", strbuff); + + num_open.rlim_max = NUM_NEEDED; + + sprintf(strbuff2, fmt, num_open.rlim_max); + sprintf(strbuff1, fmt, num_open.rlim_cur); + sprintf(strbuff, "fds needed %s > system limit %s", + strbuff2, strbuff1); + store_errmsg(strbuff, 0); + fprintf(stderr, "%s\n", msgbuff); + + for (num_open.rlim_cur = 0; + fd[num_open.rlim_cur] >= 0; + num_open.rlim_cur++) + close(fd[num_open.rlim_cur]); + free(fd); + fd = NULL; + free(memchunk); + return -9; + + } + + } + + sprintf(strbuff, fmt, num_open.rlim_max); + fprintf(stderr, "%s file descriptors open\n", strbuff); + +#if !defined(HAVE_POLL_FINE) && \ + !defined(USE_WINSOCK) && \ + !defined(TPF) + + /* + * when using select() instead of poll() we cannot test + * libcurl functionality with a socket number equal or + * greater than FD_SETSIZE. In any case, macro VERIFY_SOCK + * in lib/select.c enforces this check and protects libcurl + * from a possible crash. The effect of this protection + * is that test 518 will always fail, since the actual + * call to select() never takes place. We skip test 518 + * with an indication that select limit would be exceeded. + */ + + num_open.rlim_cur = FD_SETSIZE - SAFETY_MARGIN; + if (num_open.rlim_max > num_open.rlim_cur) { + sprintf(strbuff, "select limit is FD_SETSIZE %d", FD_SETSIZE); + store_errmsg(strbuff, 0); + fprintf(stderr, "%s\n", msgbuff); + close_file_descriptors(); + free(memchunk); + return -10; + } + + num_open.rlim_cur = FD_SETSIZE - SAFETY_MARGIN; + for (rl.rlim_cur = 0; + rl.rlim_cur < num_open.rlim_max; + rl.rlim_cur++) { + if ((fd[rl.rlim_cur] > 0) && + ((unsigned int)fd[rl.rlim_cur] > num_open.rlim_cur)) { + sprintf(strbuff, "select limit is FD_SETSIZE %d", FD_SETSIZE); + store_errmsg(strbuff, 0); + fprintf(stderr, "%s\n", msgbuff); + close_file_descriptors(); + free(memchunk); + return -11; + } + } + +#endif /* using a FD_SETSIZE bound select() */ + + /* + * Old or 'backwards compatible' implementations of stdio do not allow + * handling of streams with an underlying file descriptor number greater + * than 255, even when allowing high numbered file descriptors for sockets. + * At this point we have a big number of file descriptors which have been + * opened using dup(), so lets test the stdio implementation and discover + * if it is capable of fopen()ing some additional files. + */ + + if (!fopen_works()) { + sprintf(strbuff1, fmt, num_open.rlim_max); + sprintf(strbuff, "stdio fopen() fails with %s fds open()", + strbuff1); + fprintf(stderr, "%s\n", msgbuff); + sprintf(strbuff, "stdio fopen() fails with lots of fds open()"); + store_errmsg(strbuff, 0); + close_file_descriptors(); + free(memchunk); + return -12; + } + + /* free the chunk of memory we were reserving so that it + becomes becomes available to the test */ + + free(memchunk); + + /* close file descriptors unless instructed to keep them */ + + if (!keep_open) { + close_file_descriptors(); + } + + return 0; +} + +int test(char *URL) +{ + CURLcode res; + CURL *curl; + + if(!strcmp(URL, "check")) { + /* used by the test script to ask if we can run this test or not */ + if(rlimit(FALSE)) { + fprintf(stdout, "rlimit problem: %s\n", msgbuff); + return 1; + } + return 0; /* sure, run this! */ + } + + if (rlimit(TRUE)) { + /* failure */ + return TEST_ERR_MAJOR_BAD; + } + + /* run the test with the bunch of open file descriptors + and close them all once the test is over */ + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + close_file_descriptors(); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + close_file_descriptors(); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_HEADER, 1L); + + res = curl_easy_perform(curl); + +test_cleanup: + + close_file_descriptors(); + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} + +#else /* defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) */ + +int test(char *URL) +{ + (void)URL; + printf("system lacks necessary system function(s)"); + return 1; /* skip test */ +} + +#endif /* defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) */ diff --git a/tests/libtest/lib519.c b/tests/libtest/lib519.c new file mode 100644 index 000000000..b720c8fee --- /dev/null +++ b/tests/libtest/lib519.c @@ -0,0 +1,62 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +int test(char *URL) +{ + CURLcode res; + CURL *curl; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_USERPWD, "monster:underbed"); + test_setopt(curl, CURLOPT_HEADER, 1L); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + /* get first page */ + res = curl_easy_perform(curl); + + test_setopt(curl, CURLOPT_USERPWD, "anothermonster:inwardrobe"); + + /* get second page */ + res = curl_easy_perform(curl); + +test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} + diff --git a/tests/libtest/lib520.c b/tests/libtest/lib520.c new file mode 100644 index 000000000..9ffaa4f92 --- /dev/null +++ b/tests/libtest/lib520.c @@ -0,0 +1,54 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +int test(char *URL) +{ + CURLcode res; + CURL *curl; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_FILETIME, 1L); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + res = curl_easy_perform(curl); + +test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} diff --git a/tests/libtest/lib521.c b/tests/libtest/lib521.c new file mode 100644 index 000000000..93c306864 --- /dev/null +++ b/tests/libtest/lib521.c @@ -0,0 +1,56 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +int test(char *URL) +{ + CURLcode res; + CURL *curl; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_PORT, strtol(libtest_arg2, NULL, 10)); + test_setopt(curl, CURLOPT_USERPWD, "xxx:yyy"); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + res = curl_easy_perform(curl); + +test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} + diff --git a/tests/libtest/lib523.c b/tests/libtest/lib523.c new file mode 100644 index 000000000..0fdc83db6 --- /dev/null +++ b/tests/libtest/lib523.c @@ -0,0 +1,57 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +int test(char *URL) +{ + CURLcode res; + CURL *curl; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_PROXY, libtest_arg2); + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_PORT, 19999L); + test_setopt(curl, CURLOPT_USERPWD, "xxx:yyy"); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + res = curl_easy_perform(curl); + +test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} + diff --git a/tests/libtest/lib524.c b/tests/libtest/lib524.c new file mode 100644 index 000000000..6f56df9b0 --- /dev/null +++ b/tests/libtest/lib524.c @@ -0,0 +1,55 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +int test(char *URL) +{ + CURLcode res; + CURL *curl; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_UPLOAD, 1L); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + res = curl_easy_perform(curl); + +test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} + diff --git a/tests/libtest/lib525.c b/tests/libtest/lib525.c new file mode 100644 index 000000000..ca128cb9c --- /dev/null +++ b/tests/libtest/lib525.c @@ -0,0 +1,165 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 60 * 1000 + +int test(char *URL) +{ + int res = 0; + CURL *curl = NULL; + FILE *hd_src = NULL; + int hd ; + int error; + struct_stat file_info; + CURLM *m = NULL; + int running; + + start_test_timing(); + + if(!libtest_arg2) { +#ifdef LIB529 + /* test 529 */ + fprintf(stderr, "Usage: lib529 [url] [uploadfile]\n"); +#else + /* test 525 */ + fprintf(stderr, "Usage: lib525 [url] [uploadfile]\n"); +#endif + return TEST_ERR_USAGE; + } + + hd_src = fopen(libtest_arg2, "rb"); + if(NULL == hd_src) { + error = ERRNO; + fprintf(stderr, "fopen() failed with error: %d (%s)\n", + error, strerror(error)); + fprintf(stderr, "Error opening file: (%s)\n", libtest_arg2); + return TEST_ERR_FOPEN; + } + + /* get the file size of the local file */ + hd = fstat(fileno(hd_src), &file_info); + if(hd == -1) { + /* can't open file, bail out */ + error = ERRNO; + fprintf(stderr, "fstat() failed with error: %d (%s)\n", + error, strerror(error)); + fprintf(stderr, "ERROR: cannot open file (%s)\n", libtest_arg2); + fclose(hd_src); + return TEST_ERR_FSTAT; + } + + res_global_init(CURL_GLOBAL_ALL); + if(res) { + fclose(hd_src); + return res; + } + + easy_init(curl); + + /* enable uploading */ + easy_setopt(curl, CURLOPT_UPLOAD, 1L); + + /* specify target */ + easy_setopt(curl,CURLOPT_URL, URL); + + /* go verbose */ + easy_setopt(curl, CURLOPT_VERBOSE, 1L); + + /* use active FTP */ + easy_setopt(curl, CURLOPT_FTPPORT, "-"); + + /* now specify which file to upload */ + easy_setopt(curl, CURLOPT_READDATA, hd_src); + + /* NOTE: if you want this code to work on Windows with libcurl as a DLL, you + MUST also provide a read callback with CURLOPT_READFUNCTION. Failing to + do so will give you a crash since a DLL may not use the variable's memory + when passed in to it from an app like this. */ + + /* Set the size of the file to upload (optional). If you give a *_LARGE + option you MUST make sure that the type of the passed-in argument is a + curl_off_t. If you use CURLOPT_INFILESIZE (without _LARGE) you must + make sure that to pass in a type 'long' argument. */ + easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size); + + multi_init(m); + + multi_add_handle(m, curl); + + for(;;) { + struct timeval interval; + fd_set rd, wr, exc; + int maxfd = -99; + + interval.tv_sec = 1; + interval.tv_usec = 0; + + multi_perform(m, &running); + + abort_on_test_timeout(); + + if(!running) + break; /* done */ + + FD_ZERO(&rd); + FD_ZERO(&wr); + FD_ZERO(&exc); + + multi_fdset(m, &rd, &wr, &exc, &maxfd); + + /* At this point, maxfd is guaranteed to be greater or equal than -1. */ + + select_test(maxfd+1, &rd, &wr, &exc, &interval); + + abort_on_test_timeout(); + } + +test_cleanup: + +#ifdef LIB529 + /* test 529 */ + /* proper cleanup sequence - type PA */ + curl_multi_remove_handle(m, curl); + curl_multi_cleanup(m); + curl_easy_cleanup(curl); + curl_global_cleanup(); +#else + /* test 525 */ + /* proper cleanup sequence - type PB */ + curl_multi_remove_handle(m, curl); + curl_easy_cleanup(curl); + curl_multi_cleanup(m); + curl_global_cleanup(); +#endif + + /* close the local file */ + fclose(hd_src); + + return res; +} diff --git a/tests/libtest/lib526.c b/tests/libtest/lib526.c new file mode 100644 index 000000000..9db04dba7 --- /dev/null +++ b/tests/libtest/lib526.c @@ -0,0 +1,184 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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. + * + ***************************************************************************/ +/* + * This code sets up multiple easy handles that transfer a single file from + * the same URL, in a serial manner after each other. Due to the connection + * sharing within the multi handle all transfers are performed on the same + * persistent connection. + * + * This source code is used for lib526, lib527 and lib532 with only #ifdefs + * controlling the small differences. + * + * - lib526 closes all easy handles after + * they all have transfered the file over the single connection + * - lib527 closes each easy handle after each single transfer. + * - lib532 uses only a single easy handle that is removed, reset and then + * re-added for each transfer + * + * Test case 526, 527 and 532 use FTP, while test 528 uses the lib526 tool but + * with HTTP. + */ + +#include "test.h" + +#include <fcntl.h> + +#include "testutil.h" +#include "warnless.h" +#include "memdebug.h" + +#define TEST_HANG_TIMEOUT 60 * 1000 + +#define NUM_HANDLES 4 + +int test(char *URL) +{ + int res = 0; + CURL *curl[NUM_HANDLES]; + int running; + CURLM *m = NULL; + int current = 0; + int i; + + for(i=0; i < NUM_HANDLES; i++) + curl[i] = NULL; + + start_test_timing(); + + global_init(CURL_GLOBAL_ALL); + + /* get NUM_HANDLES easy handles */ + for(i=0; i < NUM_HANDLES; i++) { + easy_init(curl[i]); + /* specify target */ + easy_setopt(curl[i], CURLOPT_URL, URL); + /* go verbose */ + easy_setopt(curl[i], CURLOPT_VERBOSE, 1L); + } + + multi_init(m); + + multi_add_handle(m, curl[current]); + + fprintf(stderr, "Start at URL 0\n"); + + for(;;) { + struct timeval interval; + fd_set rd, wr, exc; + int maxfd = -99; + + interval.tv_sec = 1; + interval.tv_usec = 0; + + multi_perform(m, &running); + + abort_on_test_timeout(); + + if(!running) { +#ifdef LIB527 + /* NOTE: this code does not remove the handle from the multi handle + here, which would be the nice, sane and documented way of working. + This however tests that the API survives this abuse gracefully. */ + curl_easy_cleanup(curl[current]); + curl[current] = NULL; +#endif + if(++current < NUM_HANDLES) { + fprintf(stderr, "Advancing to URL %d\n", current); +#ifdef LIB532 + /* first remove the only handle we use */ + curl_multi_remove_handle(m, curl[0]); + + /* make us re-use the same handle all the time, and try resetting + the handle first too */ + curl_easy_reset(curl[0]); + easy_setopt(curl[0], CURLOPT_URL, URL); + /* go verbose */ + easy_setopt(curl[0], CURLOPT_VERBOSE, 1L); + + /* re-add it */ + multi_add_handle(m, curl[0]); +#else + multi_add_handle(m, curl[current]); +#endif + } + else { + break; /* done */ + } + } + + FD_ZERO(&rd); + FD_ZERO(&wr); + FD_ZERO(&exc); + + multi_fdset(m, &rd, &wr, &exc, &maxfd); + + /* At this point, maxfd is guaranteed to be greater or equal than -1. */ + + select_test(maxfd+1, &rd, &wr, &exc, &interval); + + abort_on_test_timeout(); + } + +test_cleanup: + +#if defined(LIB526) + + /* test 526 and 528 */ + /* proper cleanup sequence - type PB */ + + for(i=0; i < NUM_HANDLES; i++) { + curl_multi_remove_handle(m, curl[i]); + curl_easy_cleanup(curl[i]); + } + curl_multi_cleanup(m); + curl_global_cleanup(); + +#elif defined(LIB527) + + /* test 527 */ + + /* Upon non-failure test flow the easy's have already been cleanup'ed. In + case there is a failure we arrive here with easy's that have not been + cleanup'ed yet, in this case we have to cleanup them or otherwise these + will be leaked, let's use undocumented cleanup sequence - type UB */ + + if(res) + for(i=0; i < NUM_HANDLES; i++) + curl_easy_cleanup(curl[i]); + + curl_multi_cleanup(m); + curl_global_cleanup(); + +#elif defined(LIB532) + + /* test 532 */ + /* undocumented cleanup sequence - type UB */ + + for(i=0; i < NUM_HANDLES; i++) + curl_easy_cleanup(curl[i]); + curl_multi_cleanup(m); + curl_global_cleanup(); + +#endif + + return res; +} diff --git a/tests/libtest/lib530.c b/tests/libtest/lib530.c new file mode 100644 index 000000000..ad84ff8a5 --- /dev/null +++ b/tests/libtest/lib530.c @@ -0,0 +1,111 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "testutil.h" +#include "warnless.h" +#include "memdebug.h" + +#define TEST_HANG_TIMEOUT 60 * 1000 + +#define NUM_HANDLES 4 + +int test(char *URL) +{ + int res = 0; + CURL *curl[NUM_HANDLES]; + int running; + CURLM *m = NULL; + int i; + char target_url[256]; + + for(i=0; i < NUM_HANDLES; i++) + curl[i] = NULL; + + start_test_timing(); + + global_init(CURL_GLOBAL_ALL); + + multi_init(m); + + /* get NUM_HANDLES easy handles */ + for(i=0; i < NUM_HANDLES; i++) { + /* get an easy handle */ + easy_init(curl[i]); + /* specify target */ + sprintf(target_url, "%s%04i", URL, i + 1); + target_url[sizeof(target_url) - 1] = '\0'; + easy_setopt(curl[i], CURLOPT_URL, target_url); + /* go verbose */ + easy_setopt(curl[i], CURLOPT_VERBOSE, 1L); + /* include headers */ + easy_setopt(curl[i], CURLOPT_HEADER, 1L); + /* add handle to multi */ + multi_add_handle(m, curl[i]); + } + + multi_setopt(m, CURLMOPT_PIPELINING, 1L); + + fprintf(stderr, "Start at URL 0\n"); + + for(;;) { + struct timeval interval; + fd_set rd, wr, exc; + int maxfd = -99; + + interval.tv_sec = 1; + interval.tv_usec = 0; + + multi_perform(m, &running); + + abort_on_test_timeout(); + + if(!running) + break; /* done */ + + FD_ZERO(&rd); + FD_ZERO(&wr); + FD_ZERO(&exc); + + multi_fdset(m, &rd, &wr, &exc, &maxfd); + + /* At this point, maxfd is guaranteed to be greater or equal than -1. */ + + select_test(maxfd+1, &rd, &wr, &exc, &interval); + + abort_on_test_timeout(); + } + +test_cleanup: + + /* proper cleanup sequence - type PB */ + + for(i=0; i < NUM_HANDLES; i++) { + curl_multi_remove_handle(m, curl[i]); + curl_easy_cleanup(curl[i]); + } + + curl_multi_cleanup(m); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib533.c b/tests/libtest/lib533.c new file mode 100644 index 000000000..fdc18a1eb --- /dev/null +++ b/tests/libtest/lib533.c @@ -0,0 +1,112 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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. + * + ***************************************************************************/ +/* used for test case 533, 534 and 535 */ + +#include "test.h" + +#include <fcntl.h> + +#include "testutil.h" +#include "warnless.h" +#include "memdebug.h" + +#define TEST_HANG_TIMEOUT 60 * 1000 + +int test(char *URL) +{ + int res = 0; + CURL *curl = NULL; + int running; + CURLM *m = NULL; + int current=0; + + start_test_timing(); + + global_init(CURL_GLOBAL_ALL); + + easy_init(curl); + + easy_setopt(curl, CURLOPT_URL, URL); + easy_setopt(curl, CURLOPT_VERBOSE, 1L); + easy_setopt(curl, CURLOPT_FAILONERROR, 1L); + + multi_init(m); + + multi_add_handle(m, curl); + + fprintf(stderr, "Start at URL 0\n"); + + for(;;) { + struct timeval interval; + fd_set rd, wr, exc; + int maxfd = -99; + + interval.tv_sec = 1; + interval.tv_usec = 0; + + multi_perform(m, &running); + + abort_on_test_timeout(); + + if(!running) { + if(!current++) { + fprintf(stderr, "Advancing to URL 1\n"); + /* remove the handle we use */ + curl_multi_remove_handle(m, curl); + + /* make us re-use the same handle all the time, and try resetting + the handle first too */ + curl_easy_reset(curl); + easy_setopt(curl, CURLOPT_URL, libtest_arg2); + easy_setopt(curl, CURLOPT_VERBOSE, 1L); + easy_setopt(curl, CURLOPT_FAILONERROR, 1L); + + /* re-add it */ + multi_add_handle(m, curl); + } + else + break; /* done */ + } + + FD_ZERO(&rd); + FD_ZERO(&wr); + FD_ZERO(&exc); + + multi_fdset(m, &rd, &wr, &exc, &maxfd); + + /* At this point, maxfd is guaranteed to be greater or equal than -1. */ + + select_test(maxfd+1, &rd, &wr, &exc, &interval); + + abort_on_test_timeout(); + } + +test_cleanup: + + /* undocumented cleanup sequence - type UB */ + + curl_easy_cleanup(curl); + curl_multi_cleanup(m); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib536.c b/tests/libtest/lib536.c new file mode 100644 index 000000000..e3ae402b7 --- /dev/null +++ b/tests/libtest/lib536.c @@ -0,0 +1,142 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 60 * 1000 + +static int perform(CURLM *multi) +{ + int handles; + fd_set fdread, fdwrite, fdexcep; + int res = 0; + + for(;;) { + struct timeval interval; + int maxfd = -99; + + interval.tv_sec = 0; + interval.tv_usec = 100000L; /* 100 ms */ + + res_multi_perform(multi, &handles); + if(res) + return res; + + res_test_timedout(); + if(res) + return res; + + if(!handles) + break; /* done */ + + FD_ZERO(&fdread); + FD_ZERO(&fdwrite); + FD_ZERO(&fdexcep); + + res_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd); + if(res) + return res; + + /* At this point, maxfd is guaranteed to be greater or equal than -1. */ + + res_select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &interval); + if(res) + return res; + + res_test_timedout(); + if(res) + return res; + } + + return 0; /* success */ +} + +int test(char *URL) +{ + CURLM *multi = NULL; + CURL *easy = NULL; + int res = 0; + + start_test_timing(); + + global_init(CURL_GLOBAL_ALL); + + multi_init(multi); + + easy_init(easy); + + multi_setopt(multi, CURLMOPT_PIPELINING, 1L); + + easy_setopt(easy, CURLOPT_WRITEFUNCTION, fwrite); + easy_setopt(easy, CURLOPT_FAILONERROR, 1L); + easy_setopt(easy, CURLOPT_URL, URL); + + res_multi_add_handle(multi, easy); + if(res) { + printf("curl_multi_add_handle() 1 failed\n"); + goto test_cleanup; + } + + res = perform(multi); + if(res) { + printf("retrieve 1 failed\n"); + goto test_cleanup; + } + + curl_multi_remove_handle(multi, easy); + + curl_easy_reset(easy); + + easy_setopt(easy, CURLOPT_FAILONERROR, 1L); + easy_setopt(easy, CURLOPT_URL, libtest_arg2); + + res_multi_add_handle(multi, easy); + if(res) { + printf("curl_multi_add_handle() 2 failed\n"); + goto test_cleanup; + } + + res = perform(multi); + if(res) { + printf("retrieve 2 failed\n"); + goto test_cleanup; + } + + curl_multi_remove_handle(multi, easy); + +test_cleanup: + + /* undocumented cleanup sequence - type UB */ + + curl_easy_cleanup(easy); + curl_multi_cleanup(multi); + curl_global_cleanup(); + + printf("Finished!\n"); + + return res; +} diff --git a/tests/libtest/lib537.c b/tests/libtest/lib537.c new file mode 100644 index 000000000..24d252235 --- /dev/null +++ b/tests/libtest/lib537.c @@ -0,0 +1,519 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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" + +#ifdef HAVE_SYS_RESOURCE_H +#include <sys/resource.h> +#endif +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif + +#include "warnless.h" +#include "memdebug.h" + +#if !defined(HAVE_POLL_FINE) && \ + !defined(USE_WINSOCK) && \ + !defined(TPF) && \ + !defined(FD_SETSIZE) +#error "this test requires FD_SETSIZE" +#endif + +#define SAFETY_MARGIN (10) + +#if defined(WIN32) || defined(_WIN32) || defined(MSDOS) +#define DEV_NULL "NUL" +#else +#define DEV_NULL "/dev/null" +#endif + +#if defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) + +static int *fd = NULL; +static struct rlimit num_open; +static char msgbuff[256]; + +static void store_errmsg(const char *msg, int err) +{ + if (!err) + sprintf(msgbuff, "%s", msg); + else + sprintf(msgbuff, "%s, errno %d, %s", msg, err, strerror(err)); +} + +static void close_file_descriptors(void) +{ + for (num_open.rlim_cur = 0; + num_open.rlim_cur < num_open.rlim_max; + num_open.rlim_cur++) + if (fd[num_open.rlim_cur] > 0) + close(fd[num_open.rlim_cur]); + free(fd); + fd = NULL; +} + +static int fopen_works(void) +{ + FILE *fpa[3]; + int i; + int ret = 1; + + for (i = 0; i < 3; i++) { + fpa[i] = NULL; + } + for (i = 0; i < 3; i++) { + fpa[i] = fopen(DEV_NULL, "r"); + if (fpa[i] == NULL) { + store_errmsg("fopen() failed", ERRNO); + fprintf(stderr, "%s\n", msgbuff); + ret = 0; + break; + } + } + for (i = 0; i < 3; i++) { + if (fpa[i] != NULL) + fclose(fpa[i]); + } + return ret; +} + +static int rlimit(int keep_open) +{ + int *tmpfd; + int nitems, i; + int *memchunk = NULL; + char *fmt; + struct rlimit rl; + char strbuff[256]; + char strbuff1[81]; + char fmt_u[] = "%u"; + char fmt_lu[] = "%lu"; +#ifdef HAVE_LONGLONG + char fmt_llu[] = "%llu"; + + if (sizeof(rl.rlim_max) > sizeof(long)) + fmt = fmt_llu; + else +#endif + fmt = (sizeof(rl.rlim_max) < sizeof(long))?fmt_u:fmt_lu; + + /* get initial open file limits */ + + if (getrlimit(RLIMIT_NOFILE, &rl) != 0) { + store_errmsg("getrlimit() failed", ERRNO); + fprintf(stderr, "%s\n", msgbuff); + return -1; + } + + /* show initial open file limits */ + +#ifdef RLIM_INFINITY + if (rl.rlim_cur == RLIM_INFINITY) + strcpy(strbuff, "INFINITY"); + else +#endif + sprintf(strbuff, fmt, rl.rlim_cur); + fprintf(stderr, "initial soft limit: %s\n", strbuff); + +#ifdef RLIM_INFINITY + if (rl.rlim_max == RLIM_INFINITY) + strcpy(strbuff, "INFINITY"); + else +#endif + sprintf(strbuff, fmt, rl.rlim_max); + fprintf(stderr, "initial hard limit: %s\n", strbuff); + + /* + * if soft limit and hard limit are different we ask the + * system to raise soft limit all the way up to the hard + * limit. Due to some other system limit the soft limit + * might not be raised up to the hard limit. So from this + * point the resulting soft limit is our limit. Trying to + * open more than soft limit file descriptors will fail. + */ + + if (rl.rlim_cur != rl.rlim_max) { + +#ifdef OPEN_MAX + if ((rl.rlim_cur > 0) && + (rl.rlim_cur < OPEN_MAX)) { + fprintf(stderr, "raising soft limit up to OPEN_MAX\n"); + rl.rlim_cur = OPEN_MAX; + if (setrlimit(RLIMIT_NOFILE, &rl) != 0) { + /* on failure don't abort just issue a warning */ + store_errmsg("setrlimit() failed", ERRNO); + fprintf(stderr, "%s\n", msgbuff); + msgbuff[0] = '\0'; + } + } +#endif + + fprintf(stderr, "raising soft limit up to hard limit\n"); + rl.rlim_cur = rl.rlim_max; + if (setrlimit(RLIMIT_NOFILE, &rl) != 0) { + /* on failure don't abort just issue a warning */ + store_errmsg("setrlimit() failed", ERRNO); + fprintf(stderr, "%s\n", msgbuff); + msgbuff[0] = '\0'; + } + + /* get current open file limits */ + + if (getrlimit(RLIMIT_NOFILE, &rl) != 0) { + store_errmsg("getrlimit() failed", ERRNO); + fprintf(stderr, "%s\n", msgbuff); + return -3; + } + + /* show current open file limits */ + +#ifdef RLIM_INFINITY + if (rl.rlim_cur == RLIM_INFINITY) + strcpy(strbuff, "INFINITY"); + else +#endif + sprintf(strbuff, fmt, rl.rlim_cur); + fprintf(stderr, "current soft limit: %s\n", strbuff); + +#ifdef RLIM_INFINITY + if (rl.rlim_max == RLIM_INFINITY) + strcpy(strbuff, "INFINITY"); + else +#endif + sprintf(strbuff, fmt, rl.rlim_max); + fprintf(stderr, "current hard limit: %s\n", strbuff); + + } /* (rl.rlim_cur != rl.rlim_max) */ + + /* + * test 537 is all about testing libcurl functionality + * when the system has nearly exhausted the number of + * available file descriptors. Test 537 will try to run + * with a very small number of file descriptors available. + * This implies that any file descriptor which is open + * when the test runs will have a number in the high range + * of whatever the system supports. + */ + + /* + * reserve a chunk of memory before opening file descriptors to + * avoid a low memory condition once the file descriptors are + * open. System conditions that could make the test fail should + * be addressed in the precheck phase. This chunk of memory shall + * be always free()ed before exiting the rlimit() function so + * that it becomes available to the test. + */ + + for (nitems = i = 1; nitems <= i; i *= 2) + nitems = i; + if (nitems > 0x7fff) + nitems = 0x40000; + do { + num_open.rlim_max = sizeof(*memchunk) * (size_t)nitems; + sprintf(strbuff, fmt, num_open.rlim_max); + fprintf(stderr, "allocating memchunk %s byte array\n", strbuff); + memchunk = malloc(sizeof(*memchunk) * (size_t)nitems); + if (!memchunk) { + fprintf(stderr, "memchunk, malloc() failed\n"); + nitems /= 2; + } + } while (nitems && !memchunk); + if (!memchunk) { + store_errmsg("memchunk, malloc() failed", ERRNO); + fprintf(stderr, "%s\n", msgbuff); + return -4; + } + + /* initialize it to fight lazy allocation */ + + fprintf(stderr, "initializing memchunk array\n"); + + for (i = 0; i < nitems; i++) + memchunk[i] = -1; + + /* set the number of file descriptors we will try to open */ + +#ifdef RLIM_INFINITY + if ((rl.rlim_cur > 0) && (rl.rlim_cur != RLIM_INFINITY)) { +#else + if (rl.rlim_cur > 0) { +#endif + /* soft limit minus SAFETY_MARGIN */ + num_open.rlim_max = rl.rlim_cur - SAFETY_MARGIN; + } + else { + /* a huge number of file descriptors */ + for (nitems = i = 1; nitems <= i; i *= 2) + nitems = i; + if (nitems > 0x7fff) + nitems = 0x40000; + num_open.rlim_max = nitems; + } + + /* verify that we won't overflow size_t in malloc() */ + + if ((size_t)(num_open.rlim_max) > ((size_t)-1) / sizeof(*fd)) { + sprintf(strbuff1, fmt, num_open.rlim_max); + sprintf(strbuff, "unable to allocate an array for %s " + "file descriptors, would overflow size_t", strbuff1); + store_errmsg(strbuff, 0); + fprintf(stderr, "%s\n", msgbuff); + free(memchunk); + return -5; + } + + /* allocate array for file descriptors */ + + do { + sprintf(strbuff, fmt, num_open.rlim_max); + fprintf(stderr, "allocating array for %s file descriptors\n", strbuff); + fd = malloc(sizeof(*fd) * (size_t)(num_open.rlim_max)); + if (!fd) { + fprintf(stderr, "fd, malloc() failed\n"); + num_open.rlim_max /= 2; + } + } while (num_open.rlim_max && !fd); + if (!fd) { + store_errmsg("fd, malloc() failed", ERRNO); + fprintf(stderr, "%s\n", msgbuff); + free(memchunk); + return -6; + } + + /* initialize it to fight lazy allocation */ + + fprintf(stderr, "initializing fd array\n"); + + for (num_open.rlim_cur = 0; + num_open.rlim_cur < num_open.rlim_max; + num_open.rlim_cur++) + fd[num_open.rlim_cur] = -1; + + sprintf(strbuff, fmt, num_open.rlim_max); + fprintf(stderr, "trying to open %s file descriptors\n", strbuff); + + /* open a dummy descriptor */ + + fd[0] = open(DEV_NULL, O_RDONLY); + if (fd[0] < 0) { + sprintf(strbuff, "opening of %s failed", DEV_NULL); + store_errmsg(strbuff, ERRNO); + fprintf(stderr, "%s\n", msgbuff); + free(fd); + fd = NULL; + free(memchunk); + return -7; + } + + /* create a bunch of file descriptors */ + + for (num_open.rlim_cur = 1; + num_open.rlim_cur < num_open.rlim_max; + num_open.rlim_cur++) { + + fd[num_open.rlim_cur] = dup(fd[0]); + + if (fd[num_open.rlim_cur] < 0) { + + fd[num_open.rlim_cur] = -1; + + sprintf(strbuff1, fmt, num_open.rlim_cur); + sprintf(strbuff, "dup() attempt %s failed", strbuff1); + fprintf(stderr, "%s\n", strbuff); + + sprintf(strbuff1, fmt, num_open.rlim_cur); + sprintf(strbuff, "fds system limit seems close to %s", strbuff1); + fprintf(stderr, "%s\n", strbuff); + + num_open.rlim_max = num_open.rlim_cur - SAFETY_MARGIN; + + num_open.rlim_cur -= num_open.rlim_max; + sprintf(strbuff1, fmt, num_open.rlim_cur); + sprintf(strbuff, "closing %s file descriptors", strbuff1); + fprintf(stderr, "%s\n", strbuff); + + for (num_open.rlim_cur = num_open.rlim_max; + fd[num_open.rlim_cur] >= 0; + num_open.rlim_cur++) { + close(fd[num_open.rlim_cur]); + fd[num_open.rlim_cur] = -1; + } + + sprintf(strbuff, fmt, num_open.rlim_max); + fprintf(stderr, "shrinking array for %s file descriptors\n", strbuff); + + /* we don't care if we can't shrink it */ + + tmpfd = realloc(fd, sizeof(*fd) * (size_t)(num_open.rlim_max)); + if (tmpfd) { + fd = tmpfd; + tmpfd = NULL; + } + + break; + + } + + } + + sprintf(strbuff, fmt, num_open.rlim_max); + fprintf(stderr, "%s file descriptors open\n", strbuff); + +#if !defined(HAVE_POLL_FINE) && \ + !defined(USE_WINSOCK) && \ + !defined(TPF) + + /* + * when using select() instead of poll() we cannot test + * libcurl functionality with a socket number equal or + * greater than FD_SETSIZE. In any case, macro VERIFY_SOCK + * in lib/select.c enforces this check and protects libcurl + * from a possible crash. The effect of this protection + * is that test 537 will always fail, since the actual + * call to select() never takes place. We skip test 537 + * with an indication that select limit would be exceeded. + */ + + num_open.rlim_cur = FD_SETSIZE - SAFETY_MARGIN; + if (num_open.rlim_max > num_open.rlim_cur) { + sprintf(strbuff, "select limit is FD_SETSIZE %d", FD_SETSIZE); + store_errmsg(strbuff, 0); + fprintf(stderr, "%s\n", msgbuff); + close_file_descriptors(); + free(memchunk); + return -8; + } + + num_open.rlim_cur = FD_SETSIZE - SAFETY_MARGIN; + for (rl.rlim_cur = 0; + rl.rlim_cur < num_open.rlim_max; + rl.rlim_cur++) { + if ((fd[rl.rlim_cur] > 0) && + ((unsigned int)fd[rl.rlim_cur] > num_open.rlim_cur)) { + sprintf(strbuff, "select limit is FD_SETSIZE %d", FD_SETSIZE); + store_errmsg(strbuff, 0); + fprintf(stderr, "%s\n", msgbuff); + close_file_descriptors(); + free(memchunk); + return -9; + } + } + +#endif /* using a FD_SETSIZE bound select() */ + + /* + * Old or 'backwards compatible' implementations of stdio do not allow + * handling of streams with an underlying file descriptor number greater + * than 255, even when allowing high numbered file descriptors for sockets. + * At this point we have a big number of file descriptors which have been + * opened using dup(), so lets test the stdio implementation and discover + * if it is capable of fopen()ing some additional files. + */ + + if (!fopen_works()) { + sprintf(strbuff1, fmt, num_open.rlim_max); + sprintf(strbuff, "stdio fopen() fails with %s fds open()", + strbuff1); + fprintf(stderr, "%s\n", msgbuff); + sprintf(strbuff, "stdio fopen() fails with lots of fds open()"); + store_errmsg(strbuff, 0); + close_file_descriptors(); + free(memchunk); + return -10; + } + + /* free the chunk of memory we were reserving so that it + becomes becomes available to the test */ + + free(memchunk); + + /* close file descriptors unless instructed to keep them */ + + if (!keep_open) { + close_file_descriptors(); + } + + return 0; +} + +int test(char *URL) +{ + CURLcode res; + CURL *curl; + + if(!strcmp(URL, "check")) { + /* used by the test script to ask if we can run this test or not */ + if(rlimit(FALSE)) { + fprintf(stdout, "rlimit problem: %s\n", msgbuff); + return 1; + } + return 0; /* sure, run this! */ + } + + if (rlimit(TRUE)) { + /* failure */ + return TEST_ERR_MAJOR_BAD; + } + + /* run the test with the bunch of open file descriptors + and close them all once the test is over */ + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + close_file_descriptors(); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + close_file_descriptors(); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_HEADER, 1L); + + res = curl_easy_perform(curl); + +test_cleanup: + + close_file_descriptors(); + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} + +#else /* defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) */ + +int test(char *URL) +{ + (void)URL; + printf("system lacks necessary system function(s)"); + return 1; /* skip test */ +} + +#endif /* defined(HAVE_GETRLIMIT) && defined(HAVE_SETRLIMIT) */ diff --git a/tests/libtest/lib539.c b/tests/libtest/lib539.c new file mode 100644 index 000000000..923893fb2 --- /dev/null +++ b/tests/libtest/lib539.c @@ -0,0 +1,92 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +int test(char *URL) +{ + CURLcode res; + CURL *curl; + char *newURL = NULL; + struct curl_slist *slist = NULL; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + /* + * Begin with cURL set to use a single CWD to the URL's directory. + */ + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_SINGLECWD); + + res = curl_easy_perform(curl); + + /* + * Change the FTP_FILEMETHOD option to use full paths rather than a CWD + * command. Alter the URL's path a bit, appending a "./". Use an innocuous + * QUOTE command, after which cURL will CWD to ftp_conn->entrypath and then + * (on the next call to ftp_statemach_act) find a non-zero ftpconn->dirdepth + * even though no directories are stored in the ftpconn->dirs array (after a + * call to freedirs). + */ + newURL = malloc(strlen(URL) + 3); + if (newURL == NULL) { + curl_easy_cleanup(curl); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + newURL = strcat(strcpy(newURL, URL), "./"); + + slist = curl_slist_append (NULL, "SYST"); + if (slist == NULL) { + free(newURL); + curl_easy_cleanup(curl); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_URL, newURL); + test_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_NOCWD); + test_setopt(curl, CURLOPT_QUOTE, slist); + + res = curl_easy_perform(curl); + +test_cleanup: + + curl_slist_free_all(slist); + if(newURL) + free(newURL); + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} diff --git a/tests/libtest/lib540.c b/tests/libtest/lib540.c new file mode 100644 index 000000000..ac0ebe60b --- /dev/null +++ b/tests/libtest/lib540.c @@ -0,0 +1,248 @@ +/*************************************************************************** + * _ _ ____ _ + * 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. + * + ***************************************************************************/ +/* This is the 'proxyauth.c' test app posted by Shmulik Regev on the libcurl + * mailing list on 10 Jul 2007, converted to a test case. + * + * argv1 = URL + * argv2 = proxy + * argv3 = proxyuser:password + * argv4 = host name to use for the custom Host: header + */ + +#include "test.h" + +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif + +#include "testutil.h" +#include "warnless.h" +#include "memdebug.h" + +#define TEST_HANG_TIMEOUT 60 * 1000 + +#define PROXY libtest_arg2 +#define PROXYUSERPWD libtest_arg3 +#define HOST test_argv[4] + +#define NUM_HANDLES 2 + +CURL *eh[NUM_HANDLES]; + +static int init(int num, CURLM *cm, const char* url, const char* userpwd, + struct curl_slist *headers) +{ + int res = 0; + + res_easy_init(eh[num]); + if(res) + goto init_failed; + + res_easy_setopt(eh[num], CURLOPT_URL, url); + if(res) + goto init_failed; + + res_easy_setopt(eh[num], CURLOPT_PROXY, PROXY); + if(res) + goto init_failed; + + res_easy_setopt(eh[num], CURLOPT_PROXYUSERPWD, userpwd); + if(res) + goto init_failed; + + res_easy_setopt(eh[num], CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY); + if(res) + goto init_failed; + + res_easy_setopt(eh[num], CURLOPT_VERBOSE, 1L); + if(res) + goto init_failed; + + res_easy_setopt(eh[num], CURLOPT_HEADER, 1L); + if(res) + goto init_failed; + + res_easy_setopt(eh[num], CURLOPT_HTTPHEADER, headers); /* custom Host: */ + if(res) + goto init_failed; + + res_multi_add_handle(cm, eh[num]); + if(res) + goto init_failed; + + return 0; /* success */ + +init_failed: + + curl_easy_cleanup(eh[num]); + eh[num] = NULL; + + return res; /* failure */ +} + +static int loop(int num, CURLM *cm, const char* url, const char* userpwd, + struct curl_slist *headers) +{ + CURLMsg *msg; + long L; + int Q, U = -1; + fd_set R, W, E; + struct timeval T; + int res = 0; + + res = init(num, cm, url, userpwd, headers); + if(res) + return res; + + while (U) { + + int M = -99; + + res_multi_perform(cm, &U); + if(res) + return res; + + res_test_timedout(); + if(res) + return res; + + if (U) { + FD_ZERO(&R); + FD_ZERO(&W); + FD_ZERO(&E); + + res_multi_fdset(cm, &R, &W, &E, &M); + if(res) + return res; + + /* At this point, M is guaranteed to be greater or equal than -1. */ + + res_multi_timeout(cm, &L); + if(res) + return res; + + /* At this point, L is guaranteed to be greater or equal than -1. */ + + if(L != -1) { + int itimeout = (L > (long)INT_MAX) ? INT_MAX : (int)L; + T.tv_sec = itimeout/1000; + T.tv_usec = (itimeout%1000)*1000; + } + else { + T.tv_sec = 5; + T.tv_usec = 0; + } + + res_select_test(M+1, &R, &W, &E, &T); + if(res) + return res; + } + + while((msg = curl_multi_info_read(cm, &Q)) != NULL) { + if(msg->msg == CURLMSG_DONE) { + int i; + CURL *e = msg->easy_handle; + fprintf(stderr, "R: %d - %s\n", (int)msg->data.result, + curl_easy_strerror(msg->data.result)); + curl_multi_remove_handle(cm, e); + curl_easy_cleanup(e); + for(i=0; i < NUM_HANDLES; i++) { + if(eh[i] == e) { + eh[i] = NULL; + break; + } + } + } + else + fprintf(stderr, "E: CURLMsg (%d)\n", (int)msg->msg); + } + + res_test_timedout(); + if(res) + return res; + } + + return 0; /* success */ +} + +int test(char *URL) +{ + CURLM *cm = NULL; + struct curl_slist *headers = NULL; + char buffer[246]; /* naively fixed-size */ + int res = 0; + int i; + + for(i=0; i < NUM_HANDLES; i++) + eh[i] = NULL; + + start_test_timing(); + + if(test_argc < 4) + return 99; + + sprintf(buffer, "Host: %s", HOST); + + /* now add a custom Host: header */ + headers = curl_slist_append(headers, buffer); + if(!headers) { + fprintf(stderr, "curl_slist_append() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + res_global_init(CURL_GLOBAL_ALL); + if(res) { + curl_slist_free_all(headers); + return res; + } + + res_multi_init(cm); + if(res) { + curl_global_cleanup(); + curl_slist_free_all(headers); + return res; + } + + res = loop(0, cm, URL, PROXYUSERPWD, headers); + if(res) + goto test_cleanup; + + fprintf(stderr, "lib540: now we do the request again\n"); + + res = loop(1, cm, URL, PROXYUSERPWD, headers); + +test_cleanup: + + /* proper cleanup sequence - type PB */ + + for(i=0; i < NUM_HANDLES; i++) { + curl_multi_remove_handle(cm, eh[i]); + curl_easy_cleanup(eh[i]); + } + + curl_multi_cleanup(cm); + curl_global_cleanup(); + + curl_slist_free_all(headers); + + return res; +} diff --git a/tests/libtest/lib541.c b/tests/libtest/lib541.c new file mode 100644 index 000000000..5fe8dd8ad --- /dev/null +++ b/tests/libtest/lib541.c @@ -0,0 +1,117 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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" + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#include "memdebug.h" + +/* + * Two FTP uploads, the second with no content sent. + */ + +int test(char *URL) +{ + CURL *curl; + CURLcode res = CURLE_OK; + FILE *hd_src ; + int hd ; + struct_stat file_info; + int error; + + if (!libtest_arg2) { + fprintf(stderr, "Usage: <url> <file-to-upload>\n"); + return -1; + } + + hd_src = fopen(libtest_arg2, "rb"); + if(NULL == hd_src) { + error = ERRNO; + fprintf(stderr, "fopen() failed with error: %d %s\n", + error, strerror(error)); + fprintf(stderr, "Error opening file: %s\n", libtest_arg2); + return -2; /* if this happens things are major weird */ + } + + /* get the file size of the local file */ + hd = fstat(fileno(hd_src), &file_info); + if(hd == -1) { + /* can't open file, bail out */ + error = ERRNO; + fprintf(stderr, "fstat() failed with error: %d %s\n", + error, strerror(error)); + fprintf(stderr, "ERROR: cannot open file %s\n", libtest_arg2); + fclose(hd_src); + return -1; + } + + if(! file_info.st_size) { + fprintf(stderr, "ERROR: file %s has zero size!\n", libtest_arg2); + fclose(hd_src); + return -4; + } + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + fclose(hd_src); + return TEST_ERR_MAJOR_BAD; + } + + /* get a curl handle */ + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + fclose(hd_src); + return TEST_ERR_MAJOR_BAD; + } + + /* enable uploading */ + test_setopt(curl, CURLOPT_UPLOAD, 1L); + + /* enable verbose */ + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + /* specify target */ + test_setopt(curl,CURLOPT_URL, URL); + + /* now specify which file to upload */ + test_setopt(curl, CURLOPT_INFILE, hd_src); + + /* Now run off and do what you've been told! */ + res = curl_easy_perform(curl); + + /* and now upload the exact same again, but without rewinding so it already + is at end of file */ + res = curl_easy_perform(curl); + +test_cleanup: + + /* close the local file */ + fclose(hd_src); + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib542.c b/tests/libtest/lib542.c new file mode 100644 index 000000000..84f493f3e --- /dev/null +++ b/tests/libtest/lib542.c @@ -0,0 +1,72 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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" + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#include "memdebug.h" + +/* + * FTP get with NOBODY but no HEADER + */ + +int test(char *URL) +{ + CURL *curl; + CURLcode res = CURLE_OK; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + /* get a curl handle */ + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + /* enable verbose */ + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + /* enable NOBODY */ + test_setopt(curl, CURLOPT_NOBODY, 1L); + + /* disable HEADER */ + test_setopt(curl, CURLOPT_HEADER, 0L); + + /* specify target */ + test_setopt(curl,CURLOPT_URL, URL); + + /* Now run off and do what you've been told! */ + res = curl_easy_perform(curl); + +test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib543.c b/tests/libtest/lib543.c new file mode 100644 index 000000000..08d9c4544 --- /dev/null +++ b/tests/libtest/lib543.c @@ -0,0 +1,54 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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. + * + ***************************************************************************/ +/* Based on Alex Fishman's bug report on September 30, 2007 */ + +#include "test.h" + +#include "memdebug.h" + +int test(char *URL) +{ + unsigned char a[] = {0x9c, 0x26, 0x4b, 0x3d, 0x49, 0x4, 0xa1, 0x1, + 0xe0, 0xd8, 0x7c, 0x20, 0xb7, 0xef, 0x53, 0x29, 0xfa, + 0x1d, 0x57, 0xe1}; + + CURL *easy; + int asize; + char *s; + (void)URL; + + if ((easy = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + asize = (int)sizeof(a); + + s = curl_easy_escape(easy, (char*)a, asize); + + printf("%s\n", s); + + curl_free(s); + curl_easy_cleanup(easy); + + return 0; +} diff --git a/tests/libtest/lib544.c b/tests/libtest/lib544.c new file mode 100644 index 000000000..b766187f2 --- /dev/null +++ b/tests/libtest/lib544.c @@ -0,0 +1,78 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +static char teststring[] = +#ifdef CURL_DOES_CONVERSIONS + /* ASCII representation with escape sequences for non-ASCII platforms */ + "\x54\x68\x69\x73\x00\x20\x69\x73\x20\x74\x65\x73\x74\x20\x62\x69\x6e\x61" + "\x72\x79\x20\x64\x61\x74\x61\x20\x77\x69\x74\x68\x20\x61\x6e\x20\x65\x6d" + "\x62\x65\x64\x64\x65\x64\x20\x4e\x55\x4c\x20\x62\x79\x74\x65\x0a"; +#else + "This\0 is test binary data with an embedded NUL byte\n"; +#endif + + +int test(char *URL) +{ + CURL *curl; + CURLcode res=CURLE_OK; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + /* First set the URL that is about to receive our POST. */ + test_setopt(curl, CURLOPT_URL, URL); + +#ifdef LIB545 + test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) sizeof teststring - 1); +#endif + + test_setopt(curl, CURLOPT_COPYPOSTFIELDS, teststring); + + test_setopt(curl, CURLOPT_VERBOSE, 1L); /* show verbose for debug */ + test_setopt(curl, CURLOPT_HEADER, 1L); /* include header */ + + /* Update the original data to detect non-copy. */ + strcpy(teststring, "FAIL"); + + /* Now, this is a POST request with binary 0 embedded in POST data. */ + res = curl_easy_perform(curl); + +test_cleanup: + + /* always cleanup */ + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} diff --git a/tests/libtest/lib547.c b/tests/libtest/lib547.c new file mode 100644 index 000000000..c82bc3f23 --- /dev/null +++ b/tests/libtest/lib547.c @@ -0,0 +1,129 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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. + * + ***************************************************************************/ +/* argv1 = URL + * argv2 = proxy + * argv3 = proxyuser:password + */ + +#include "test.h" + +#include "memdebug.h" + +#ifdef CURL_DOES_CONVERSIONS + /* ASCII representation with escape sequences for non-ASCII platforms */ +# define UPLOADTHIS "\x74\x68\x69\x73\x20\x69\x73\x20\x74\x68\x65\x20\x62" \ + "\x6c\x75\x72\x62\x20\x77\x65\x20\x77\x61\x6e\x74\x20" \ + "\x74\x6f\x20\x75\x70\x6c\x6f\x61\x64\x0a" +#else +# define UPLOADTHIS "this is the blurb we want to upload\n" +#endif + +#ifndef LIB548 +static size_t readcallback(void *ptr, + size_t size, + size_t nmemb, + void *clientp) +{ + int *counter = (int *)clientp; + + if(*counter) { + /* only do this once and then require a clearing of this */ + fprintf(stderr, "READ ALREADY DONE!\n"); + return 0; + } + (*counter)++; /* bump */ + + if(size * nmemb > strlen(UPLOADTHIS)) { + fprintf(stderr, "READ!\n"); + strcpy(ptr, UPLOADTHIS); + return strlen(UPLOADTHIS); + } + fprintf(stderr, "READ NOT FINE!\n"); + return 0; +} +static curlioerr ioctlcallback(CURL *handle, + int cmd, + void *clientp) +{ + int *counter = (int *)clientp; + (void)handle; /* unused */ + if(cmd == CURLIOCMD_RESTARTREAD) { + fprintf(stderr, "REWIND!\n"); + *counter = 0; /* clear counter to make the read callback restart */ + } + return CURLIOE_OK; +} + + + +#endif + +int test(char *URL) +{ + CURLcode res; + CURL *curl; +#ifndef LIB548 + int counter=0; +#endif + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_HEADER, 1L); +#ifdef LIB548 + /* set the data to POST with a mere pointer to a zero-terminated string */ + test_setopt(curl, CURLOPT_POSTFIELDS, UPLOADTHIS); +#else + /* 547 style, which means reading the POST data from a callback */ + test_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctlcallback); + test_setopt(curl, CURLOPT_IOCTLDATA, &counter); + test_setopt(curl, CURLOPT_READFUNCTION, readcallback); + test_setopt(curl, CURLOPT_READDATA, &counter); + /* We CANNOT do the POST fine without setting the size (or choose chunked)! */ + test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(UPLOADTHIS)); +#endif + test_setopt(curl, CURLOPT_POST, 1L); + test_setopt(curl, CURLOPT_PROXY, libtest_arg2); + test_setopt(curl, CURLOPT_PROXYUSERPWD, libtest_arg3); + test_setopt(curl, CURLOPT_PROXYAUTH, + (long) (CURLAUTH_NTLM | CURLAUTH_DIGEST | CURLAUTH_BASIC) ); + + res = curl_easy_perform(curl); + +test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} + diff --git a/tests/libtest/lib549.c b/tests/libtest/lib549.c new file mode 100644 index 000000000..a1568c88f --- /dev/null +++ b/tests/libtest/lib549.c @@ -0,0 +1,65 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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. + * + ***************************************************************************/ +/* argv1 = URL + * argv2 = proxy + * argv3 = non-zero means ASCII transfer + */ + +#include "test.h" + +#include "memdebug.h" + +int test(char *URL) +{ + CURLcode res; + CURL *curl; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_PROXY, libtest_arg2); + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_PROXY_TRANSFER_MODE, 1L); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + if(libtest_arg3) { + /* enable ascii/text mode */ + test_setopt(curl, CURLOPT_TRANSFERTEXT, 1L); + } + + res = curl_easy_perform(curl); + +test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} + diff --git a/tests/libtest/lib552.c b/tests/libtest/lib552.c new file mode 100644 index 000000000..2cc942ad4 --- /dev/null +++ b/tests/libtest/lib552.c @@ -0,0 +1,220 @@ +/*************************************************************************** + * _ _ ____ _ + * 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. + * + ***************************************************************************/ +/* argv1 = URL + * argv2 = proxy with embedded user+password + */ + +#include "test.h" + +#include "warnless.h" +#include "memdebug.h" + +struct data { + char trace_ascii; /* 1 or 0 */ +}; + +static +void dump(const char *text, + FILE *stream, unsigned char *ptr, size_t size, + char nohex) +{ + size_t i; + size_t c; + + unsigned int width=0x10; + + if(nohex) + /* without the hex output, we can fit more on screen */ + width = 0x40; + + fprintf(stream, "%s, %d bytes (0x%x)\n", text, (int)size, (int)size); + + for(i=0; i<size; i+= width) { + + fprintf(stream, "%04x: ", (int)i); + + if(!nohex) { + /* hex not disabled, show it */ + for(c = 0; c < width; c++) + if(i+c < size) + fprintf(stream, "%02x ", ptr[i+c]); + else + fputs(" ", stream); + } + + for(c = 0; (c < width) && (i+c < size); c++) { + /* check for 0D0A; if found, skip past and start a new line of output */ + if (nohex && (i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) { + i+=(c+2-width); + break; + } + fprintf(stream, "%c", + (ptr[i+c]>=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.'); + /* check again for 0D0A, to avoid an extra \n if it's at width */ + if (nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) { + i+=(c+3-width); + break; + } + } + fputc('\n', stream); /* newline */ + } + fflush(stream); +} + +static +int my_trace(CURL *handle, curl_infotype type, + char *data, size_t size, + void *userp) +{ + struct data *config = (struct data *)userp; + const char *text; + (void)handle; /* prevent compiler warning */ + + switch (type) { + case CURLINFO_TEXT: + fprintf(stderr, "== Info: %s", (char *)data); + default: /* in case a new one is introduced to shock us */ + return 0; + + case CURLINFO_HEADER_OUT: + text = "=> Send header"; + break; + case CURLINFO_DATA_OUT: + text = "=> Send data"; + break; + case CURLINFO_SSL_DATA_OUT: + text = "=> Send SSL data"; + break; + case CURLINFO_HEADER_IN: + text = "<= Recv header"; + break; + case CURLINFO_DATA_IN: + text = "<= Recv data"; + break; + case CURLINFO_SSL_DATA_IN: + text = "<= Recv SSL data"; + break; + } + + dump(text, stderr, (unsigned char *)data, size, config->trace_ascii); + return 0; +} + + +static size_t current_offset = 0; +static char databuf[70000]; /* MUST be more than 64k OR MAX_INITIAL_POST_SIZE */ + +static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream) +{ + size_t amount = nmemb * size; /* Total bytes curl wants */ + size_t available = sizeof(databuf) - current_offset; /* What we have to give */ + size_t given = amount < available ? amount : available; /* What is given */ + (void)stream; + memcpy(ptr, databuf + current_offset, given); + current_offset += given; + return given; +} + + +static size_t write_callback(void *ptr, size_t size, size_t nmemb, void *stream) +{ + int amount = curlx_uztosi(size * nmemb); + printf("%.*s", amount, (char *)ptr); + (void)stream; + return size * nmemb; +} + + +static curlioerr ioctl_callback(CURL * handle, int cmd, void *clientp) +{ + (void)clientp; + if (cmd == CURLIOCMD_RESTARTREAD ) { + printf("APPLICATION: recieved a CURLIOCMD_RESTARTREAD request\n"); + printf("APPLICATION: ** REWINDING! **\n"); + current_offset = 0; + return CURLIOE_OK; + } + (void)handle; + return CURLIOE_UNKNOWNCMD; +} + + + +int test(char *URL) +{ + CURL *curl; + CURLcode res = CURLE_OUT_OF_MEMORY; + struct data config; + size_t i; + static const char fill[] = "test data"; + + config.trace_ascii = 1; /* enable ascii tracing */ + + if((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace); + test_setopt(curl, CURLOPT_DEBUGDATA, &config); + /* the DEBUGFUNCTION has no effect until we enable VERBOSE */ + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + /* setup repeated data string */ + for (i=0; i < sizeof(databuf); ++i) + databuf[i] = fill[i % sizeof fill]; + + /* Post */ + test_setopt(curl, CURLOPT_POST, 1L); + +#ifdef CURL_DOES_CONVERSIONS + /* Convert the POST data to ASCII */ + test_setopt(curl, CURLOPT_TRANSFERTEXT, 1L); +#endif + + /* Setup read callback */ + test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) sizeof(databuf)); + test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + + /* Write callback */ + test_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); + + /* Ioctl function */ + test_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_callback); + + test_setopt(curl, CURLOPT_PROXY, libtest_arg2); + + test_setopt(curl, CURLOPT_URL, URL); + + /* Accept any auth. But for this bug configure proxy with DIGEST, basic might work too, not NTLM */ + test_setopt(curl, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY); + + res = curl_easy_perform(curl); + fprintf(stderr, "curl_easy_perform = %d\n", (int)res); + +test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + return (int)res; +} diff --git a/tests/libtest/lib553.c b/tests/libtest/lib553.c new file mode 100644 index 000000000..cb1cefd5e --- /dev/null +++ b/tests/libtest/lib553.c @@ -0,0 +1,114 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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. + * + ***************************************************************************/ + +/* This test case and code is based on the bug recipe Joe Malicki provided for + * bug report #1871269, fixed on Jan 14 2008 before the 7.18.0 release. + */ + +#include "test.h" + +#include "memdebug.h" + +#define POSTLEN 40960 + +static size_t myreadfunc(void *ptr, size_t size, size_t nmemb, void *stream) +{ + static size_t total=POSTLEN; + static char buf[1024]; + (void)stream; + + memset(buf, 'A', sizeof(buf)); + + size *= nmemb; + if (size > total) + size = total; + + if(size > sizeof(buf)) + size = sizeof(buf); + + memcpy(ptr, buf, size); + total -= size; + return size; +} + +#define NUM_HEADERS 8 +#define SIZE_HEADERS 5000 + +static char buf[SIZE_HEADERS + 100]; + +int test(char *URL) +{ + CURL *curl; + CURLcode res = CURLE_FAILED_INIT; + int i; + struct curl_slist *headerlist=NULL, *hl; + + if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + for (i = 0; i < NUM_HEADERS; i++) { + int len = sprintf(buf, "Header%d: ", i); + memset(&buf[len], 'A', SIZE_HEADERS); + buf[len + SIZE_HEADERS]=0; /* zero terminate */ + hl = curl_slist_append(headerlist, buf); + if (!hl) + goto test_cleanup; + headerlist = hl; + } + + hl = curl_slist_append(headerlist, "Expect: "); + if (!hl) + goto test_cleanup; + headerlist = hl; + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_HTTPHEADER, headerlist); + test_setopt(curl, CURLOPT_POST, 1L); +#ifdef CURL_DOES_CONVERSIONS + /* Convert the POST data to ASCII */ + test_setopt(curl, CURLOPT_TRANSFERTEXT, 1L); +#endif + test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)POSTLEN); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_HEADER, 1L); + test_setopt(curl, CURLOPT_READFUNCTION, myreadfunc); + + res = curl_easy_perform(curl); + +test_cleanup: + + curl_easy_cleanup(curl); + + curl_slist_free_all(headerlist); + + curl_global_cleanup(); + + return (int)res; +} diff --git a/tests/libtest/lib554.c b/tests/libtest/lib554.c new file mode 100644 index 000000000..0596f3ef1 --- /dev/null +++ b/tests/libtest/lib554.c @@ -0,0 +1,199 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "memdebug.h" + +static char data[]= +#ifdef CURL_DOES_CONVERSIONS + /* ASCII representation with escape sequences for non-ASCII platforms */ + "\x74\x68\x69\x73\x20\x69\x73\x20\x77\x68\x61\x74\x20\x77\x65\x20\x70" + "\x6f\x73\x74\x20\x74\x6f\x20\x74\x68\x65\x20\x73\x69\x6c\x6c\x79\x20" + "\x77\x65\x62\x20\x73\x65\x72\x76\x65\x72\x0a"; +#else + "this is what we post to the silly web server\n"; +#endif + +struct WriteThis { + char *readptr; + size_t sizeleft; +}; + +static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp) +{ +#ifdef LIB587 + (void)ptr; + (void)size; + (void)nmemb; + (void)userp; + return CURL_READFUNC_ABORT; +#else + + struct WriteThis *pooh = (struct WriteThis *)userp; + + if(size*nmemb < 1) + return 0; + + if(pooh->sizeleft) { + *(char *)ptr = pooh->readptr[0]; /* copy one single byte */ + pooh->readptr++; /* advance pointer */ + pooh->sizeleft--; /* less data left */ + return 1; /* we return 1 byte at a time! */ + } + + return 0; /* no more data left to deliver */ +#endif +} + +int test(char *URL) +{ + CURL *curl; + CURLcode res=CURLE_OK; + CURLFORMcode formrc; + + struct curl_httppost *formpost=NULL; + struct curl_httppost *lastptr=NULL; + struct WriteThis pooh; + struct WriteThis pooh2; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + pooh.readptr = data; + pooh.sizeleft = strlen(data); + + /* Fill in the file upload field */ + formrc = curl_formadd(&formpost, + &lastptr, + CURLFORM_COPYNAME, "sendfile", + CURLFORM_STREAM, &pooh, + CURLFORM_CONTENTSLENGTH, (long)pooh.sizeleft, + CURLFORM_FILENAME, "postit2.c", + CURLFORM_END); + + if(formrc) + printf("curl_formadd(1) = %d\n", (int)formrc); + + /* Now add the same data with another name and make it not look like + a file upload but still using the callback */ + + pooh2.readptr = data; + pooh2.sizeleft = strlen(data); + + /* Fill in the file upload field */ + formrc = curl_formadd(&formpost, + &lastptr, + CURLFORM_COPYNAME, "callbackdata", + CURLFORM_STREAM, &pooh2, + CURLFORM_CONTENTSLENGTH, (long)pooh2.sizeleft, + CURLFORM_END); + + if(formrc) + printf("curl_formadd(1) = %d\n", (int)formrc); + + /* Fill in the filename field */ + formrc = curl_formadd(&formpost, + &lastptr, + CURLFORM_COPYNAME, "filename", +#ifdef CURL_DOES_CONVERSIONS + /* ASCII representation with escape + sequences for non-ASCII platforms */ + CURLFORM_COPYCONTENTS, + "\x70\x6f\x73\x74\x69\x74\x32\x2e\x63", +#else + CURLFORM_COPYCONTENTS, "postit2.c", +#endif + CURLFORM_END); + + if(formrc) + printf("curl_formadd(2) = %d\n", (int)formrc); + + /* Fill in a submit field too */ + formrc = curl_formadd(&formpost, + &lastptr, + CURLFORM_COPYNAME, "submit", +#ifdef CURL_DOES_CONVERSIONS + /* ASCII representation with escape + sequences for non-ASCII platforms */ + CURLFORM_COPYCONTENTS, "\x73\x65\x6e\x64", +#else + CURLFORM_COPYCONTENTS, "send", +#endif + CURLFORM_END); + + if(formrc) + printf("curl_formadd(3) = %d\n", (int)formrc); + + formrc = curl_formadd(&formpost, &lastptr, + CURLFORM_COPYNAME, "somename", + CURLFORM_BUFFER, "somefile.txt", + CURLFORM_BUFFERPTR, "blah blah", + CURLFORM_BUFFERLENGTH, (long)9, + CURLFORM_END); + + if(formrc) + printf("curl_formadd(4) = %d\n", (int)formrc); + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_formfree(formpost); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + /* First set the URL that is about to receive our POST. */ + test_setopt(curl, CURLOPT_URL, URL); + + /* Now specify we want to POST data */ + test_setopt(curl, CURLOPT_POST, 1L); + + /* Set the expected POST size */ + test_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)pooh.sizeleft); + + /* we want to use our own read function */ + test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + + /* send a multi-part formpost */ + test_setopt(curl, CURLOPT_HTTPPOST, formpost); + + /* get verbose debug output please */ + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + /* include headers in the output */ + test_setopt(curl, CURLOPT_HEADER, 1L); + + /* Perform the request, res will get the return code */ + res = curl_easy_perform(curl); + +test_cleanup: + + /* always cleanup */ + curl_easy_cleanup(curl); + curl_global_cleanup(); + + /* now cleanup the formpost chain */ + curl_formfree(formpost); + + return res; +} diff --git a/tests/libtest/lib555.c b/tests/libtest/lib555.c new file mode 100644 index 000000000..49a81bf57 --- /dev/null +++ b/tests/libtest/lib555.c @@ -0,0 +1,159 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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. + * + ***************************************************************************/ + +/* This test case is supposed to be identical to 547 except that this uses the + * multi interface and 547 is easy interface. + * + * argv1 = URL + * argv2 = proxy + * argv3 = proxyuser:password + */ + +#include "test.h" +#include "testutil.h" +#include "warnless.h" +#include "memdebug.h" + +#define TEST_HANG_TIMEOUT 60 * 1000 + +#define UPLOADTHIS "this is the blurb we want to upload\n" + +static size_t readcallback(void *ptr, + size_t size, + size_t nmemb, + void *clientp) +{ + int *counter = (int *)clientp; + + if(*counter) { + /* only do this once and then require a clearing of this */ + fprintf(stderr, "READ ALREADY DONE!\n"); + return 0; + } + (*counter)++; /* bump */ + + if(size * nmemb > strlen(UPLOADTHIS)) { + fprintf(stderr, "READ!\n"); + strcpy(ptr, UPLOADTHIS); + return strlen(UPLOADTHIS); + } + fprintf(stderr, "READ NOT FINE!\n"); + return 0; +} +static curlioerr ioctlcallback(CURL *handle, + int cmd, + void *clientp) +{ + int *counter = (int *)clientp; + (void)handle; /* unused */ + if(cmd == CURLIOCMD_RESTARTREAD) { + fprintf(stderr, "REWIND!\n"); + *counter = 0; /* clear counter to make the read callback restart */ + } + return CURLIOE_OK; +} + + +int test(char *URL) +{ + int res = 0; + CURL *curl = NULL; + int counter=0; + CURLM *m = NULL; + int running=1; + + start_test_timing(); + + global_init(CURL_GLOBAL_ALL); + + easy_init(curl); + + easy_setopt(curl, CURLOPT_URL, URL); + easy_setopt(curl, CURLOPT_VERBOSE, 1L); + easy_setopt(curl, CURLOPT_HEADER, 1L); + + /* read the POST data from a callback */ + easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctlcallback); + easy_setopt(curl, CURLOPT_IOCTLDATA, &counter); + easy_setopt(curl, CURLOPT_READFUNCTION, readcallback); + easy_setopt(curl, CURLOPT_READDATA, &counter); + /* We CANNOT do the POST fine without setting the size (or choose chunked)! */ + easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(UPLOADTHIS)); + + easy_setopt(curl, CURLOPT_POST, 1L); +#ifdef CURL_DOES_CONVERSIONS + /* Convert the POST data to ASCII. */ + easy_setopt(curl, CURLOPT_TRANSFERTEXT, 1L); +#endif + easy_setopt(curl, CURLOPT_PROXY, libtest_arg2); + easy_setopt(curl, CURLOPT_PROXYUSERPWD, libtest_arg3); + easy_setopt(curl, CURLOPT_PROXYAUTH, + (long) (CURLAUTH_NTLM | CURLAUTH_DIGEST | CURLAUTH_BASIC) ); + + multi_init(m); + + multi_add_handle(m, curl); + + while (running) { + struct timeval timeout; + fd_set fdread, fdwrite, fdexcep; + int maxfd = -99; + + timeout.tv_sec = 0; + timeout.tv_usec = 100000L; /* 100 ms */ + + multi_perform(m, &running); + + abort_on_test_timeout(); + +#ifdef TPF + sleep(1); /* avoid ctl-10 dump */ +#endif + + if(!running) + break; /* done */ + + FD_ZERO(&fdread); + FD_ZERO(&fdwrite); + FD_ZERO(&fdexcep); + + multi_fdset(m, &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(); + } + +test_cleanup: + + /* proper cleanup sequence - type PA */ + + curl_multi_remove_handle(m, curl); + curl_multi_cleanup(m); + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} + diff --git a/tests/libtest/lib556.c b/tests/libtest/lib556.c new file mode 100644 index 000000000..98062209f --- /dev/null +++ b/tests/libtest/lib556.c @@ -0,0 +1,106 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +/* For Windows, mainly (may be moved in a config file?) */ +#ifndef STDIN_FILENO + #define STDIN_FILENO 0 +#endif +#ifndef STDOUT_FILENO + #define STDOUT_FILENO 1 +#endif +#ifndef STDERR_FILENO + #define STDERR_FILENO 2 +#endif + +int test(char *URL) +{ + CURLcode res; + CURL *curl; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_CONNECT_ONLY, 1L); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + res = curl_easy_perform(curl); + + if(!res) { + /* we are connected, now get a HTTP document the raw way */ + const char *request = +#ifdef CURL_DOES_CONVERSIONS + /* ASCII representation with escape sequences for non-ASCII platforms */ + "\x47\x45\x54\x20\x2f\x35\x35\x36\x20\x48\x54\x54\x50\x2f\x31\x2e" + "\x32\x0d\x0a\x48\x6f\x73\x74\x3a\x20\x6e\x69\x6e\x6a\x61\x0d\x0a" + "\x0d\x0a"; +#else + "GET /556 HTTP/1.2\r\n" + "Host: ninja\r\n\r\n"; +#endif + size_t iolen; + char buf[1024]; + + res = curl_easy_send(curl, request, strlen(request), &iolen); + + if(!res) { + /* we assume that sending always work */ + size_t total=0; + + do { + /* busy-read like crazy */ + res = curl_easy_recv(curl, buf, 1024, &iolen); + +#ifdef TPF + sleep(1); /* avoid ctl-10 dump */ +#endif + + if(iolen) { + /* send received stuff to stdout */ + if(!write(STDOUT_FILENO, buf, iolen)) + break; + } + total += iolen; + + } while(((res == CURLE_OK) || (res == CURLE_AGAIN)) && (total < 129)); + } + } + +test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} + diff --git a/tests/libtest/lib557.c b/tests/libtest/lib557.c new file mode 100644 index 000000000..dc3bcae86 --- /dev/null +++ b/tests/libtest/lib557.c @@ -0,0 +1,1401 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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. + * + ***************************************************************************/ + +/* + * The purpose of this test is to minimally exercise libcurl's internal + * curl_m*printf formatting capabilities and handling of some data types. + */ + +#include "test.h" + +#include <curl/mprintf.h> + +#include "memdebug.h" + + +#if (CURL_SIZEOF_CURL_OFF_T > CURL_SIZEOF_LONG) +# define MPRNT_SUFFIX_CURL_OFF_T LL +#else +# define MPRNT_SUFFIX_CURL_OFF_T L +#endif + + +#ifdef CURL_ISOCPP +# define MPRNT_OFF_T_C_HELPER2(Val,Suffix) Val ## Suffix +#else +# define MPRNT_OFF_T_C_HELPER2(Val,Suffix) Val/**/Suffix +#endif +#define MPRNT_OFF_T_C_HELPER1(Val,Suffix) MPRNT_OFF_T_C_HELPER2(Val,Suffix) +#define MPRNT_OFF_T_C(Val) MPRNT_OFF_T_C_HELPER1(Val,MPRNT_SUFFIX_CURL_OFF_T) + + +#define BUFSZ 256 +#define USHORT_TESTS_ARRSZ 1 + 100 +#define SSHORT_TESTS_ARRSZ 1 + 100 +#define UINT_TESTS_ARRSZ 1 + 100 +#define SINT_TESTS_ARRSZ 1 + 100 +#define ULONG_TESTS_ARRSZ 1 + 100 +#define SLONG_TESTS_ARRSZ 1 + 100 +#define COFFT_TESTS_ARRSZ 1 + 100 + + +struct unsshort_st { + unsigned short num; /* unsigned short */ + const char *expected; /* expected string */ + char result[BUFSZ]; /* result string */ +}; + + +struct sigshort_st { + short num; /* signed short */ + const char *expected; /* expected string */ + char result[BUFSZ]; /* result string */ +}; + + +struct unsint_st { + unsigned int num; /* unsigned int */ + const char *expected; /* expected string */ + char result[BUFSZ]; /* result string */ +}; + + +struct sigint_st { + int num; /* signed int */ + const char *expected; /* expected string */ + char result[BUFSZ]; /* result string */ +}; + + +struct unslong_st { + unsigned long num; /* unsigned long */ + const char *expected; /* expected string */ + char result[BUFSZ]; /* result string */ +}; + + +struct siglong_st { + long num; /* signed long */ + const char *expected; /* expected string */ + char result[BUFSZ]; /* result string */ +}; + + +struct curloff_st { + curl_off_t num; /* curl_off_t */ + const char *expected; /* expected string */ + char result[BUFSZ]; /* result string */ +}; + + +static struct unsshort_st us_test[USHORT_TESTS_ARRSZ]; +static struct sigshort_st ss_test[SSHORT_TESTS_ARRSZ]; +static struct unsint_st ui_test[UINT_TESTS_ARRSZ]; +static struct sigint_st si_test[SINT_TESTS_ARRSZ]; +static struct unslong_st ul_test[ULONG_TESTS_ARRSZ]; +static struct siglong_st sl_test[SLONG_TESTS_ARRSZ]; +static struct curloff_st co_test[COFFT_TESTS_ARRSZ]; + + +static int test_unsigned_short_formatting(void) +{ + int i, j; + int num_ushort_tests; + int failed = 0; + +#if (SIZEOF_SHORT == 1) + + i=1; us_test[i].num = 0xFFU; us_test[i].expected = "256"; + i++; us_test[i].num = 0xF0U; us_test[i].expected = "240"; + i++; us_test[i].num = 0x0FU; us_test[i].expected = "15"; + + i++; us_test[i].num = 0xE0U; us_test[i].expected = "224"; + i++; us_test[i].num = 0x0EU; us_test[i].expected = "14"; + + i++; us_test[i].num = 0xC0U; us_test[i].expected = "192"; + i++; us_test[i].num = 0x0CU; us_test[i].expected = "12"; + + i++; us_test[i].num = 0x01U; us_test[i].expected = "1"; + i++; us_test[i].num = 0x00U; us_test[i].expected = "0"; + + num_ushort_tests = i; + +#elif (SIZEOF_SHORT == 2) + + i=1; us_test[i].num = 0xFFFFU; us_test[i].expected = "65535"; + i++; us_test[i].num = 0xFF00U; us_test[i].expected = "65280"; + i++; us_test[i].num = 0x00FFU; us_test[i].expected = "255"; + + i++; us_test[i].num = 0xF000U; us_test[i].expected = "61440"; + i++; us_test[i].num = 0x0F00U; us_test[i].expected = "3840"; + i++; us_test[i].num = 0x00F0U; us_test[i].expected = "240"; + i++; us_test[i].num = 0x000FU; us_test[i].expected = "15"; + + i++; us_test[i].num = 0xC000U; us_test[i].expected = "49152"; + i++; us_test[i].num = 0x0C00U; us_test[i].expected = "3072"; + i++; us_test[i].num = 0x00C0U; us_test[i].expected = "192"; + i++; us_test[i].num = 0x000CU; us_test[i].expected = "12"; + + i++; us_test[i].num = 0x0001U; us_test[i].expected = "1"; + i++; us_test[i].num = 0x0000U; us_test[i].expected = "0"; + + num_ushort_tests = i; + +#elif (SIZEOF_SHORT == 4) + + i=1; us_test[i].num = 0xFFFFFFFFU; us_test[i].expected = "4294967295"; + i++; us_test[i].num = 0xFFFF0000U; us_test[i].expected = "4294901760"; + i++; us_test[i].num = 0x0000FFFFU; us_test[i].expected = "65535"; + + i++; us_test[i].num = 0xFF000000U; us_test[i].expected = "4278190080"; + i++; us_test[i].num = 0x00FF0000U; us_test[i].expected = "16711680"; + i++; us_test[i].num = 0x0000FF00U; us_test[i].expected = "65280"; + i++; us_test[i].num = 0x000000FFU; us_test[i].expected = "255"; + + i++; us_test[i].num = 0xF0000000U; us_test[i].expected = "4026531840"; + i++; us_test[i].num = 0x0F000000U; us_test[i].expected = "251658240"; + i++; us_test[i].num = 0x00F00000U; us_test[i].expected = "15728640"; + i++; us_test[i].num = 0x000F0000U; us_test[i].expected = "983040"; + i++; us_test[i].num = 0x0000F000U; us_test[i].expected = "61440"; + i++; us_test[i].num = 0x00000F00U; us_test[i].expected = "3840"; + i++; us_test[i].num = 0x000000F0U; us_test[i].expected = "240"; + i++; us_test[i].num = 0x0000000FU; us_test[i].expected = "15"; + + i++; us_test[i].num = 0xC0000000U; us_test[i].expected = "3221225472"; + i++; us_test[i].num = 0x0C000000U; us_test[i].expected = "201326592"; + i++; us_test[i].num = 0x00C00000U; us_test[i].expected = "12582912"; + i++; us_test[i].num = 0x000C0000U; us_test[i].expected = "786432"; + i++; us_test[i].num = 0x0000C000U; us_test[i].expected = "49152"; + i++; us_test[i].num = 0x00000C00U; us_test[i].expected = "3072"; + i++; us_test[i].num = 0x000000C0U; us_test[i].expected = "192"; + i++; us_test[i].num = 0x0000000CU; us_test[i].expected = "12"; + + i++; us_test[i].num = 0x00000001U; us_test[i].expected = "1"; + i++; us_test[i].num = 0x00000000U; us_test[i].expected = "0"; + + num_ushort_tests = i; + +#endif + + for(i=1; i<=num_ushort_tests; i++) { + + for(j=0; j<BUFSZ; j++) + us_test[i].result[j] = 'X'; + us_test[i].result[BUFSZ-1] = '\0'; + + (void)curl_msprintf(us_test[i].result, "%hu", us_test[i].num); + + if(memcmp(us_test[i].result, + us_test[i].expected, + strlen(us_test[i].expected))) { + printf("unsigned short test #%.2d: Failed (Expected: %s Got: %s)\n", + i, us_test[i].expected, us_test[i].result); + failed++; + } + + } + + if(!failed) + printf("All curl_mprintf() unsigned short tests OK!\n"); + else + printf("Some curl_mprintf() unsigned short tests Failed!\n"); + + return failed; +} + + +static int test_signed_short_formatting(void) +{ + int i, j; + int num_sshort_tests; + int failed = 0; + +#if (SIZEOF_SHORT == 1) + + i=1; ss_test[i].num = 0x7F; ss_test[i].expected = "127"; + + i++; ss_test[i].num = 0x70; ss_test[i].expected = "112"; + i++; ss_test[i].num = 0x07; ss_test[i].expected = "7"; + + i++; ss_test[i].num = 0x50; ss_test[i].expected = "80"; + i++; ss_test[i].num = 0x05; ss_test[i].expected = "5"; + + i++; ss_test[i].num = 0x01; ss_test[i].expected = "1"; + i++; ss_test[i].num = 0x00; ss_test[i].expected = "0"; + + i++; ss_test[i].num = -0x7F -1; ss_test[i].expected = "-128"; + + i++; ss_test[i].num = -0x70 -1; ss_test[i].expected = "-113"; + i++; ss_test[i].num = -0x07 -1; ss_test[i].expected = "-8"; + + i++; ss_test[i].num = -0x50 -1; ss_test[i].expected = "-81"; + i++; ss_test[i].num = -0x05 -1; ss_test[i].expected = "-6"; + + i++; ss_test[i].num = 0x00 -1; ss_test[i].expected = "-1"; + + num_sshort_tests = i; + +#elif (SIZEOF_SHORT == 2) + + i=1; ss_test[i].num = 0x7FFF; ss_test[i].expected = "32767"; + i++; ss_test[i].num = 0x7FFE; ss_test[i].expected = "32766"; + i++; ss_test[i].num = 0x7FFD; ss_test[i].expected = "32765"; + i++; ss_test[i].num = 0x7F00; ss_test[i].expected = "32512"; + i++; ss_test[i].num = 0x07F0; ss_test[i].expected = "2032"; + i++; ss_test[i].num = 0x007F; ss_test[i].expected = "127"; + + i++; ss_test[i].num = 0x7000; ss_test[i].expected = "28672"; + i++; ss_test[i].num = 0x0700; ss_test[i].expected = "1792"; + i++; ss_test[i].num = 0x0070; ss_test[i].expected = "112"; + i++; ss_test[i].num = 0x0007; ss_test[i].expected = "7"; + + i++; ss_test[i].num = 0x5000; ss_test[i].expected = "20480"; + i++; ss_test[i].num = 0x0500; ss_test[i].expected = "1280"; + i++; ss_test[i].num = 0x0050; ss_test[i].expected = "80"; + i++; ss_test[i].num = 0x0005; ss_test[i].expected = "5"; + + i++; ss_test[i].num = 0x0001; ss_test[i].expected = "1"; + i++; ss_test[i].num = 0x0000; ss_test[i].expected = "0"; + + i++; ss_test[i].num = -0x7FFF -1; ss_test[i].expected = "-32768"; + i++; ss_test[i].num = -0x7FFE -1; ss_test[i].expected = "-32767"; + i++; ss_test[i].num = -0x7FFD -1; ss_test[i].expected = "-32766"; + i++; ss_test[i].num = -0x7F00 -1; ss_test[i].expected = "-32513"; + i++; ss_test[i].num = -0x07F0 -1; ss_test[i].expected = "-2033"; + i++; ss_test[i].num = -0x007F -1; ss_test[i].expected = "-128"; + + i++; ss_test[i].num = -0x7000 -1; ss_test[i].expected = "-28673"; + i++; ss_test[i].num = -0x0700 -1; ss_test[i].expected = "-1793"; + i++; ss_test[i].num = -0x0070 -1; ss_test[i].expected = "-113"; + i++; ss_test[i].num = -0x0007 -1; ss_test[i].expected = "-8"; + + i++; ss_test[i].num = -0x5000 -1; ss_test[i].expected = "-20481"; + i++; ss_test[i].num = -0x0500 -1; ss_test[i].expected = "-1281"; + i++; ss_test[i].num = -0x0050 -1; ss_test[i].expected = "-81"; + i++; ss_test[i].num = -0x0005 -1; ss_test[i].expected = "-6"; + + i++; ss_test[i].num = 0x0000 -1; ss_test[i].expected = "-1"; + + num_sshort_tests = i; + +#elif (SIZEOF_SHORT == 4) + + i=1; ss_test[i].num = 0x7FFFFFFF; ss_test[i].expected = "2147483647"; + i++; ss_test[i].num = 0x7FFFFFFE; ss_test[i].expected = "2147483646"; + i++; ss_test[i].num = 0x7FFFFFFD; ss_test[i].expected = "2147483645"; + i++; ss_test[i].num = 0x7FFF0000; ss_test[i].expected = "2147418112"; + i++; ss_test[i].num = 0x00007FFF; ss_test[i].expected = "32767"; + + i++; ss_test[i].num = 0x7F000000; ss_test[i].expected = "2130706432"; + i++; ss_test[i].num = 0x007F0000; ss_test[i].expected = "8323072"; + i++; ss_test[i].num = 0x00007F00; ss_test[i].expected = "32512"; + i++; ss_test[i].num = 0x0000007F; ss_test[i].expected = "127"; + + i++; ss_test[i].num = 0x70000000; ss_test[i].expected = "1879048192"; + i++; ss_test[i].num = 0x07000000; ss_test[i].expected = "117440512"; + i++; ss_test[i].num = 0x00700000; ss_test[i].expected = "7340032"; + i++; ss_test[i].num = 0x00070000; ss_test[i].expected = "458752"; + i++; ss_test[i].num = 0x00007000; ss_test[i].expected = "28672"; + i++; ss_test[i].num = 0x00000700; ss_test[i].expected = "1792"; + i++; ss_test[i].num = 0x00000070; ss_test[i].expected = "112"; + i++; ss_test[i].num = 0x00000007; ss_test[i].expected = "7"; + + i++; ss_test[i].num = 0x50000000; ss_test[i].expected = "1342177280"; + i++; ss_test[i].num = 0x05000000; ss_test[i].expected = "83886080"; + i++; ss_test[i].num = 0x00500000; ss_test[i].expected = "5242880"; + i++; ss_test[i].num = 0x00050000; ss_test[i].expected = "327680"; + i++; ss_test[i].num = 0x00005000; ss_test[i].expected = "20480"; + i++; ss_test[i].num = 0x00000500; ss_test[i].expected = "1280"; + i++; ss_test[i].num = 0x00000050; ss_test[i].expected = "80"; + i++; ss_test[i].num = 0x00000005; ss_test[i].expected = "5"; + + i++; ss_test[i].num = 0x00000001; ss_test[i].expected = "1"; + i++; ss_test[i].num = 0x00000000; ss_test[i].expected = "0"; + + i++; ss_test[i].num = -0x7FFFFFFF -1; ss_test[i].expected = "-2147483648"; + i++; ss_test[i].num = -0x7FFFFFFE -1; ss_test[i].expected = "-2147483647"; + i++; ss_test[i].num = -0x7FFFFFFD -1; ss_test[i].expected = "-2147483646"; + i++; ss_test[i].num = -0x7FFF0000 -1; ss_test[i].expected = "-2147418113"; + i++; ss_test[i].num = -0x00007FFF -1; ss_test[i].expected = "-32768"; + + i++; ss_test[i].num = -0x7F000000 -1; ss_test[i].expected = "-2130706433"; + i++; ss_test[i].num = -0x007F0000 -1; ss_test[i].expected = "-8323073"; + i++; ss_test[i].num = -0x00007F00 -1; ss_test[i].expected = "-32513"; + i++; ss_test[i].num = -0x0000007F -1; ss_test[i].expected = "-128"; + + i++; ss_test[i].num = -0x70000000 -1; ss_test[i].expected = "-1879048193"; + i++; ss_test[i].num = -0x07000000 -1; ss_test[i].expected = "-117440513"; + i++; ss_test[i].num = -0x00700000 -1; ss_test[i].expected = "-7340033"; + i++; ss_test[i].num = -0x00070000 -1; ss_test[i].expected = "-458753"; + i++; ss_test[i].num = -0x00007000 -1; ss_test[i].expected = "-28673"; + i++; ss_test[i].num = -0x00000700 -1; ss_test[i].expected = "-1793"; + i++; ss_test[i].num = -0x00000070 -1; ss_test[i].expected = "-113"; + i++; ss_test[i].num = -0x00000007 -1; ss_test[i].expected = "-8"; + + i++; ss_test[i].num = -0x50000000 -1; ss_test[i].expected = "-1342177281"; + i++; ss_test[i].num = -0x05000000 -1; ss_test[i].expected = "-83886081"; + i++; ss_test[i].num = -0x00500000 -1; ss_test[i].expected = "-5242881"; + i++; ss_test[i].num = -0x00050000 -1; ss_test[i].expected = "-327681"; + i++; ss_test[i].num = -0x00005000 -1; ss_test[i].expected = "-20481"; + i++; ss_test[i].num = -0x00000500 -1; ss_test[i].expected = "-1281"; + i++; ss_test[i].num = -0x00000050 -1; ss_test[i].expected = "-81"; + i++; ss_test[i].num = -0x00000005 -1; ss_test[i].expected = "-6"; + + i++; ss_test[i].num = 0x00000000 -1; ss_test[i].expected = "-1"; + + num_sshort_tests = i; + +#endif + + for(i=1; i<=num_sshort_tests; i++) { + + for(j=0; j<BUFSZ; j++) + ss_test[i].result[j] = 'X'; + ss_test[i].result[BUFSZ-1] = '\0'; + + (void)curl_msprintf(ss_test[i].result, "%hd", ss_test[i].num); + + if(memcmp(ss_test[i].result, + ss_test[i].expected, + strlen(ss_test[i].expected))) { + printf("signed short test #%.2d: Failed (Expected: %s Got: %s)\n", + i, ss_test[i].expected, ss_test[i].result); + failed++; + } + + } + + if(!failed) + printf("All curl_mprintf() signed short tests OK!\n"); + else + printf("Some curl_mprintf() signed short tests Failed!\n"); + + return failed; +} + + +static int test_unsigned_int_formatting(void) +{ + int i, j; + int num_uint_tests; + int failed = 0; + +#if (SIZEOF_INT == 2) + + i=1; ui_test[i].num = 0xFFFFU; ui_test[i].expected = "65535"; + i++; ui_test[i].num = 0xFF00U; ui_test[i].expected = "65280"; + i++; ui_test[i].num = 0x00FFU; ui_test[i].expected = "255"; + + i++; ui_test[i].num = 0xF000U; ui_test[i].expected = "61440"; + i++; ui_test[i].num = 0x0F00U; ui_test[i].expected = "3840"; + i++; ui_test[i].num = 0x00F0U; ui_test[i].expected = "240"; + i++; ui_test[i].num = 0x000FU; ui_test[i].expected = "15"; + + i++; ui_test[i].num = 0xC000U; ui_test[i].expected = "49152"; + i++; ui_test[i].num = 0x0C00U; ui_test[i].expected = "3072"; + i++; ui_test[i].num = 0x00C0U; ui_test[i].expected = "192"; + i++; ui_test[i].num = 0x000CU; ui_test[i].expected = "12"; + + i++; ui_test[i].num = 0x0001U; ui_test[i].expected = "1"; + i++; ui_test[i].num = 0x0000U; ui_test[i].expected = "0"; + + num_uint_tests = i; + +#elif (SIZEOF_INT == 4) + + i=1; ui_test[i].num = 0xFFFFFFFFU; ui_test[i].expected = "4294967295"; + i++; ui_test[i].num = 0xFFFF0000U; ui_test[i].expected = "4294901760"; + i++; ui_test[i].num = 0x0000FFFFU; ui_test[i].expected = "65535"; + + i++; ui_test[i].num = 0xFF000000U; ui_test[i].expected = "4278190080"; + i++; ui_test[i].num = 0x00FF0000U; ui_test[i].expected = "16711680"; + i++; ui_test[i].num = 0x0000FF00U; ui_test[i].expected = "65280"; + i++; ui_test[i].num = 0x000000FFU; ui_test[i].expected = "255"; + + i++; ui_test[i].num = 0xF0000000U; ui_test[i].expected = "4026531840"; + i++; ui_test[i].num = 0x0F000000U; ui_test[i].expected = "251658240"; + i++; ui_test[i].num = 0x00F00000U; ui_test[i].expected = "15728640"; + i++; ui_test[i].num = 0x000F0000U; ui_test[i].expected = "983040"; + i++; ui_test[i].num = 0x0000F000U; ui_test[i].expected = "61440"; + i++; ui_test[i].num = 0x00000F00U; ui_test[i].expected = "3840"; + i++; ui_test[i].num = 0x000000F0U; ui_test[i].expected = "240"; + i++; ui_test[i].num = 0x0000000FU; ui_test[i].expected = "15"; + + i++; ui_test[i].num = 0xC0000000U; ui_test[i].expected = "3221225472"; + i++; ui_test[i].num = 0x0C000000U; ui_test[i].expected = "201326592"; + i++; ui_test[i].num = 0x00C00000U; ui_test[i].expected = "12582912"; + i++; ui_test[i].num = 0x000C0000U; ui_test[i].expected = "786432"; + i++; ui_test[i].num = 0x0000C000U; ui_test[i].expected = "49152"; + i++; ui_test[i].num = 0x00000C00U; ui_test[i].expected = "3072"; + i++; ui_test[i].num = 0x000000C0U; ui_test[i].expected = "192"; + i++; ui_test[i].num = 0x0000000CU; ui_test[i].expected = "12"; + + i++; ui_test[i].num = 0x00000001U; ui_test[i].expected = "1"; + i++; ui_test[i].num = 0x00000000U; ui_test[i].expected = "0"; + + num_uint_tests = i; + +#elif (SIZEOF_INT == 8) + + i=1; ui_test[i].num = 0xFFFFFFFFFFFFFFFFU; ui_test[i].expected = "18446744073709551615"; + i++; ui_test[i].num = 0xFFFFFFFF00000000U; ui_test[i].expected = "18446744069414584320"; + i++; ui_test[i].num = 0x00000000FFFFFFFFU; ui_test[i].expected = "4294967295"; + + i++; ui_test[i].num = 0xFFFF000000000000U; ui_test[i].expected = "18446462598732840960"; + i++; ui_test[i].num = 0x0000FFFF00000000U; ui_test[i].expected = "281470681743360"; + i++; ui_test[i].num = 0x00000000FFFF0000U; ui_test[i].expected = "4294901760"; + i++; ui_test[i].num = 0x000000000000FFFFU; ui_test[i].expected = "65535"; + + i++; ui_test[i].num = 0xFF00000000000000U; ui_test[i].expected = "18374686479671623680"; + i++; ui_test[i].num = 0x00FF000000000000U; ui_test[i].expected = "71776119061217280"; + i++; ui_test[i].num = 0x0000FF0000000000U; ui_test[i].expected = "280375465082880"; + i++; ui_test[i].num = 0x000000FF00000000U; ui_test[i].expected = "1095216660480"; + i++; ui_test[i].num = 0x00000000FF000000U; ui_test[i].expected = "4278190080"; + i++; ui_test[i].num = 0x0000000000FF0000U; ui_test[i].expected = "16711680"; + i++; ui_test[i].num = 0x000000000000FF00U; ui_test[i].expected = "65280"; + i++; ui_test[i].num = 0x00000000000000FFU; ui_test[i].expected = "255"; + + i++; ui_test[i].num = 0xF000000000000000U; ui_test[i].expected = "17293822569102704640"; + i++; ui_test[i].num = 0x0F00000000000000U; ui_test[i].expected = "1080863910568919040"; + i++; ui_test[i].num = 0x00F0000000000000U; ui_test[i].expected = "67553994410557440"; + i++; ui_test[i].num = 0x000F000000000000U; ui_test[i].expected = "4222124650659840"; + i++; ui_test[i].num = 0x0000F00000000000U; ui_test[i].expected = "263882790666240"; + i++; ui_test[i].num = 0x00000F0000000000U; ui_test[i].expected = "16492674416640"; + i++; ui_test[i].num = 0x000000F000000000U; ui_test[i].expected = "1030792151040"; + i++; ui_test[i].num = 0x0000000F00000000U; ui_test[i].expected = "64424509440"; + i++; ui_test[i].num = 0x00000000F0000000U; ui_test[i].expected = "4026531840"; + i++; ui_test[i].num = 0x000000000F000000U; ui_test[i].expected = "251658240"; + i++; ui_test[i].num = 0x0000000000F00000U; ui_test[i].expected = "15728640"; + i++; ui_test[i].num = 0x00000000000F0000U; ui_test[i].expected = "983040"; + i++; ui_test[i].num = 0x000000000000F000U; ui_test[i].expected = "61440"; + i++; ui_test[i].num = 0x0000000000000F00U; ui_test[i].expected = "3840"; + i++; ui_test[i].num = 0x00000000000000F0U; ui_test[i].expected = "240"; + i++; ui_test[i].num = 0x000000000000000FU; ui_test[i].expected = "15"; + + i++; ui_test[i].num = 0xC000000000000000U; ui_test[i].expected = "13835058055282163712"; + i++; ui_test[i].num = 0x0C00000000000000U; ui_test[i].expected = "864691128455135232"; + i++; ui_test[i].num = 0x00C0000000000000U; ui_test[i].expected = "54043195528445952"; + i++; ui_test[i].num = 0x000C000000000000U; ui_test[i].expected = "3377699720527872"; + i++; ui_test[i].num = 0x0000C00000000000U; ui_test[i].expected = "211106232532992"; + i++; ui_test[i].num = 0x00000C0000000000U; ui_test[i].expected = "13194139533312"; + i++; ui_test[i].num = 0x000000C000000000U; ui_test[i].expected = "824633720832"; + i++; ui_test[i].num = 0x0000000C00000000U; ui_test[i].expected = "51539607552"; + i++; ui_test[i].num = 0x00000000C0000000U; ui_test[i].expected = "3221225472"; + i++; ui_test[i].num = 0x000000000C000000U; ui_test[i].expected = "201326592"; + i++; ui_test[i].num = 0x0000000000C00000U; ui_test[i].expected = "12582912"; + i++; ui_test[i].num = 0x00000000000C0000U; ui_test[i].expected = "786432"; + i++; ui_test[i].num = 0x000000000000C000U; ui_test[i].expected = "49152"; + i++; ui_test[i].num = 0x0000000000000C00U; ui_test[i].expected = "3072"; + i++; ui_test[i].num = 0x00000000000000C0U; ui_test[i].expected = "192"; + i++; ui_test[i].num = 0x000000000000000CU; ui_test[i].expected = "12"; + + i++; ui_test[i].num = 0x00000001U; ui_test[i].expected = "1"; + i++; ui_test[i].num = 0x00000000U; ui_test[i].expected = "0"; + + num_uint_tests = i; + +#endif + + for(i=1; i<=num_uint_tests; i++) { + + for(j=0; j<BUFSZ; j++) + ui_test[i].result[j] = 'X'; + ui_test[i].result[BUFSZ-1] = '\0'; + + (void)curl_msprintf(ui_test[i].result, "%u", ui_test[i].num); + + if(memcmp(ui_test[i].result, + ui_test[i].expected, + strlen(ui_test[i].expected))) { + printf("unsigned int test #%.2d: Failed (Expected: %s Got: %s)\n", + i, ui_test[i].expected, ui_test[i].result); + failed++; + } + + } + + if(!failed) + printf("All curl_mprintf() unsigned int tests OK!\n"); + else + printf("Some curl_mprintf() unsigned int tests Failed!\n"); + + return failed; +} + + +static int test_signed_int_formatting(void) +{ + int i, j; + int num_sint_tests; + int failed = 0; + +#if (SIZEOF_INT == 2) + + i=1; si_test[i].num = 0x7FFF; si_test[i].expected = "32767"; + i++; si_test[i].num = 0x7FFE; si_test[i].expected = "32766"; + i++; si_test[i].num = 0x7FFD; si_test[i].expected = "32765"; + i++; si_test[i].num = 0x7F00; si_test[i].expected = "32512"; + i++; si_test[i].num = 0x07F0; si_test[i].expected = "2032"; + i++; si_test[i].num = 0x007F; si_test[i].expected = "127"; + + i++; si_test[i].num = 0x7000; si_test[i].expected = "28672"; + i++; si_test[i].num = 0x0700; si_test[i].expected = "1792"; + i++; si_test[i].num = 0x0070; si_test[i].expected = "112"; + i++; si_test[i].num = 0x0007; si_test[i].expected = "7"; + + i++; si_test[i].num = 0x5000; si_test[i].expected = "20480"; + i++; si_test[i].num = 0x0500; si_test[i].expected = "1280"; + i++; si_test[i].num = 0x0050; si_test[i].expected = "80"; + i++; si_test[i].num = 0x0005; si_test[i].expected = "5"; + + i++; si_test[i].num = 0x0001; si_test[i].expected = "1"; + i++; si_test[i].num = 0x0000; si_test[i].expected = "0"; + + i++; si_test[i].num = -0x7FFF -1; si_test[i].expected = "-32768"; + i++; si_test[i].num = -0x7FFE -1; si_test[i].expected = "-32767"; + i++; si_test[i].num = -0x7FFD -1; si_test[i].expected = "-32766"; + i++; si_test[i].num = -0x7F00 -1; si_test[i].expected = "-32513"; + i++; si_test[i].num = -0x07F0 -1; si_test[i].expected = "-2033"; + i++; si_test[i].num = -0x007F -1; si_test[i].expected = "-128"; + + i++; si_test[i].num = -0x7000 -1; si_test[i].expected = "-28673"; + i++; si_test[i].num = -0x0700 -1; si_test[i].expected = "-1793"; + i++; si_test[i].num = -0x0070 -1; si_test[i].expected = "-113"; + i++; si_test[i].num = -0x0007 -1; si_test[i].expected = "-8"; + + i++; si_test[i].num = -0x5000 -1; si_test[i].expected = "-20481"; + i++; si_test[i].num = -0x0500 -1; si_test[i].expected = "-1281"; + i++; si_test[i].num = -0x0050 -1; si_test[i].expected = "-81"; + i++; si_test[i].num = -0x0005 -1; si_test[i].expected = "-6"; + + i++; si_test[i].num = 0x0000 -1; si_test[i].expected = "-1"; + + num_sint_tests = i; + +#elif (SIZEOF_INT == 4) + + i=1; si_test[i].num = 0x7FFFFFFF; si_test[i].expected = "2147483647"; + i++; si_test[i].num = 0x7FFFFFFE; si_test[i].expected = "2147483646"; + i++; si_test[i].num = 0x7FFFFFFD; si_test[i].expected = "2147483645"; + i++; si_test[i].num = 0x7FFF0000; si_test[i].expected = "2147418112"; + i++; si_test[i].num = 0x00007FFF; si_test[i].expected = "32767"; + + i++; si_test[i].num = 0x7F000000; si_test[i].expected = "2130706432"; + i++; si_test[i].num = 0x007F0000; si_test[i].expected = "8323072"; + i++; si_test[i].num = 0x00007F00; si_test[i].expected = "32512"; + i++; si_test[i].num = 0x0000007F; si_test[i].expected = "127"; + + i++; si_test[i].num = 0x70000000; si_test[i].expected = "1879048192"; + i++; si_test[i].num = 0x07000000; si_test[i].expected = "117440512"; + i++; si_test[i].num = 0x00700000; si_test[i].expected = "7340032"; + i++; si_test[i].num = 0x00070000; si_test[i].expected = "458752"; + i++; si_test[i].num = 0x00007000; si_test[i].expected = "28672"; + i++; si_test[i].num = 0x00000700; si_test[i].expected = "1792"; + i++; si_test[i].num = 0x00000070; si_test[i].expected = "112"; + i++; si_test[i].num = 0x00000007; si_test[i].expected = "7"; + + i++; si_test[i].num = 0x50000000; si_test[i].expected = "1342177280"; + i++; si_test[i].num = 0x05000000; si_test[i].expected = "83886080"; + i++; si_test[i].num = 0x00500000; si_test[i].expected = "5242880"; + i++; si_test[i].num = 0x00050000; si_test[i].expected = "327680"; + i++; si_test[i].num = 0x00005000; si_test[i].expected = "20480"; + i++; si_test[i].num = 0x00000500; si_test[i].expected = "1280"; + i++; si_test[i].num = 0x00000050; si_test[i].expected = "80"; + i++; si_test[i].num = 0x00000005; si_test[i].expected = "5"; + + i++; si_test[i].num = 0x00000001; si_test[i].expected = "1"; + i++; si_test[i].num = 0x00000000; si_test[i].expected = "0"; + + i++; si_test[i].num = -0x7FFFFFFF -1; si_test[i].expected = "-2147483648"; + i++; si_test[i].num = -0x7FFFFFFE -1; si_test[i].expected = "-2147483647"; + i++; si_test[i].num = -0x7FFFFFFD -1; si_test[i].expected = "-2147483646"; + i++; si_test[i].num = -0x7FFF0000 -1; si_test[i].expected = "-2147418113"; + i++; si_test[i].num = -0x00007FFF -1; si_test[i].expected = "-32768"; + + i++; si_test[i].num = -0x7F000000 -1; si_test[i].expected = "-2130706433"; + i++; si_test[i].num = -0x007F0000 -1; si_test[i].expected = "-8323073"; + i++; si_test[i].num = -0x00007F00 -1; si_test[i].expected = "-32513"; + i++; si_test[i].num = -0x0000007F -1; si_test[i].expected = "-128"; + + i++; si_test[i].num = -0x70000000 -1; si_test[i].expected = "-1879048193"; + i++; si_test[i].num = -0x07000000 -1; si_test[i].expected = "-117440513"; + i++; si_test[i].num = -0x00700000 -1; si_test[i].expected = "-7340033"; + i++; si_test[i].num = -0x00070000 -1; si_test[i].expected = "-458753"; + i++; si_test[i].num = -0x00007000 -1; si_test[i].expected = "-28673"; + i++; si_test[i].num = -0x00000700 -1; si_test[i].expected = "-1793"; + i++; si_test[i].num = -0x00000070 -1; si_test[i].expected = "-113"; + i++; si_test[i].num = -0x00000007 -1; si_test[i].expected = "-8"; + + i++; si_test[i].num = -0x50000000 -1; si_test[i].expected = "-1342177281"; + i++; si_test[i].num = -0x05000000 -1; si_test[i].expected = "-83886081"; + i++; si_test[i].num = -0x00500000 -1; si_test[i].expected = "-5242881"; + i++; si_test[i].num = -0x00050000 -1; si_test[i].expected = "-327681"; + i++; si_test[i].num = -0x00005000 -1; si_test[i].expected = "-20481"; + i++; si_test[i].num = -0x00000500 -1; si_test[i].expected = "-1281"; + i++; si_test[i].num = -0x00000050 -1; si_test[i].expected = "-81"; + i++; si_test[i].num = -0x00000005 -1; si_test[i].expected = "-6"; + + i++; si_test[i].num = 0x00000000 -1; si_test[i].expected = "-1"; + + num_sint_tests = i; + +#elif (SIZEOF_INT == 8) + + i=1; si_test[i].num = 0x7FFFFFFFFFFFFFFF; si_test[i].expected = "9223372036854775807"; + i++; si_test[i].num = 0x7FFFFFFFFFFFFFFE; si_test[i].expected = "9223372036854775806"; + i++; si_test[i].num = 0x7FFFFFFFFFFFFFFD; si_test[i].expected = "9223372036854775805"; + i++; si_test[i].num = 0x7FFFFFFF00000000; si_test[i].expected = "9223372032559808512"; + i++; si_test[i].num = 0x000000007FFFFFFF; si_test[i].expected = "2147483647"; + + i++; si_test[i].num = 0x7FFF000000000000; si_test[i].expected = "9223090561878065152"; + i++; si_test[i].num = 0x00007FFF00000000; si_test[i].expected = "140733193388032"; + i++; si_test[i].num = 0x000000007FFF0000; si_test[i].expected = "2147418112"; + i++; si_test[i].num = 0x0000000000007FFF; si_test[i].expected = "32767"; + + i++; si_test[i].num = 0x7F00000000000000; si_test[i].expected = "9151314442816847872"; + i++; si_test[i].num = 0x007F000000000000; si_test[i].expected = "35747322042253312"; + i++; si_test[i].num = 0x00007F0000000000; si_test[i].expected = "139637976727552"; + i++; si_test[i].num = 0x0000007F00000000; si_test[i].expected = "545460846592"; + i++; si_test[i].num = 0x000000007F000000; si_test[i].expected = "2130706432"; + i++; si_test[i].num = 0x00000000007F0000; si_test[i].expected = "8323072"; + i++; si_test[i].num = 0x0000000000007F00; si_test[i].expected = "32512"; + i++; si_test[i].num = 0x000000000000007F; si_test[i].expected = "127"; + + i++; si_test[i].num = 0x7000000000000000; si_test[i].expected = "8070450532247928832"; + i++; si_test[i].num = 0x0700000000000000; si_test[i].expected = "504403158265495552"; + i++; si_test[i].num = 0x0070000000000000; si_test[i].expected = "31525197391593472"; + i++; si_test[i].num = 0x0007000000000000; si_test[i].expected = "1970324836974592"; + i++; si_test[i].num = 0x0000700000000000; si_test[i].expected = "123145302310912"; + i++; si_test[i].num = 0x0000070000000000; si_test[i].expected = "7696581394432"; + i++; si_test[i].num = 0x0000007000000000; si_test[i].expected = "481036337152"; + i++; si_test[i].num = 0x0000000700000000; si_test[i].expected = "30064771072"; + i++; si_test[i].num = 0x0000000070000000; si_test[i].expected = "1879048192"; + i++; si_test[i].num = 0x0000000007000000; si_test[i].expected = "117440512"; + i++; si_test[i].num = 0x0000000000700000; si_test[i].expected = "7340032"; + i++; si_test[i].num = 0x0000000000070000; si_test[i].expected = "458752"; + i++; si_test[i].num = 0x0000000000007000; si_test[i].expected = "28672"; + i++; si_test[i].num = 0x0000000000000700; si_test[i].expected = "1792"; + i++; si_test[i].num = 0x0000000000000070; si_test[i].expected = "112"; + i++; si_test[i].num = 0x0000000000000007; si_test[i].expected = "7"; + + i++; si_test[i].num = 0x0000000000000001; si_test[i].expected = "1"; + i++; si_test[i].num = 0x0000000000000000; si_test[i].expected = "0"; + + i++; si_test[i].num = -0x7FFFFFFFFFFFFFFF -1; si_test[i].expected = "-9223372036854775808"; + i++; si_test[i].num = -0x7FFFFFFFFFFFFFFE -1; si_test[i].expected = "-9223372036854775807"; + i++; si_test[i].num = -0x7FFFFFFFFFFFFFFD -1; si_test[i].expected = "-9223372036854775806"; + i++; si_test[i].num = -0x7FFFFFFF00000000 -1; si_test[i].expected = "-9223372032559808513"; + i++; si_test[i].num = -0x000000007FFFFFFF -1; si_test[i].expected = "-2147483648"; + + i++; si_test[i].num = -0x7FFF000000000000 -1; si_test[i].expected = "-9223090561878065153"; + i++; si_test[i].num = -0x00007FFF00000000 -1; si_test[i].expected = "-140733193388033"; + i++; si_test[i].num = -0x000000007FFF0000 -1; si_test[i].expected = "-2147418113"; + i++; si_test[i].num = -0x0000000000007FFF -1; si_test[i].expected = "-32768"; + + i++; si_test[i].num = -0x7F00000000000000 -1; si_test[i].expected = "-9151314442816847873"; + i++; si_test[i].num = -0x007F000000000000 -1; si_test[i].expected = "-35747322042253313"; + i++; si_test[i].num = -0x00007F0000000000 -1; si_test[i].expected = "-139637976727553"; + i++; si_test[i].num = -0x0000007F00000000 -1; si_test[i].expected = "-545460846593"; + i++; si_test[i].num = -0x000000007F000000 -1; si_test[i].expected = "-2130706433"; + i++; si_test[i].num = -0x00000000007F0000 -1; si_test[i].expected = "-8323073"; + i++; si_test[i].num = -0x0000000000007F00 -1; si_test[i].expected = "-32513"; + i++; si_test[i].num = -0x000000000000007F -1; si_test[i].expected = "-128"; + + i++; si_test[i].num = -0x7000000000000000 -1; si_test[i].expected = "-8070450532247928833"; + i++; si_test[i].num = -0x0700000000000000 -1; si_test[i].expected = "-504403158265495553"; + i++; si_test[i].num = -0x0070000000000000 -1; si_test[i].expected = "-31525197391593473"; + i++; si_test[i].num = -0x0007000000000000 -1; si_test[i].expected = "-1970324836974593"; + i++; si_test[i].num = -0x0000700000000000 -1; si_test[i].expected = "-123145302310913"; + i++; si_test[i].num = -0x0000070000000000 -1; si_test[i].expected = "-7696581394433"; + i++; si_test[i].num = -0x0000007000000000 -1; si_test[i].expected = "-481036337153"; + i++; si_test[i].num = -0x0000000700000000 -1; si_test[i].expected = "-30064771073"; + i++; si_test[i].num = -0x0000000070000000 -1; si_test[i].expected = "-1879048193"; + i++; si_test[i].num = -0x0000000007000000 -1; si_test[i].expected = "-117440513"; + i++; si_test[i].num = -0x0000000000700000 -1; si_test[i].expected = "-7340033"; + i++; si_test[i].num = -0x0000000000070000 -1; si_test[i].expected = "-458753"; + i++; si_test[i].num = -0x0000000000007000 -1; si_test[i].expected = "-28673"; + i++; si_test[i].num = -0x0000000000000700 -1; si_test[i].expected = "-1793"; + i++; si_test[i].num = -0x0000000000000070 -1; si_test[i].expected = "-113"; + i++; si_test[i].num = -0x0000000000000007 -1; si_test[i].expected = "-8"; + + i++; si_test[i].num = 0x0000000000000000 -1; si_test[i].expected = "-1"; + + num_sint_tests = i; + +#endif + + for(i=1; i<=num_sint_tests; i++) { + + for(j=0; j<BUFSZ; j++) + si_test[i].result[j] = 'X'; + si_test[i].result[BUFSZ-1] = '\0'; + + (void)curl_msprintf(si_test[i].result, "%d", si_test[i].num); + + if(memcmp(si_test[i].result, + si_test[i].expected, + strlen(si_test[i].expected))) { + printf("signed int test #%.2d: Failed (Expected: %s Got: %s)\n", + i, si_test[i].expected, si_test[i].result); + failed++; + } + + } + + if(!failed) + printf("All curl_mprintf() signed int tests OK!\n"); + else + printf("Some curl_mprintf() signed int tests Failed!\n"); + + return failed; +} + + +static int test_unsigned_long_formatting(void) +{ + int i, j; + int num_ulong_tests; + int failed = 0; + +#if (CURL_SIZEOF_LONG == 2) + + i=1; ul_test[i].num = 0xFFFFUL; ul_test[i].expected = "65535"; + i++; ul_test[i].num = 0xFF00UL; ul_test[i].expected = "65280"; + i++; ul_test[i].num = 0x00FFUL; ul_test[i].expected = "255"; + + i++; ul_test[i].num = 0xF000UL; ul_test[i].expected = "61440"; + i++; ul_test[i].num = 0x0F00UL; ul_test[i].expected = "3840"; + i++; ul_test[i].num = 0x00F0UL; ul_test[i].expected = "240"; + i++; ul_test[i].num = 0x000FUL; ul_test[i].expected = "15"; + + i++; ul_test[i].num = 0xC000UL; ul_test[i].expected = "49152"; + i++; ul_test[i].num = 0x0C00UL; ul_test[i].expected = "3072"; + i++; ul_test[i].num = 0x00C0UL; ul_test[i].expected = "192"; + i++; ul_test[i].num = 0x000CUL; ul_test[i].expected = "12"; + + i++; ul_test[i].num = 0x0001UL; ul_test[i].expected = "1"; + i++; ul_test[i].num = 0x0000UL; ul_test[i].expected = "0"; + + num_ulong_tests = i; + +#elif (CURL_SIZEOF_LONG == 4) + + i=1; ul_test[i].num = 0xFFFFFFFFUL; ul_test[i].expected = "4294967295"; + i++; ul_test[i].num = 0xFFFF0000UL; ul_test[i].expected = "4294901760"; + i++; ul_test[i].num = 0x0000FFFFUL; ul_test[i].expected = "65535"; + + i++; ul_test[i].num = 0xFF000000UL; ul_test[i].expected = "4278190080"; + i++; ul_test[i].num = 0x00FF0000UL; ul_test[i].expected = "16711680"; + i++; ul_test[i].num = 0x0000FF00UL; ul_test[i].expected = "65280"; + i++; ul_test[i].num = 0x000000FFUL; ul_test[i].expected = "255"; + + i++; ul_test[i].num = 0xF0000000UL; ul_test[i].expected = "4026531840"; + i++; ul_test[i].num = 0x0F000000UL; ul_test[i].expected = "251658240"; + i++; ul_test[i].num = 0x00F00000UL; ul_test[i].expected = "15728640"; + i++; ul_test[i].num = 0x000F0000UL; ul_test[i].expected = "983040"; + i++; ul_test[i].num = 0x0000F000UL; ul_test[i].expected = "61440"; + i++; ul_test[i].num = 0x00000F00UL; ul_test[i].expected = "3840"; + i++; ul_test[i].num = 0x000000F0UL; ul_test[i].expected = "240"; + i++; ul_test[i].num = 0x0000000FUL; ul_test[i].expected = "15"; + + i++; ul_test[i].num = 0xC0000000UL; ul_test[i].expected = "3221225472"; + i++; ul_test[i].num = 0x0C000000UL; ul_test[i].expected = "201326592"; + i++; ul_test[i].num = 0x00C00000UL; ul_test[i].expected = "12582912"; + i++; ul_test[i].num = 0x000C0000UL; ul_test[i].expected = "786432"; + i++; ul_test[i].num = 0x0000C000UL; ul_test[i].expected = "49152"; + i++; ul_test[i].num = 0x00000C00UL; ul_test[i].expected = "3072"; + i++; ul_test[i].num = 0x000000C0UL; ul_test[i].expected = "192"; + i++; ul_test[i].num = 0x0000000CUL; ul_test[i].expected = "12"; + + i++; ul_test[i].num = 0x00000001UL; ul_test[i].expected = "1"; + i++; ul_test[i].num = 0x00000000UL; ul_test[i].expected = "0"; + + num_ulong_tests = i; + +#elif (CURL_SIZEOF_LONG == 8) + + i=1; ul_test[i].num = 0xFFFFFFFFFFFFFFFFUL; ul_test[i].expected = "18446744073709551615"; + i++; ul_test[i].num = 0xFFFFFFFF00000000UL; ul_test[i].expected = "18446744069414584320"; + i++; ul_test[i].num = 0x00000000FFFFFFFFUL; ul_test[i].expected = "4294967295"; + + i++; ul_test[i].num = 0xFFFF000000000000UL; ul_test[i].expected = "18446462598732840960"; + i++; ul_test[i].num = 0x0000FFFF00000000UL; ul_test[i].expected = "281470681743360"; + i++; ul_test[i].num = 0x00000000FFFF0000UL; ul_test[i].expected = "4294901760"; + i++; ul_test[i].num = 0x000000000000FFFFUL; ul_test[i].expected = "65535"; + + i++; ul_test[i].num = 0xFF00000000000000UL; ul_test[i].expected = "18374686479671623680"; + i++; ul_test[i].num = 0x00FF000000000000UL; ul_test[i].expected = "71776119061217280"; + i++; ul_test[i].num = 0x0000FF0000000000UL; ul_test[i].expected = "280375465082880"; + i++; ul_test[i].num = 0x000000FF00000000UL; ul_test[i].expected = "1095216660480"; + i++; ul_test[i].num = 0x00000000FF000000UL; ul_test[i].expected = "4278190080"; + i++; ul_test[i].num = 0x0000000000FF0000UL; ul_test[i].expected = "16711680"; + i++; ul_test[i].num = 0x000000000000FF00UL; ul_test[i].expected = "65280"; + i++; ul_test[i].num = 0x00000000000000FFUL; ul_test[i].expected = "255"; + + i++; ul_test[i].num = 0xF000000000000000UL; ul_test[i].expected = "17293822569102704640"; + i++; ul_test[i].num = 0x0F00000000000000UL; ul_test[i].expected = "1080863910568919040"; + i++; ul_test[i].num = 0x00F0000000000000UL; ul_test[i].expected = "67553994410557440"; + i++; ul_test[i].num = 0x000F000000000000UL; ul_test[i].expected = "4222124650659840"; + i++; ul_test[i].num = 0x0000F00000000000UL; ul_test[i].expected = "263882790666240"; + i++; ul_test[i].num = 0x00000F0000000000UL; ul_test[i].expected = "16492674416640"; + i++; ul_test[i].num = 0x000000F000000000UL; ul_test[i].expected = "1030792151040"; + i++; ul_test[i].num = 0x0000000F00000000UL; ul_test[i].expected = "64424509440"; + i++; ul_test[i].num = 0x00000000F0000000UL; ul_test[i].expected = "4026531840"; + i++; ul_test[i].num = 0x000000000F000000UL; ul_test[i].expected = "251658240"; + i++; ul_test[i].num = 0x0000000000F00000UL; ul_test[i].expected = "15728640"; + i++; ul_test[i].num = 0x00000000000F0000UL; ul_test[i].expected = "983040"; + i++; ul_test[i].num = 0x000000000000F000UL; ul_test[i].expected = "61440"; + i++; ul_test[i].num = 0x0000000000000F00UL; ul_test[i].expected = "3840"; + i++; ul_test[i].num = 0x00000000000000F0UL; ul_test[i].expected = "240"; + i++; ul_test[i].num = 0x000000000000000FUL; ul_test[i].expected = "15"; + + i++; ul_test[i].num = 0xC000000000000000UL; ul_test[i].expected = "13835058055282163712"; + i++; ul_test[i].num = 0x0C00000000000000UL; ul_test[i].expected = "864691128455135232"; + i++; ul_test[i].num = 0x00C0000000000000UL; ul_test[i].expected = "54043195528445952"; + i++; ul_test[i].num = 0x000C000000000000UL; ul_test[i].expected = "3377699720527872"; + i++; ul_test[i].num = 0x0000C00000000000UL; ul_test[i].expected = "211106232532992"; + i++; ul_test[i].num = 0x00000C0000000000UL; ul_test[i].expected = "13194139533312"; + i++; ul_test[i].num = 0x000000C000000000UL; ul_test[i].expected = "824633720832"; + i++; ul_test[i].num = 0x0000000C00000000UL; ul_test[i].expected = "51539607552"; + i++; ul_test[i].num = 0x00000000C0000000UL; ul_test[i].expected = "3221225472"; + i++; ul_test[i].num = 0x000000000C000000UL; ul_test[i].expected = "201326592"; + i++; ul_test[i].num = 0x0000000000C00000UL; ul_test[i].expected = "12582912"; + i++; ul_test[i].num = 0x00000000000C0000UL; ul_test[i].expected = "786432"; + i++; ul_test[i].num = 0x000000000000C000UL; ul_test[i].expected = "49152"; + i++; ul_test[i].num = 0x0000000000000C00UL; ul_test[i].expected = "3072"; + i++; ul_test[i].num = 0x00000000000000C0UL; ul_test[i].expected = "192"; + i++; ul_test[i].num = 0x000000000000000CUL; ul_test[i].expected = "12"; + + i++; ul_test[i].num = 0x00000001UL; ul_test[i].expected = "1"; + i++; ul_test[i].num = 0x00000000UL; ul_test[i].expected = "0"; + + num_ulong_tests = i; + +#endif + + for(i=1; i<=num_ulong_tests; i++) { + + for(j=0; j<BUFSZ; j++) + ul_test[i].result[j] = 'X'; + ul_test[i].result[BUFSZ-1] = '\0'; + + (void)curl_msprintf(ul_test[i].result, "%lu", ul_test[i].num); + + if(memcmp(ul_test[i].result, + ul_test[i].expected, + strlen(ul_test[i].expected))) { + printf("unsigned long test #%.2d: Failed (Expected: %s Got: %s)\n", + i, ul_test[i].expected, ul_test[i].result); + failed++; + } + + } + + if(!failed) + printf("All curl_mprintf() unsigned long tests OK!\n"); + else + printf("Some curl_mprintf() unsigned long tests Failed!\n"); + + return failed; +} + + +static int test_signed_long_formatting(void) +{ + int i, j; + int num_slong_tests; + int failed = 0; + +#if (CURL_SIZEOF_LONG == 2) + + i=1; sl_test[i].num = 0x7FFFL; sl_test[i].expected = "32767"; + i++; sl_test[i].num = 0x7FFEL; sl_test[i].expected = "32766"; + i++; sl_test[i].num = 0x7FFDL; sl_test[i].expected = "32765"; + i++; sl_test[i].num = 0x7F00L; sl_test[i].expected = "32512"; + i++; sl_test[i].num = 0x07F0L; sl_test[i].expected = "2032"; + i++; sl_test[i].num = 0x007FL; sl_test[i].expected = "127"; + + i++; sl_test[i].num = 0x7000L; sl_test[i].expected = "28672"; + i++; sl_test[i].num = 0x0700L; sl_test[i].expected = "1792"; + i++; sl_test[i].num = 0x0070L; sl_test[i].expected = "112"; + i++; sl_test[i].num = 0x0007L; sl_test[i].expected = "7"; + + i++; sl_test[i].num = 0x5000L; sl_test[i].expected = "20480"; + i++; sl_test[i].num = 0x0500L; sl_test[i].expected = "1280"; + i++; sl_test[i].num = 0x0050L; sl_test[i].expected = "80"; + i++; sl_test[i].num = 0x0005L; sl_test[i].expected = "5"; + + i++; sl_test[i].num = 0x0001L; sl_test[i].expected = "1"; + i++; sl_test[i].num = 0x0000L; sl_test[i].expected = "0"; + + i++; sl_test[i].num = -0x7FFFL -1L; sl_test[i].expected = "-32768"; + i++; sl_test[i].num = -0x7FFEL -1L; sl_test[i].expected = "-32767"; + i++; sl_test[i].num = -0x7FFDL -1L; sl_test[i].expected = "-32766"; + i++; sl_test[i].num = -0x7F00L -1L; sl_test[i].expected = "-32513"; + i++; sl_test[i].num = -0x07F0L -1L; sl_test[i].expected = "-2033"; + i++; sl_test[i].num = -0x007FL -1L; sl_test[i].expected = "-128"; + + i++; sl_test[i].num = -0x7000L -1L; sl_test[i].expected = "-28673"; + i++; sl_test[i].num = -0x0700L -1L; sl_test[i].expected = "-1793"; + i++; sl_test[i].num = -0x0070L -1L; sl_test[i].expected = "-113"; + i++; sl_test[i].num = -0x0007L -1L; sl_test[i].expected = "-8"; + + i++; sl_test[i].num = -0x5000L -1L; sl_test[i].expected = "-20481"; + i++; sl_test[i].num = -0x0500L -1L; sl_test[i].expected = "-1281"; + i++; sl_test[i].num = -0x0050L -1L; sl_test[i].expected = "-81"; + i++; sl_test[i].num = -0x0005L -1L; sl_test[i].expected = "-6"; + + i++; sl_test[i].num = 0x0000L -1L; sl_test[i].expected = "-1"; + + num_slong_tests = i; + +#elif (CURL_SIZEOF_LONG == 4) + + i=1; sl_test[i].num = 0x7FFFFFFFL; sl_test[i].expected = "2147483647"; + i++; sl_test[i].num = 0x7FFFFFFEL; sl_test[i].expected = "2147483646"; + i++; sl_test[i].num = 0x7FFFFFFDL; sl_test[i].expected = "2147483645"; + i++; sl_test[i].num = 0x7FFF0000L; sl_test[i].expected = "2147418112"; + i++; sl_test[i].num = 0x00007FFFL; sl_test[i].expected = "32767"; + + i++; sl_test[i].num = 0x7F000000L; sl_test[i].expected = "2130706432"; + i++; sl_test[i].num = 0x007F0000L; sl_test[i].expected = "8323072"; + i++; sl_test[i].num = 0x00007F00L; sl_test[i].expected = "32512"; + i++; sl_test[i].num = 0x0000007FL; sl_test[i].expected = "127"; + + i++; sl_test[i].num = 0x70000000L; sl_test[i].expected = "1879048192"; + i++; sl_test[i].num = 0x07000000L; sl_test[i].expected = "117440512"; + i++; sl_test[i].num = 0x00700000L; sl_test[i].expected = "7340032"; + i++; sl_test[i].num = 0x00070000L; sl_test[i].expected = "458752"; + i++; sl_test[i].num = 0x00007000L; sl_test[i].expected = "28672"; + i++; sl_test[i].num = 0x00000700L; sl_test[i].expected = "1792"; + i++; sl_test[i].num = 0x00000070L; sl_test[i].expected = "112"; + i++; sl_test[i].num = 0x00000007L; sl_test[i].expected = "7"; + + i++; sl_test[i].num = 0x50000000L; sl_test[i].expected = "1342177280"; + i++; sl_test[i].num = 0x05000000L; sl_test[i].expected = "83886080"; + i++; sl_test[i].num = 0x00500000L; sl_test[i].expected = "5242880"; + i++; sl_test[i].num = 0x00050000L; sl_test[i].expected = "327680"; + i++; sl_test[i].num = 0x00005000L; sl_test[i].expected = "20480"; + i++; sl_test[i].num = 0x00000500L; sl_test[i].expected = "1280"; + i++; sl_test[i].num = 0x00000050L; sl_test[i].expected = "80"; + i++; sl_test[i].num = 0x00000005L; sl_test[i].expected = "5"; + + i++; sl_test[i].num = 0x00000001L; sl_test[i].expected = "1"; + i++; sl_test[i].num = 0x00000000L; sl_test[i].expected = "0"; + + i++; sl_test[i].num = -0x7FFFFFFFL -1L; sl_test[i].expected = "-2147483648"; + i++; sl_test[i].num = -0x7FFFFFFEL -1L; sl_test[i].expected = "-2147483647"; + i++; sl_test[i].num = -0x7FFFFFFDL -1L; sl_test[i].expected = "-2147483646"; + i++; sl_test[i].num = -0x7FFF0000L -1L; sl_test[i].expected = "-2147418113"; + i++; sl_test[i].num = -0x00007FFFL -1L; sl_test[i].expected = "-32768"; + + i++; sl_test[i].num = -0x7F000000L -1L; sl_test[i].expected = "-2130706433"; + i++; sl_test[i].num = -0x007F0000L -1L; sl_test[i].expected = "-8323073"; + i++; sl_test[i].num = -0x00007F00L -1L; sl_test[i].expected = "-32513"; + i++; sl_test[i].num = -0x0000007FL -1L; sl_test[i].expected = "-128"; + + i++; sl_test[i].num = -0x70000000L -1L; sl_test[i].expected = "-1879048193"; + i++; sl_test[i].num = -0x07000000L -1L; sl_test[i].expected = "-117440513"; + i++; sl_test[i].num = -0x00700000L -1L; sl_test[i].expected = "-7340033"; + i++; sl_test[i].num = -0x00070000L -1L; sl_test[i].expected = "-458753"; + i++; sl_test[i].num = -0x00007000L -1L; sl_test[i].expected = "-28673"; + i++; sl_test[i].num = -0x00000700L -1L; sl_test[i].expected = "-1793"; + i++; sl_test[i].num = -0x00000070L -1L; sl_test[i].expected = "-113"; + i++; sl_test[i].num = -0x00000007L -1L; sl_test[i].expected = "-8"; + + i++; sl_test[i].num = -0x50000000L -1L; sl_test[i].expected = "-1342177281"; + i++; sl_test[i].num = -0x05000000L -1L; sl_test[i].expected = "-83886081"; + i++; sl_test[i].num = -0x00500000L -1L; sl_test[i].expected = "-5242881"; + i++; sl_test[i].num = -0x00050000L -1L; sl_test[i].expected = "-327681"; + i++; sl_test[i].num = -0x00005000L -1L; sl_test[i].expected = "-20481"; + i++; sl_test[i].num = -0x00000500L -1L; sl_test[i].expected = "-1281"; + i++; sl_test[i].num = -0x00000050L -1L; sl_test[i].expected = "-81"; + i++; sl_test[i].num = -0x00000005L -1L; sl_test[i].expected = "-6"; + + i++; sl_test[i].num = 0x00000000L -1L; sl_test[i].expected = "-1"; + + num_slong_tests = i; + +#elif (CURL_SIZEOF_LONG == 8) + + i=1; sl_test[i].num = 0x7FFFFFFFFFFFFFFFL; sl_test[i].expected = "9223372036854775807"; + i++; sl_test[i].num = 0x7FFFFFFFFFFFFFFEL; sl_test[i].expected = "9223372036854775806"; + i++; sl_test[i].num = 0x7FFFFFFFFFFFFFFDL; sl_test[i].expected = "9223372036854775805"; + i++; sl_test[i].num = 0x7FFFFFFF00000000L; sl_test[i].expected = "9223372032559808512"; + i++; sl_test[i].num = 0x000000007FFFFFFFL; sl_test[i].expected = "2147483647"; + + i++; sl_test[i].num = 0x7FFF000000000000L; sl_test[i].expected = "9223090561878065152"; + i++; sl_test[i].num = 0x00007FFF00000000L; sl_test[i].expected = "140733193388032"; + i++; sl_test[i].num = 0x000000007FFF0000L; sl_test[i].expected = "2147418112"; + i++; sl_test[i].num = 0x0000000000007FFFL; sl_test[i].expected = "32767"; + + i++; sl_test[i].num = 0x7F00000000000000L; sl_test[i].expected = "9151314442816847872"; + i++; sl_test[i].num = 0x007F000000000000L; sl_test[i].expected = "35747322042253312"; + i++; sl_test[i].num = 0x00007F0000000000L; sl_test[i].expected = "139637976727552"; + i++; sl_test[i].num = 0x0000007F00000000L; sl_test[i].expected = "545460846592"; + i++; sl_test[i].num = 0x000000007F000000L; sl_test[i].expected = "2130706432"; + i++; sl_test[i].num = 0x00000000007F0000L; sl_test[i].expected = "8323072"; + i++; sl_test[i].num = 0x0000000000007F00L; sl_test[i].expected = "32512"; + i++; sl_test[i].num = 0x000000000000007FL; sl_test[i].expected = "127"; + + i++; sl_test[i].num = 0x7000000000000000L; sl_test[i].expected = "8070450532247928832"; + i++; sl_test[i].num = 0x0700000000000000L; sl_test[i].expected = "504403158265495552"; + i++; sl_test[i].num = 0x0070000000000000L; sl_test[i].expected = "31525197391593472"; + i++; sl_test[i].num = 0x0007000000000000L; sl_test[i].expected = "1970324836974592"; + i++; sl_test[i].num = 0x0000700000000000L; sl_test[i].expected = "123145302310912"; + i++; sl_test[i].num = 0x0000070000000000L; sl_test[i].expected = "7696581394432"; + i++; sl_test[i].num = 0x0000007000000000L; sl_test[i].expected = "481036337152"; + i++; sl_test[i].num = 0x0000000700000000L; sl_test[i].expected = "30064771072"; + i++; sl_test[i].num = 0x0000000070000000L; sl_test[i].expected = "1879048192"; + i++; sl_test[i].num = 0x0000000007000000L; sl_test[i].expected = "117440512"; + i++; sl_test[i].num = 0x0000000000700000L; sl_test[i].expected = "7340032"; + i++; sl_test[i].num = 0x0000000000070000L; sl_test[i].expected = "458752"; + i++; sl_test[i].num = 0x0000000000007000L; sl_test[i].expected = "28672"; + i++; sl_test[i].num = 0x0000000000000700L; sl_test[i].expected = "1792"; + i++; sl_test[i].num = 0x0000000000000070L; sl_test[i].expected = "112"; + i++; sl_test[i].num = 0x0000000000000007L; sl_test[i].expected = "7"; + + i++; sl_test[i].num = 0x0000000000000001L; sl_test[i].expected = "1"; + i++; sl_test[i].num = 0x0000000000000000L; sl_test[i].expected = "0"; + + i++; sl_test[i].num = -0x7FFFFFFFFFFFFFFFL -1L; sl_test[i].expected = "-9223372036854775808"; + i++; sl_test[i].num = -0x7FFFFFFFFFFFFFFEL -1L; sl_test[i].expected = "-9223372036854775807"; + i++; sl_test[i].num = -0x7FFFFFFFFFFFFFFDL -1L; sl_test[i].expected = "-9223372036854775806"; + i++; sl_test[i].num = -0x7FFFFFFF00000000L -1L; sl_test[i].expected = "-9223372032559808513"; + i++; sl_test[i].num = -0x000000007FFFFFFFL -1L; sl_test[i].expected = "-2147483648"; + + i++; sl_test[i].num = -0x7FFF000000000000L -1L; sl_test[i].expected = "-9223090561878065153"; + i++; sl_test[i].num = -0x00007FFF00000000L -1L; sl_test[i].expected = "-140733193388033"; + i++; sl_test[i].num = -0x000000007FFF0000L -1L; sl_test[i].expected = "-2147418113"; + i++; sl_test[i].num = -0x0000000000007FFFL -1L; sl_test[i].expected = "-32768"; + + i++; sl_test[i].num = -0x7F00000000000000L -1L; sl_test[i].expected = "-9151314442816847873"; + i++; sl_test[i].num = -0x007F000000000000L -1L; sl_test[i].expected = "-35747322042253313"; + i++; sl_test[i].num = -0x00007F0000000000L -1L; sl_test[i].expected = "-139637976727553"; + i++; sl_test[i].num = -0x0000007F00000000L -1L; sl_test[i].expected = "-545460846593"; + i++; sl_test[i].num = -0x000000007F000000L -1L; sl_test[i].expected = "-2130706433"; + i++; sl_test[i].num = -0x00000000007F0000L -1L; sl_test[i].expected = "-8323073"; + i++; sl_test[i].num = -0x0000000000007F00L -1L; sl_test[i].expected = "-32513"; + i++; sl_test[i].num = -0x000000000000007FL -1L; sl_test[i].expected = "-128"; + + i++; sl_test[i].num = -0x7000000000000000L -1L; sl_test[i].expected = "-8070450532247928833"; + i++; sl_test[i].num = -0x0700000000000000L -1L; sl_test[i].expected = "-504403158265495553"; + i++; sl_test[i].num = -0x0070000000000000L -1L; sl_test[i].expected = "-31525197391593473"; + i++; sl_test[i].num = -0x0007000000000000L -1L; sl_test[i].expected = "-1970324836974593"; + i++; sl_test[i].num = -0x0000700000000000L -1L; sl_test[i].expected = "-123145302310913"; + i++; sl_test[i].num = -0x0000070000000000L -1L; sl_test[i].expected = "-7696581394433"; + i++; sl_test[i].num = -0x0000007000000000L -1L; sl_test[i].expected = "-481036337153"; + i++; sl_test[i].num = -0x0000000700000000L -1L; sl_test[i].expected = "-30064771073"; + i++; sl_test[i].num = -0x0000000070000000L -1L; sl_test[i].expected = "-1879048193"; + i++; sl_test[i].num = -0x0000000007000000L -1L; sl_test[i].expected = "-117440513"; + i++; sl_test[i].num = -0x0000000000700000L -1L; sl_test[i].expected = "-7340033"; + i++; sl_test[i].num = -0x0000000000070000L -1L; sl_test[i].expected = "-458753"; + i++; sl_test[i].num = -0x0000000000007000L -1L; sl_test[i].expected = "-28673"; + i++; sl_test[i].num = -0x0000000000000700L -1L; sl_test[i].expected = "-1793"; + i++; sl_test[i].num = -0x0000000000000070L -1L; sl_test[i].expected = "-113"; + i++; sl_test[i].num = -0x0000000000000007L -1L; sl_test[i].expected = "-8"; + + i++; sl_test[i].num = 0x0000000000000000L -1L; sl_test[i].expected = "-1"; + + num_slong_tests = i; + +#endif + + for(i=1; i<=num_slong_tests; i++) { + + for(j=0; j<BUFSZ; j++) + sl_test[i].result[j] = 'X'; + sl_test[i].result[BUFSZ-1] = '\0'; + + (void)curl_msprintf(sl_test[i].result, "%ld", sl_test[i].num); + + if(memcmp(sl_test[i].result, + sl_test[i].expected, + strlen(sl_test[i].expected))) { + printf("signed long test #%.2d: Failed (Expected: %s Got: %s)\n", + i, sl_test[i].expected, sl_test[i].result); + failed++; + } + + } + + if(!failed) + printf("All curl_mprintf() signed long tests OK!\n"); + else + printf("Some curl_mprintf() signed long tests Failed!\n"); + + return failed; +} + + +static int test_curl_off_t_formatting(void) +{ + int i, j; + int num_cofft_tests; + int failed = 0; + +#if (CURL_SIZEOF_CURL_OFF_T == 2) + + i=1; co_test[i].num = MPRNT_OFF_T_C(0x7FFF); co_test[i].expected = "32767"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFE); co_test[i].expected = "32766"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFD); co_test[i].expected = "32765"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x7F00); co_test[i].expected = "32512"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x07F0); co_test[i].expected = "2032"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x007F); co_test[i].expected = "127"; + + i++; co_test[i].num = MPRNT_OFF_T_C(0x7000); co_test[i].expected = "28672"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0700); co_test[i].expected = "1792"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0070); co_test[i].expected = "112"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0007); co_test[i].expected = "7"; + + i++; co_test[i].num = MPRNT_OFF_T_C(0x5000); co_test[i].expected = "20480"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0500); co_test[i].expected = "1280"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0050); co_test[i].expected = "80"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0005); co_test[i].expected = "5"; + + i++; co_test[i].num = MPRNT_OFF_T_C(0x0001); co_test[i].expected = "1"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000); co_test[i].expected = "0"; + + i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFF) -MPRNT_OFF_T_C(1); co_test[i].expected = "-32768"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFE) -MPRNT_OFF_T_C(1); co_test[i].expected = "-32767"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFD) -MPRNT_OFF_T_C(1); co_test[i].expected = "-32766"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x7F00) -MPRNT_OFF_T_C(1); co_test[i].expected = "-32513"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x07F0) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2033"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x007F) -MPRNT_OFF_T_C(1); co_test[i].expected = "-128"; + + i++; co_test[i].num = -MPRNT_OFF_T_C(0x7000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-28673"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0700) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1793"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0070) -MPRNT_OFF_T_C(1); co_test[i].expected = "-113"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0007) -MPRNT_OFF_T_C(1); co_test[i].expected = "-8"; + + i++; co_test[i].num = -MPRNT_OFF_T_C(0x5000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-20481"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0500) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1281"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0050) -MPRNT_OFF_T_C(1); co_test[i].expected = "-81"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0005) -MPRNT_OFF_T_C(1); co_test[i].expected = "-6"; + + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1"; + + num_cofft_tests = i; + +#elif (CURL_SIZEOF_CURL_OFF_T == 4) + + i=1; co_test[i].num = MPRNT_OFF_T_C(0x7FFFFFFF); co_test[i].expected = "2147483647"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFFFFFE); co_test[i].expected = "2147483646"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFFFFFD); co_test[i].expected = "2147483645"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFF0000); co_test[i].expected = "2147418112"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x00007FFF); co_test[i].expected = "32767"; + + i++; co_test[i].num = MPRNT_OFF_T_C(0x7F000000); co_test[i].expected = "2130706432"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x007F0000); co_test[i].expected = "8323072"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x00007F00); co_test[i].expected = "32512"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000007F); co_test[i].expected = "127"; + + i++; co_test[i].num = MPRNT_OFF_T_C(0x70000000); co_test[i].expected = "1879048192"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x07000000); co_test[i].expected = "117440512"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x00700000); co_test[i].expected = "7340032"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x00070000); co_test[i].expected = "458752"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x00007000); co_test[i].expected = "28672"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x00000700); co_test[i].expected = "1792"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x00000070); co_test[i].expected = "112"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x00000007); co_test[i].expected = "7"; + + i++; co_test[i].num = MPRNT_OFF_T_C(0x50000000); co_test[i].expected = "1342177280"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x05000000); co_test[i].expected = "83886080"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x00500000); co_test[i].expected = "5242880"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x00050000); co_test[i].expected = "327680"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x00005000); co_test[i].expected = "20480"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x00000500); co_test[i].expected = "1280"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x00000050); co_test[i].expected = "80"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x00000005); co_test[i].expected = "5"; + + i++; co_test[i].num = MPRNT_OFF_T_C(0x00000001); co_test[i].expected = "1"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x00000000); co_test[i].expected = "0"; + + i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFFFFFF) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2147483648"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFFFFFE) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2147483647"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFFFFFD) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2147483646"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFF0000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2147418113"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x00007FFF) -MPRNT_OFF_T_C(1); co_test[i].expected = "-32768"; + + i++; co_test[i].num = -MPRNT_OFF_T_C(0x7F000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2130706433"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x007F0000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-8323073"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x00007F00) -MPRNT_OFF_T_C(1); co_test[i].expected = "-32513"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000007F) -MPRNT_OFF_T_C(1); co_test[i].expected = "-128"; + + i++; co_test[i].num = -MPRNT_OFF_T_C(0x70000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1879048193"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x07000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-117440513"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x00700000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-7340033"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x00070000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-458753"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x00007000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-28673"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x00000700) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1793"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x00000070) -MPRNT_OFF_T_C(1); co_test[i].expected = "-113"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x00000007) -MPRNT_OFF_T_C(1); co_test[i].expected = "-8"; + + i++; co_test[i].num = -MPRNT_OFF_T_C(0x50000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1342177281"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x05000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-83886081"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x00500000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-5242881"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x00050000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-327681"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x00005000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-20481"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x00000500) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1281"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x00000050) -MPRNT_OFF_T_C(1); co_test[i].expected = "-81"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x00000005) -MPRNT_OFF_T_C(1); co_test[i].expected = "-6"; + + i++; co_test[i].num = MPRNT_OFF_T_C(0x00000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1"; + + num_cofft_tests = i; + +#elif (CURL_SIZEOF_CURL_OFF_T == 8) + + i=1; co_test[i].num = MPRNT_OFF_T_C(0x7FFFFFFFFFFFFFFF); co_test[i].expected = "9223372036854775807"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFFFFFFFFFFFFFE); co_test[i].expected = "9223372036854775806"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFFFFFFFFFFFFFD); co_test[i].expected = "9223372036854775805"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFFFFFF00000000); co_test[i].expected = "9223372032559808512"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x000000007FFFFFFF); co_test[i].expected = "2147483647"; + + i++; co_test[i].num = MPRNT_OFF_T_C(0x7FFF000000000000); co_test[i].expected = "9223090561878065152"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x00007FFF00000000); co_test[i].expected = "140733193388032"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x000000007FFF0000); co_test[i].expected = "2147418112"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000007FFF); co_test[i].expected = "32767"; + + i++; co_test[i].num = MPRNT_OFF_T_C(0x7F00000000000000); co_test[i].expected = "9151314442816847872"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x007F000000000000); co_test[i].expected = "35747322042253312"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x00007F0000000000); co_test[i].expected = "139637976727552"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000007F00000000); co_test[i].expected = "545460846592"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x000000007F000000); co_test[i].expected = "2130706432"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x00000000007F0000); co_test[i].expected = "8323072"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000007F00); co_test[i].expected = "32512"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x000000000000007F); co_test[i].expected = "127"; + + i++; co_test[i].num = MPRNT_OFF_T_C(0x7000000000000000); co_test[i].expected = "8070450532247928832"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0700000000000000); co_test[i].expected = "504403158265495552"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0070000000000000); co_test[i].expected = "31525197391593472"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0007000000000000); co_test[i].expected = "1970324836974592"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000700000000000); co_test[i].expected = "123145302310912"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000070000000000); co_test[i].expected = "7696581394432"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000007000000000); co_test[i].expected = "481036337152"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000700000000); co_test[i].expected = "30064771072"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000070000000); co_test[i].expected = "1879048192"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000007000000); co_test[i].expected = "117440512"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000700000); co_test[i].expected = "7340032"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000070000); co_test[i].expected = "458752"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000007000); co_test[i].expected = "28672"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000000700); co_test[i].expected = "1792"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000000070); co_test[i].expected = "112"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000000007); co_test[i].expected = "7"; + + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000000001); co_test[i].expected = "1"; + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000000000); co_test[i].expected = "0"; + + i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFFFFFFFFFFFFFF) -MPRNT_OFF_T_C(1); co_test[i].expected = "-9223372036854775808"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFFFFFFFFFFFFFE) -MPRNT_OFF_T_C(1); co_test[i].expected = "-9223372036854775807"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFFFFFFFFFFFFFD) -MPRNT_OFF_T_C(1); co_test[i].expected = "-9223372036854775806"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFFFFFF00000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-9223372032559808513"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x000000007FFFFFFF) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2147483648"; + + i++; co_test[i].num = -MPRNT_OFF_T_C(0x7FFF000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-9223090561878065153"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x00007FFF00000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-140733193388033"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x000000007FFF0000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2147418113"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000007FFF) -MPRNT_OFF_T_C(1); co_test[i].expected = "-32768"; + + i++; co_test[i].num = -MPRNT_OFF_T_C(0x7F00000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-9151314442816847873"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x007F000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-35747322042253313"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x00007F0000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-139637976727553"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000007F00000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-545460846593"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x000000007F000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-2130706433"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x00000000007F0000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-8323073"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000007F00) -MPRNT_OFF_T_C(1); co_test[i].expected = "-32513"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x000000000000007F) -MPRNT_OFF_T_C(1); co_test[i].expected = "-128"; + + i++; co_test[i].num = -MPRNT_OFF_T_C(0x7000000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-8070450532247928833"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0700000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-504403158265495553"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0070000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-31525197391593473"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0007000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1970324836974593"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000700000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-123145302310913"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000070000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-7696581394433"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000007000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-481036337153"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000700000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-30064771073"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000070000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1879048193"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000007000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-117440513"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000700000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-7340033"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000070000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-458753"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000007000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-28673"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000000700) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1793"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000000070) -MPRNT_OFF_T_C(1); co_test[i].expected = "-113"; + i++; co_test[i].num = -MPRNT_OFF_T_C(0x0000000000000007) -MPRNT_OFF_T_C(1); co_test[i].expected = "-8"; + + i++; co_test[i].num = MPRNT_OFF_T_C(0x0000000000000000) -MPRNT_OFF_T_C(1); co_test[i].expected = "-1"; + + num_cofft_tests = i; + +#endif + + for(i=1; i<=num_cofft_tests; i++) { + + for(j=0; j<BUFSZ; j++) + co_test[i].result[j] = 'X'; + co_test[i].result[BUFSZ-1] = '\0'; + + (void)curl_msprintf(co_test[i].result, "%" FORMAT_OFF_T, co_test[i].num); + + if(memcmp(co_test[i].result, + co_test[i].expected, + strlen(co_test[i].expected))) { + printf("curl_off_t test #%.2d: Failed (Expected: %s Got: %s)\n", + i, co_test[i].expected, co_test[i].result); + failed++; + } + + } + + if(!failed) + printf("All curl_mprintf() curl_off_t tests OK!\n"); + else + printf("Some curl_mprintf() curl_off_t tests Failed!\n"); + + return failed; +} + + +int test(char *URL) +{ + int errors = 0; + (void)URL; /* not used */ + + errors += test_unsigned_short_formatting(); + + errors += test_signed_short_formatting(); + + errors += test_unsigned_int_formatting(); + + errors += test_signed_int_formatting(); + + errors += test_unsigned_long_formatting(); + + errors += test_signed_long_formatting(); + + errors += test_curl_off_t_formatting(); + + if(errors) + return TEST_ERR_MAJOR_BAD; + else + return 0; +} diff --git a/tests/libtest/lib560.c b/tests/libtest/lib560.c new file mode 100644 index 000000000..e8be1c7bd --- /dev/null +++ b/tests/libtest/lib560.c @@ -0,0 +1,113 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "testutil.h" +#include "warnless.h" +#include "memdebug.h" + +#define TEST_HANG_TIMEOUT 60 * 1000 + +/* + * Simply download a HTTPS file! + * + * This test was added after the HTTPS-using-multi-interface with OpenSSL + * regression of 7.19.1 to hopefully prevent this embarassing mistake from + * appearing again... Unfortunately the bug wasn't triggered by this test, + * which presumably is because the connect to a local server is too + * fast/different compared to the real/distant servers we saw the bug happen + * with. + */ +int test(char *URL) +{ + CURL *http_handle = NULL; + CURLM *multi_handle = NULL; + int res = 0; + + int still_running; /* keep number of running handles */ + + start_test_timing(); + + /* + ** curl_global_init called indirectly from curl_easy_init. + */ + + easy_init(http_handle); + + /* set options */ + easy_setopt(http_handle, CURLOPT_URL, URL); + easy_setopt(http_handle, CURLOPT_HEADER, 1L); + easy_setopt(http_handle, CURLOPT_SSL_VERIFYPEER, 0L); + easy_setopt(http_handle, CURLOPT_SSL_VERIFYHOST, 0L); + + /* init a multi stack */ + multi_init(multi_handle); + + /* add the individual transfers */ + multi_add_handle(multi_handle, http_handle); + + /* we start some action by calling perform right away */ + multi_perform(multi_handle, &still_running); + + abort_on_test_timeout(); + + while(still_running) { + struct timeval timeout; + + fd_set fdread; + fd_set fdwrite; + fd_set fdexcep; + int maxfd = -99; + + FD_ZERO(&fdread); + FD_ZERO(&fdwrite); + FD_ZERO(&fdexcep); + + /* set a suitable timeout to play around with */ + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + /* get file descriptors from the transfers */ + multi_fdset(multi_handle, &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(); + + /* timeout or readable/writable sockets */ + multi_perform(multi_handle, &still_running); + + abort_on_test_timeout(); + } + +test_cleanup: + + /* undocumented cleanup sequence - type UA */ + + curl_multi_cleanup(multi_handle); + curl_easy_cleanup(http_handle); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib562.c b/tests/libtest/lib562.c new file mode 100644 index 000000000..a5f0ea534 --- /dev/null +++ b/tests/libtest/lib562.c @@ -0,0 +1,73 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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" + +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#include "memdebug.h" + +/* + * From "KNOWN_BUGS" April 2009: + + 59. If the CURLOPT_PORT option is used on an FTP URL like + "ftp://example.com/file;type=A" the ";type=A" is stripped off. + + */ + +int test(char *URL) +{ + CURL *curl; + CURLcode res = CURLE_OK; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + /* get a curl handle */ + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + /* enable verbose */ + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + /* set port number */ + test_setopt(curl, CURLOPT_PORT, strtol(libtest_arg2, NULL, 10)); + + /* specify target */ + test_setopt(curl,CURLOPT_URL, URL); + + /* Now run off and do what you've been told! */ + res = curl_easy_perform(curl); + +test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib564.c b/tests/libtest/lib564.c new file mode 100644 index 000000000..ed00e1bf6 --- /dev/null +++ b/tests/libtest/lib564.c @@ -0,0 +1,93 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 60 * 1000 + +int test(char *URL) +{ + int res = 0; + CURL *curl = NULL; + int running; + CURLM *m = NULL; + + start_test_timing(); + + global_init(CURL_GLOBAL_ALL); + + easy_init(curl); + + easy_setopt(curl, CURLOPT_URL, URL); + easy_setopt(curl, CURLOPT_VERBOSE, 1L); + easy_setopt(curl, CURLOPT_PROXY, libtest_arg2); + easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4); + + multi_init(m); + + multi_add_handle(m, curl); + + fprintf(stderr, "Start at URL 0\n"); + + for(;;) { + struct timeval interval; + fd_set rd, wr, exc; + int maxfd = -99; + + interval.tv_sec = 1; + interval.tv_usec = 0; + + multi_perform(m, &running); + + abort_on_test_timeout(); + + if(!running) + break; /* done */ + + FD_ZERO(&rd); + FD_ZERO(&wr); + FD_ZERO(&exc); + + multi_fdset(m, &rd, &wr, &exc, &maxfd); + + /* At this point, maxfd is guaranteed to be greater or equal than -1. */ + + select_test(maxfd+1, &rd, &wr, &exc, &interval); + + abort_on_test_timeout(); + } + +test_cleanup: + + /* undocumented cleanup sequence - type UB */ + + curl_easy_cleanup(curl); + curl_multi_cleanup(m); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib566.c b/tests/libtest/lib566.c new file mode 100644 index 000000000..ba839d65f --- /dev/null +++ b/tests/libtest/lib566.c @@ -0,0 +1,67 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +int test(char *URL) +{ + CURLcode res; + CURL *curl; + + double content_length = 3; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_HEADER, 1L); + + res = curl_easy_perform(curl); + + if(!res) { + FILE *moo; + res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, + &content_length); + moo = fopen(libtest_arg2, "wb"); + if(moo) { + fprintf(moo, "CL: %.0f\n", content_length); + fclose(moo); + } + } + +test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} + diff --git a/tests/libtest/lib567.c b/tests/libtest/lib567.c new file mode 100644 index 000000000..573529cd8 --- /dev/null +++ b/tests/libtest/lib567.c @@ -0,0 +1,69 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +/* + * Test a simple OPTIONS request with a custom header + */ +int test(char *URL) +{ + CURLcode res; + CURL *curl; + struct curl_slist *custom_headers=NULL; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + /* Dump data to stdout for protocol verification */ + test_setopt(curl, CURLOPT_HEADERDATA, stdout); + test_setopt(curl, CURLOPT_WRITEDATA, stdout); + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_RTSP_STREAM_URI, URL); + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_OPTIONS); + test_setopt(curl, CURLOPT_USERAGENT, "test567"); + + custom_headers = curl_slist_append(custom_headers, "Test-Number: 567"); + test_setopt(curl, CURLOPT_RTSPHEADER, custom_headers); + + res = curl_easy_perform(curl); + +test_cleanup: + + if(custom_headers) + curl_slist_free_all(custom_headers); + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} + diff --git a/tests/libtest/lib568.c b/tests/libtest/lib568.c new file mode 100644 index 000000000..4b15821f2 --- /dev/null +++ b/tests/libtest/lib568.c @@ -0,0 +1,175 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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" + +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#include <curl/mprintf.h> + +#include "memdebug.h" + +/* build request url */ +static char *suburl(const char *base, int i) +{ + return curl_maprintf("%s%.4d", base, i); +} + +/* + * Test the Client->Server ANNOUNCE functionality (PUT style) + */ +int test(char *URL) +{ + int res; + CURL *curl; + int sdp; + FILE *sdpf = NULL; + struct_stat file_info; + char *stream_uri = NULL; + int request=1; + struct curl_slist *custom_headers=NULL; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_HEADERDATA, stdout); + test_setopt(curl, CURLOPT_WRITEDATA, stdout); + + test_setopt(curl, CURLOPT_URL, URL); + + if((stream_uri = suburl(URL, request++)) == NULL) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); + free(stream_uri); + stream_uri = NULL; + + sdp = open("log/file568.txt", O_RDONLY); + fstat(sdp, &file_info); + close(sdp); + + sdpf = fopen("log/file568.txt", "rb"); + if(sdpf == NULL) { + fprintf(stderr, "can't open log/file568.txt\n"); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_ANNOUNCE); + + test_setopt(curl, CURLOPT_READDATA, sdpf); + test_setopt(curl, CURLOPT_UPLOAD, 1L); + test_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t) file_info.st_size); + + /* Do the ANNOUNCE */ + res = curl_easy_perform(curl); + if(res) + goto test_cleanup; + + test_setopt(curl, CURLOPT_UPLOAD, 0L); + fclose(sdpf); + sdpf = NULL; + + /* Make sure we can do a normal request now */ + if((stream_uri = suburl(URL, request++)) == NULL) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); + free(stream_uri); + stream_uri = NULL; + + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_DESCRIBE); + res = curl_easy_perform(curl); + if(res) + goto test_cleanup; + + /* Now do a POST style one */ + + if((stream_uri = suburl(URL, request++)) == NULL) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); + free(stream_uri); + stream_uri = NULL; + + custom_headers = curl_slist_append(custom_headers, + "Content-Type: posty goodness"); + if(!custom_headers) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSPHEADER, custom_headers); + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_ANNOUNCE); + test_setopt(curl, CURLOPT_POSTFIELDS, "postyfield=postystuff&project=curl\n"); + + res = curl_easy_perform(curl); + if(res) + goto test_cleanup; + + test_setopt(curl, CURLOPT_POSTFIELDS, NULL); + test_setopt(curl, CURLOPT_RTSPHEADER, NULL); + curl_slist_free_all(custom_headers); + custom_headers = NULL; + + /* Make sure we can do a normal request now */ + if((stream_uri = suburl(URL, request++)) == NULL) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); + free(stream_uri); + stream_uri = NULL; + + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_OPTIONS); + res = curl_easy_perform(curl); + +test_cleanup: + + if(sdpf) + fclose(sdpf); + + if(stream_uri) + free(stream_uri); + + if(custom_headers) + curl_slist_free_all(custom_headers); + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} + diff --git a/tests/libtest/lib569.c b/tests/libtest/lib569.c new file mode 100644 index 000000000..a434d7459 --- /dev/null +++ b/tests/libtest/lib569.c @@ -0,0 +1,129 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 <curl/mprintf.h> + +#include "memdebug.h" + +/* build request url */ +static char *suburl(const char *base, int i) +{ + return curl_maprintf("%s%.4d", base, i); +} + +/* + * Test Session ID capture + */ +int test(char *URL) +{ + int res; + CURL *curl; + char *stream_uri = NULL; + char *rtsp_session_id; + int request=1; + int i; + FILE *idfile = NULL; + + idfile = fopen(libtest_arg2, "wb"); + if(idfile == NULL) { + fprintf(stderr, "couldn't open the Session ID File\n"); + return TEST_ERR_MAJOR_BAD; + } + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + fclose(idfile); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + fclose(idfile); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_HEADERDATA, stdout); + test_setopt(curl, CURLOPT_WRITEDATA, stdout); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + test_setopt(curl, CURLOPT_URL, URL); + + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP); + res = curl_easy_perform(curl); + if(res != (int)CURLE_BAD_FUNCTION_ARGUMENT) { + fprintf(stderr, "This should have failed. " + "Cannot setup without a Transport: header"); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + + /* Go through the various Session IDs */ + for(i = 0; i < 3; i++) { + if((stream_uri = suburl(URL, request++)) == NULL) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); + free(stream_uri); + stream_uri = NULL; + + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP); + test_setopt(curl, CURLOPT_RTSP_TRANSPORT, "Fake/NotReal/JustATest;foo=baz"); + res = curl_easy_perform(curl); + if(res) + goto test_cleanup; + + curl_easy_getinfo(curl, CURLINFO_RTSP_SESSION_ID, &rtsp_session_id); + fprintf(idfile, "Got Session ID: [%s]\n", rtsp_session_id); + rtsp_session_id = NULL; + + if((stream_uri = suburl(URL, request++)) == NULL) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); + free(stream_uri); + stream_uri = NULL; + + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_TEARDOWN); + res = curl_easy_perform(curl); + + /* Clear for the next go-round */ + test_setopt(curl, CURLOPT_RTSP_SESSION_ID, NULL); + } + +test_cleanup: + + if(idfile) + fclose(idfile); + + if(stream_uri) + free(stream_uri); + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} + diff --git a/tests/libtest/lib570.c b/tests/libtest/lib570.c new file mode 100644 index 000000000..a9fac9915 --- /dev/null +++ b/tests/libtest/lib570.c @@ -0,0 +1,117 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 <curl/mprintf.h> + +#include "memdebug.h" + +/* build request url */ +static char *suburl(const char *base, int i) +{ + return curl_maprintf("%s%.4d", base, i); +} + +int test(char *URL) +{ + int res; + CURL *curl; + int request=1; + char *stream_uri = NULL; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_HEADERDATA, stdout); + test_setopt(curl, CURLOPT_WRITEDATA, stdout); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + test_setopt(curl, CURLOPT_URL, URL); + + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_OPTIONS); + + if((stream_uri = suburl(URL, request++)) == NULL) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); + free(stream_uri); + stream_uri = NULL; + + res = curl_easy_perform(curl); + if(res != (int)CURLE_RTSP_CSEQ_ERROR) { + fprintf(stderr, "Failed to detect CSeq mismatch"); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + + test_setopt(curl, CURLOPT_RTSP_CLIENT_CSEQ, 999); + test_setopt(curl, CURLOPT_RTSP_TRANSPORT, + "RAW/RAW/UDP;unicast;client_port=3056-3057"); + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP); + + if((stream_uri = suburl(URL, request++)) == NULL) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); + free(stream_uri); + stream_uri = NULL; + + res = curl_easy_perform(curl); + if(res) + goto test_cleanup; + + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_PLAY); + + if((stream_uri = suburl(URL, request++)) == NULL) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); + free(stream_uri); + stream_uri = NULL; + + res = curl_easy_perform(curl); + if(res != CURLE_RTSP_SESSION_ERROR) { + fprintf(stderr, "Failed to detect a Session ID mismatch"); + } + +test_cleanup: + + if(stream_uri) + free(stream_uri); + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} + diff --git a/tests/libtest/lib571.c b/tests/libtest/lib571.c new file mode 100644 index 000000000..ba0aa1ce4 --- /dev/null +++ b/tests/libtest/lib571.c @@ -0,0 +1,212 @@ +/*************************************************************************** + * _ _ ____ _ + * 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" + +#ifdef HAVE_NETINET_IN_H +# include <netinet/in.h> +#endif +#ifdef HAVE_NETDB_H +# include <netdb.h> +#endif +#ifdef HAVE_ARPA_INET_H +# include <arpa/inet.h> +#endif +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif +#ifdef HAVE_FCNTL_H +# include <fcntl.h> +#endif + +#include <curl/mprintf.h> + +#include "warnless.h" +#include "memdebug.h" + +#define RTP_PKT_CHANNEL(p) ((int)((unsigned char)((p)[1]))) + +#define RTP_PKT_LENGTH(p) ((((int)((unsigned char)((p)[2]))) << 8) | \ + ((int)((unsigned char)((p)[3])))) + +#define RTP_DATA_SIZE 12 +static const char *RTP_DATA = "$_1234\n\0asdf"; + +static int rtp_packet_count = 0; + +static size_t rtp_write(void *ptr, size_t size, size_t nmemb, void *stream) { + char *data = (char *)ptr; + int channel = RTP_PKT_CHANNEL(data); + int message_size; + int coded_size = RTP_PKT_LENGTH(data); + size_t failure = (size * nmemb) ? 0 : 1; + int i; + (void)stream; + + message_size = curlx_uztosi(size * nmemb) - 4; + + printf("RTP: message size %d, channel %d\n", message_size, channel); + if(message_size != coded_size) { + printf("RTP embedded size (%d) does not match the write size (%d).\n", + coded_size, message_size); + return failure; + } + + data += 4; + for(i = 0; i < message_size; i+= RTP_DATA_SIZE) { + if(message_size - i > RTP_DATA_SIZE) { + if(memcmp(RTP_DATA, data + i, RTP_DATA_SIZE) != 0) { + printf("RTP PAYLOAD CORRUPTED [%s]\n", data + i); + return failure; + } + } else { + if (memcmp(RTP_DATA, data + i, message_size - i) != 0) { + printf("RTP PAYLOAD END CORRUPTED (%d), [%s]\n", + message_size - i, data + i); + return failure; + } + } + } + + rtp_packet_count++; + fprintf(stderr, "packet count is %d\n", rtp_packet_count); + + return size * nmemb; +} + +/* build request url */ +static char *suburl(const char *base, int i) +{ + return curl_maprintf("%s%.4d", base, i); +} + +int test(char *URL) +{ + int res; + CURL *curl; + char *stream_uri = NULL; + int request=1; + FILE *protofile = NULL; + + protofile = fopen(libtest_arg2, "wb"); + if(protofile == NULL) { + fprintf(stderr, "Couldn't open the protocol dump file\n"); + return TEST_ERR_MAJOR_BAD; + } + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + fclose(protofile); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + fclose(protofile); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + test_setopt(curl, CURLOPT_URL, URL); + + if((stream_uri = suburl(URL, request++)) == NULL) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); + free(stream_uri); + stream_uri = NULL; + + test_setopt(curl, CURLOPT_INTERLEAVEFUNCTION, rtp_write); + test_setopt(curl, CURLOPT_TIMEOUT, 3); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_WRITEDATA, protofile); + + test_setopt(curl, CURLOPT_RTSP_TRANSPORT, "RTP/AVP/TCP;interleaved=0-1"); + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP); + + res = curl_easy_perform(curl); + if(res) + goto test_cleanup; + + /* This PLAY starts the interleave */ + if((stream_uri = suburl(URL, request++)) == NULL) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); + free(stream_uri); + stream_uri = NULL; + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_PLAY); + + res = curl_easy_perform(curl); + if(res) + goto test_cleanup; + + /* The DESCRIBE request will try to consume data after the Content */ + if((stream_uri = suburl(URL, request++)) == NULL) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); + free(stream_uri); + stream_uri = NULL; + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_DESCRIBE); + + res = curl_easy_perform(curl); + if(res) + goto test_cleanup; + + if((stream_uri = suburl(URL, request++)) == NULL) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); + free(stream_uri); + stream_uri = NULL; + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_PLAY); + + res = curl_easy_perform(curl); + if(res) + goto test_cleanup; + + fprintf(stderr, "PLAY COMPLETE\n"); + + /* Use Receive to get the rest of the data */ + while(!res && rtp_packet_count < 13) { + fprintf(stderr, "LOOPY LOOP!\n"); + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_RECEIVE); + res = curl_easy_perform(curl); + } + +test_cleanup: + + if(stream_uri) + free(stream_uri); + + if(protofile) + fclose(protofile); + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} + diff --git a/tests/libtest/lib572.c b/tests/libtest/lib572.c new file mode 100644 index 000000000..3df4d036a --- /dev/null +++ b/tests/libtest/lib572.c @@ -0,0 +1,181 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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" + +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif +#ifdef HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#include <curl/mprintf.h> + +#include "memdebug.h" + +/* build request url */ +static char *suburl(const char *base, int i) +{ + return curl_maprintf("%s%.4d", base, i); +} + +/* + * Test GET_PARAMETER: PUT, HEARTBEAT, and POST + */ +int test(char *URL) +{ + int res; + CURL *curl; + int params; + FILE *paramsf = NULL; + struct_stat file_info; + char *stream_uri = NULL; + int request=1; + struct curl_slist *custom_headers=NULL; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + + test_setopt(curl, CURLOPT_HEADERDATA, stdout); + test_setopt(curl, CURLOPT_WRITEDATA, stdout); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + test_setopt(curl, CURLOPT_URL, URL); + + /* SETUP */ + if((stream_uri = suburl(URL, request++)) == NULL) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); + free(stream_uri); + stream_uri = NULL; + + test_setopt(curl, CURLOPT_RTSP_TRANSPORT, "Planes/Trains/Automobiles"); + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_SETUP); + res = curl_easy_perform(curl); + if(res) + goto test_cleanup; + + if((stream_uri = suburl(URL, request++)) == NULL) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); + free(stream_uri); + stream_uri = NULL; + + /* PUT style GET_PARAMETERS */ + params = open("log/file572.txt", O_RDONLY); + fstat(params, &file_info); + close(params); + + paramsf = fopen("log/file572.txt", "rb"); + if(paramsf == NULL) { + fprintf(stderr, "can't open log/file572.txt\n"); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_GET_PARAMETER); + + test_setopt(curl, CURLOPT_READDATA, paramsf); + test_setopt(curl, CURLOPT_UPLOAD, 1L); + test_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t) file_info.st_size); + + res = curl_easy_perform(curl); + if(res) + goto test_cleanup; + + test_setopt(curl, CURLOPT_UPLOAD, 0L); + fclose(paramsf); + paramsf = NULL; + + /* Heartbeat GET_PARAMETERS */ + if((stream_uri = suburl(URL, request++)) == NULL) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); + free(stream_uri); + stream_uri = NULL; + + res = curl_easy_perform(curl); + if(res) + goto test_cleanup; + + /* POST GET_PARAMETERS */ + + if((stream_uri = suburl(URL, request++)) == NULL) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); + free(stream_uri); + stream_uri = NULL; + + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_GET_PARAMETER); + test_setopt(curl, CURLOPT_POSTFIELDS, "packets_received\njitter\n"); + + res = curl_easy_perform(curl); + if(res) + goto test_cleanup; + + test_setopt(curl, CURLOPT_POSTFIELDS, NULL); + + /* Make sure we can do a normal request now */ + if((stream_uri = suburl(URL, request++)) == NULL) { + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + test_setopt(curl, CURLOPT_RTSP_STREAM_URI, stream_uri); + free(stream_uri); + stream_uri = NULL; + + test_setopt(curl, CURLOPT_RTSP_REQUEST, CURL_RTSPREQ_OPTIONS); + res = curl_easy_perform(curl); + +test_cleanup: + + if(paramsf) + fclose(paramsf); + + if(stream_uri) + free(stream_uri); + + if(custom_headers) + curl_slist_free_all(custom_headers); + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} + diff --git a/tests/libtest/lib573.c b/tests/libtest/lib573.c new file mode 100644 index 000000000..b49d26a5d --- /dev/null +++ b/tests/libtest/lib573.c @@ -0,0 +1,113 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "testtrace.h" +#include "testutil.h" +#include "warnless.h" +#include "memdebug.h" + +#define TEST_HANG_TIMEOUT 60 * 1000 + +/* + * Get a single URL without select(). + */ + +int test(char *URL) +{ + CURL *c = NULL; + CURLM *m = NULL; + int res = 0; + int running = 1; + double connect_time = 0.0; + double dbl_epsilon; + + dbl_epsilon = 1.0; + do { + dbl_epsilon /= 2.0; + } while ((double)(1.0 + (dbl_epsilon/2.0)) > (double)1.0); + + start_test_timing(); + + global_init(CURL_GLOBAL_ALL); + + easy_init(c); + + easy_setopt(c, CURLOPT_HEADER, 1L); + easy_setopt(c, CURLOPT_URL, URL); + + libtest_debug_config.nohex = 1; + libtest_debug_config.tracetime = 1; + easy_setopt(c, CURLOPT_DEBUGDATA, &libtest_debug_config); + easy_setopt(c, CURLOPT_DEBUGFUNCTION, libtest_debug_cb); + easy_setopt(c, CURLOPT_VERBOSE, 1L); + + multi_init(m); + + multi_add_handle(m, c); + + while (running) { + struct timeval timeout; + fd_set fdread, fdwrite, fdexcep; + int maxfd = -99; + + timeout.tv_sec = 0; + timeout.tv_usec = 100000L; /* 100 ms */ + + multi_perform(m, &running); + + abort_on_test_timeout(); + + if(!running) + break; /* done */ + + FD_ZERO(&fdread); + FD_ZERO(&fdwrite); + FD_ZERO(&fdexcep); + + multi_fdset(m, &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(); + } + + curl_easy_getinfo(c, CURLINFO_CONNECT_TIME, &connect_time); + if (connect_time < dbl_epsilon) { + fprintf(stderr, "connect time is < epsilon\n"); + res = TEST_ERR_MAJOR_BAD; + } + +test_cleanup: + + /* proper cleanup sequence - type PA */ + + curl_multi_remove_handle(m, c); + curl_multi_cleanup(m); + curl_easy_cleanup(c); + curl_global_cleanup(); + + return res; +} + diff --git a/tests/libtest/lib574.c b/tests/libtest/lib574.c new file mode 100644 index 000000000..afb2bceae --- /dev/null +++ b/tests/libtest/lib574.c @@ -0,0 +1,68 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +static int new_fnmatch(const char *pattern, const char *string) +{ + (void)pattern; + (void)string; + return CURL_FNMATCHFUNC_MATCH; +} + +int test(char *URL) +{ + int res; + CURL *curl; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_WILDCARDMATCH, 1L); + test_setopt(curl, CURLOPT_FNMATCH_FUNCTION, new_fnmatch); + + res = curl_easy_perform(curl); + if(res) { + fprintf(stderr, "curl_easy_perform() failed %d\n", res); + goto test_cleanup; + } + res = curl_easy_perform(curl); + if(res) { + fprintf(stderr, "curl_easy_perform() failed %d\n", res); + goto test_cleanup; + } + +test_cleanup: + curl_easy_cleanup(curl); + curl_global_cleanup(); + return res; +} diff --git a/tests/libtest/lib575.c b/tests/libtest/lib575.c new file mode 100644 index 000000000..942df68c5 --- /dev/null +++ b/tests/libtest/lib575.c @@ -0,0 +1,114 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 60 * 1000 + +/* 3x download! + * 1. normal + * 2. dup handle + * 3. with multi interface + */ + +int test(char *URL) +{ + CURL *handle = NULL; + CURL *duphandle = 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_WILDCARDMATCH, 1L); + easy_setopt(handle, CURLOPT_VERBOSE, 1L); + + res = curl_easy_perform(handle); + if(res) + goto test_cleanup; + + res = curl_easy_perform(handle); + if(res) + goto test_cleanup; + + duphandle = curl_easy_duphandle(handle); + if(!duphandle) + goto test_cleanup; + curl_easy_cleanup(handle); + handle = duphandle; + + 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; + + 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(); + + multi_perform(mhandle, &still_running); + + abort_on_test_timeout(); + } + +test_cleanup: + + /* undocumented cleanup sequence - type UA */ + + curl_multi_cleanup(mhandle); + curl_easy_cleanup(handle); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib576.c b/tests/libtest/lib576.c new file mode 100644 index 000000000..61bb61325 --- /dev/null +++ b/tests/libtest/lib576.c @@ -0,0 +1,124 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "testutil.h" +#include "memdebug.h" + +typedef struct { + int remains; + int print_content; +} chunk_data_t; + +static +long chunk_bgn(const struct curl_fileinfo *finfo, void *ptr, int remains); +static +long chunk_end(void *ptr); + +static +long chunk_bgn(const struct curl_fileinfo *finfo, void *ptr, int remains) +{ + chunk_data_t *ch_d = ptr; + ch_d->remains = remains; + + printf("=============================================================\n"); + printf("Remains: %d\n", remains); + printf("Filename: %s\n", finfo->filename); + if(finfo->strings.perm) { + printf("Permissions: %s", finfo->strings.perm); + if(finfo->flags & CURLFINFOFLAG_KNOWN_PERM) + printf(" (parsed => %o)", finfo->perm); + printf("\n"); + } + printf("Size: %ldB\n", (long)finfo->size); + if(finfo->strings.user) + printf("User: %s\n", finfo->strings.user); + if(finfo->strings.group) + printf("Group: %s\n", finfo->strings.group); + if(finfo->strings.time) + printf("Time: %s\n", finfo->strings.time); + printf("Filetype: "); + switch(finfo->filetype) { + case CURLFILETYPE_FILE: + printf("regular file\n"); + break; + case CURLFILETYPE_DIRECTORY: + printf("directory\n"); + break; + case CURLFILETYPE_SYMLINK: + printf("symlink\n"); + printf("Target: %s\n", finfo->strings.target); + break; + default: + printf("other type\n"); + break; + } + if(finfo->filetype == CURLFILETYPE_FILE) { + ch_d->print_content = 1; + printf("Content:\n-------------------------------------------------------------\n"); + } + if(strcmp(finfo->filename, "someothertext.txt") == 0) { + printf("# THIS CONTENT WAS SKIPPED IN CHUNK_BGN CALLBACK #\n"); + return CURL_CHUNK_BGN_FUNC_SKIP; + } + return CURL_CHUNK_BGN_FUNC_OK; +} + +static +long chunk_end(void *ptr) +{ + chunk_data_t *ch_d = ptr; + if(ch_d->print_content) { + ch_d->print_content = 0; + printf("-------------------------------------------------------------\n"); + } + if(ch_d->remains == 1) + printf("=============================================================\n"); + return CURL_CHUNK_END_FUNC_OK; +} + +int test(char *URL) +{ + CURL *handle = NULL; + CURLcode res = CURLE_OK; + chunk_data_t chunk_data = {0,0}; + curl_global_init(CURL_GLOBAL_ALL); + handle = curl_easy_init(); + if(!handle) { + res = CURLE_OUT_OF_MEMORY; + goto test_cleanup; + } + + test_setopt(handle, CURLOPT_URL, URL); + test_setopt(handle, CURLOPT_WILDCARDMATCH, 1L); + test_setopt(handle, CURLOPT_CHUNK_BGN_FUNCTION, chunk_bgn); + test_setopt(handle, CURLOPT_CHUNK_END_FUNCTION, chunk_end); + test_setopt(handle, CURLOPT_CHUNK_DATA, &chunk_data); + + res = curl_easy_perform(handle); + +test_cleanup: + if(handle) + curl_easy_cleanup(handle); + curl_global_cleanup(); + return res; +} diff --git a/tests/libtest/lib578.c b/tests/libtest/lib578.c new file mode 100644 index 000000000..a39b31772 --- /dev/null +++ b/tests/libtest/lib578.c @@ -0,0 +1,102 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 "memdebug.h" + +/* The size of data should be kept below MAX_INITIAL_POST_SIZE! */ +static char data[]="this is a short string.\n"; + +static size_t data_size = sizeof(data) / sizeof(char); + +static int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) +{ + FILE *moo = fopen(libtest_arg2, "wb"); + + (void)clientp; /* UNUSED */ + (void)dltotal; /* UNUSED */ + (void)dlnow; /* UNUSED */ + + if(moo) { + if ((size_t)ultotal == data_size && (size_t)ulnow == data_size) + fprintf(moo, "PASSED, UL data matched data size\n"); + else + fprintf(moo, "Progress callback called with UL %f out of %f\n", ulnow, ultotal); + fclose(moo); + } + return 0; +} + +int test(char *URL) +{ + CURL *curl; + CURLcode res=CURLE_OK; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + /* First set the URL that is about to receive our POST. */ + test_setopt(curl, CURLOPT_URL, URL); + + /* Now specify we want to POST data */ + test_setopt(curl, CURLOPT_POST, 1L); + +#ifdef CURL_DOES_CONVERSIONS + /* Convert the POST data to ASCII */ + test_setopt(curl, CURLOPT_TRANSFERTEXT, 1L); +#endif + + /* Set the expected POST size */ + test_setopt(curl, CURLOPT_POSTFIELDSIZE, data_size); + test_setopt(curl, CURLOPT_POSTFIELDS, data); + + /* we want to use our own progress function */ + test_setopt(curl, CURLOPT_NOPROGRESS, 0L); + test_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback); + + /* pointer to pass to our read function */ + + /* get verbose debug output please */ + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + /* include headers in the output */ + test_setopt(curl, CURLOPT_HEADER, 1L); + + /* Perform the request, res will get the return code */ + res = curl_easy_perform(curl); + +test_cleanup: + + /* always cleanup */ + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib579.c b/tests/libtest/lib579.c new file mode 100644 index 000000000..c5cf603bb --- /dev/null +++ b/tests/libtest/lib579.c @@ -0,0 +1,161 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "memdebug.h" + +static const char * const post[]={ + "one", + "two", + "three", + "and a final longer crap: four", + NULL +}; + + +struct WriteThis { + int counter; +}; + +static int progress_callback(void *clientp, double dltotal, double dlnow, + double ultotal, double ulnow) +{ + FILE *moo; + static int prev_ultotal = -1; + static int prev_ulnow = -1; + (void)clientp; /* UNUSED */ + (void)dltotal; /* UNUSED */ + (void)dlnow; /* UNUSED */ + + /* to avoid depending on timing, which will cause this progress function to + get called a different number of times depending on circumstances, we + only log these lines if the numbers are different from the previous + invoke */ + if((prev_ultotal != (int)ultotal) || + (prev_ulnow != (int)ulnow)) { + + moo = fopen(libtest_arg2, "ab"); + if(moo) { + fprintf(moo, "Progress callback called with UL %d out of %d\n", + (int)ulnow, (int)ultotal); + fclose(moo); + } + prev_ulnow = (int) ulnow; + prev_ultotal = (int) ultotal; + } + return 0; +} + +static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp) +{ + struct WriteThis *pooh = (struct WriteThis *)userp; + const char *data; + + if(size*nmemb < 1) + return 0; + + data = post[pooh->counter]; + + if(data) { + size_t len = strlen(data); + memcpy(ptr, data, len); + pooh->counter++; /* advance pointer */ + return len; + } + return 0; /* no more data left to deliver */ +} + +int test(char *URL) +{ + CURL *curl; + CURLcode res=CURLE_OK; + struct curl_slist *slist = NULL; + struct WriteThis pooh; + pooh.counter = 0; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + slist = curl_slist_append(slist, "Transfer-Encoding: chunked"); + if (slist == NULL) { + fprintf(stderr, "curl_slist_append() failed\n"); + curl_easy_cleanup(curl); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + /* First set the URL that is about to receive our POST. */ + test_setopt(curl, CURLOPT_URL, URL); + + /* Now specify we want to POST data */ + test_setopt(curl, CURLOPT_POST, 1L); + +#ifdef CURL_DOES_CONVERSIONS + /* Convert the POST data to ASCII */ + test_setopt(curl, CURLOPT_TRANSFERTEXT, 1L); +#endif + + /* we want to use our own read function */ + test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + + /* pointer to pass to our read function */ + test_setopt(curl, CURLOPT_INFILE, &pooh); + + /* get verbose debug output please */ + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + /* include headers in the output */ + test_setopt(curl, CURLOPT_HEADER, 1L); + + /* enforce chunked transfer by setting the header */ + test_setopt(curl, CURLOPT_HTTPHEADER, slist); + + test_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_DIGEST); + test_setopt(curl, CURLOPT_USERPWD, "foo:bar"); + + /* we want to use our own progress function */ + test_setopt(curl, CURLOPT_NOPROGRESS, 0L); + test_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback); + + /* Perform the request, res will get the return code */ + res = curl_easy_perform(curl); + +test_cleanup: + + /* clean up the headers list */ + if(slist) + curl_slist_free_all(slist); + + /* always cleanup */ + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib582.c b/tests/libtest/lib582.c new file mode 100644 index 000000000..952efb4ed --- /dev/null +++ b/tests/libtest/lib582.c @@ -0,0 +1,366 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 60 * 1000 + +struct Sockets +{ + curl_socket_t *sockets; + int count; /* number of sockets actually stored in array */ + int max_count; /* max number of sockets that fit in allocated array */ +}; + +struct ReadWriteSockets +{ + struct Sockets read, write; +}; + +/** + * Remove a file descriptor from a sockets array. + */ +static void removeFd(struct Sockets* sockets, curl_socket_t fd, int mention) +{ + int i; + + if(mention) + fprintf(stderr, "Remove socket fd %d\n", (int) fd); + + for (i = 0; i < sockets->count; ++i) { + if (sockets->sockets[i] == fd) { + if (i < sockets->count - 1) + memmove(&sockets->sockets[i], &sockets->sockets[i + 1], + sizeof(curl_socket_t) * (sockets->count - (i + 1))); + --sockets->count; + } + } +} + +/** + * Add a file descriptor to a sockets array. + */ +static void addFd(struct Sockets* sockets, curl_socket_t fd, const char *what) +{ + /** + * To ensure we only have each file descriptor once, we remove it then add + * it again. + */ + fprintf(stderr, "Add socket fd %d for %s\n", (int) fd, what); + removeFd(sockets, fd, 0); + /* + * Allocate array storage when required. + */ + if(!sockets->sockets) { + sockets->sockets = malloc(sizeof(curl_socket_t) * 20U); + if(!sockets->sockets) + return; + sockets->max_count = 20; + } + else if(sockets->count + 1 > sockets->max_count) { + curl_socket_t *oldptr = sockets->sockets; + sockets->sockets = realloc(oldptr, sizeof(curl_socket_t) * + (sockets->max_count + 20)); + if(!sockets->sockets) { + /* cleanup in test_cleanup */ + sockets->sockets = oldptr; + return; + } + sockets->max_count += 20; + } + /* + * Add file descriptor to array. + */ + sockets->sockets[sockets->count] = fd; + ++sockets->count; +} + +/** + * Callback invoked by curl to poll reading / writing of a socket. + */ +static int curlSocketCallback(CURL *easy, curl_socket_t s, int action, + void *userp, void *socketp) +{ + struct ReadWriteSockets* sockets = userp; + + (void)easy; /* unused */ + (void)socketp; /* unused */ + + if (action == CURL_POLL_IN || action == CURL_POLL_INOUT) + addFd(&sockets->read, s, "read"); + + if (action == CURL_POLL_OUT || action == CURL_POLL_INOUT) + addFd(&sockets->write, s, "write"); + + if(action == CURL_POLL_REMOVE) { + removeFd(&sockets->read, s, 1); + removeFd(&sockets->write, s, 0); + } + + return 0; +} + +/** + * Callback invoked by curl to set a timeout. + */ +static int curlTimerCallback(CURLM *multi, long timeout_ms, void *userp) +{ + struct timeval* timeout = userp; + + (void)multi; /* unused */ + if (timeout_ms != -1) { + *timeout = tutil_tvnow(); + timeout->tv_usec += timeout_ms * 1000; + } + else { + timeout->tv_sec = -1; + } + return 0; +} + +/** + * Check for curl completion. + */ +static int checkForCompletion(CURLM* curl, int* success) +{ + int numMessages; + CURLMsg* message; + int result = 0; + *success = 0; + while ((message = curl_multi_info_read(curl, &numMessages)) != NULL) { + if (message->msg == CURLMSG_DONE) { + result = 1; + if (message->data.result == CURLE_OK) + *success = 1; + else + *success = 0; + } + else { + fprintf(stderr, "Got an unexpected message from curl: %i\n", + (int)message->msg); + result = 1; + *success = 0; + } + } + return result; +} + +static int getMicroSecondTimeout(struct timeval* timeout) +{ + struct timeval now; + ssize_t result; + now = tutil_tvnow(); + result = (timeout->tv_sec - now.tv_sec) * 1000000 + + timeout->tv_usec - now.tv_usec; + if (result < 0) + result = 0; + + return curlx_sztosi(result); +} + +/** + * Update a fd_set with all of the sockets in use. + */ +static void updateFdSet(struct Sockets* sockets, fd_set* fdset, + curl_socket_t *maxFd) +{ + int i; + for (i = 0; i < sockets->count; ++i) { + FD_SET(sockets->sockets[i], fdset); + if (*maxFd < sockets->sockets[i] + 1) { + *maxFd = sockets->sockets[i] + 1; + } + } +} + +static void notifyCurl(CURLM *curl, curl_socket_t s, int evBitmask, + const char *info) +{ + int numhandles = 0; + CURLMcode result = curl_multi_socket_action(curl, s, evBitmask, &numhandles); + if (result != CURLM_OK) { + fprintf(stderr, "Curl error on %s: %i (%s)\n", + info, result, curl_multi_strerror(result)); + } +} + +/** + * Invoke curl when a file descriptor is set. + */ +static void checkFdSet(CURLM *curl, struct Sockets *sockets, fd_set *fdset, + int evBitmask, const char *name) +{ + int i; + for (i = 0; i < sockets->count; ++i) { + if (FD_ISSET(sockets->sockets[i], fdset)) { + notifyCurl(curl, sockets->sockets[i], evBitmask, name); + } + } +} + +int test(char *URL) +{ + int res = 0; + CURL *curl = NULL; + FILE *hd_src = NULL; + int hd ; + int error; + struct_stat file_info; + CURLM *m = NULL; + struct ReadWriteSockets sockets = {{NULL, 0, 0}, {NULL, 0, 0}}; + struct timeval timeout = {-1, 0}; + int success = 0; + + start_test_timing(); + + if (!libtest_arg3) { + fprintf(stderr, "Usage: lib582 [url] [filename] [username]\n"); + return TEST_ERR_USAGE; + } + + hd_src = fopen(libtest_arg2, "rb"); + if(NULL == hd_src) { + error = ERRNO; + fprintf(stderr, "fopen() failed with error: %d (%s)\n", + error, strerror(error)); + fprintf(stderr, "Error opening file: (%s)\n", libtest_arg2); + return TEST_ERR_FOPEN; + } + + /* get the file size of the local file */ + hd = fstat(fileno(hd_src), &file_info); + if(hd == -1) { + /* can't open file, bail out */ + error = ERRNO; + fprintf(stderr, "fstat() failed with error: %d (%s)\n", + error, strerror(error)); + fprintf(stderr, "ERROR: cannot open file (%s)\n", libtest_arg2); + fclose(hd_src); + return TEST_ERR_FSTAT; + } + fprintf(stderr, "Set to upload %d bytes\n", (int)file_info.st_size); + + res_global_init(CURL_GLOBAL_ALL); + if(res) { + fclose(hd_src); + return res; + } + + easy_init(curl); + + /* enable uploading */ + easy_setopt(curl, CURLOPT_UPLOAD, 1L); + + /* specify target */ + easy_setopt(curl,CURLOPT_URL, URL); + + /* go verbose */ + easy_setopt(curl, CURLOPT_VERBOSE, 1L); + + /* now specify which file to upload */ + easy_setopt(curl, CURLOPT_READDATA, hd_src); + + easy_setopt(curl, CURLOPT_USERPWD, libtest_arg3); + easy_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, "curl_client_key.pub"); + easy_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, "curl_client_key"); + + easy_setopt(curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)file_info.st_size); + + multi_init(m); + + multi_setopt(m, CURLMOPT_SOCKETFUNCTION, curlSocketCallback); + multi_setopt(m, CURLMOPT_SOCKETDATA, &sockets); + + multi_setopt(m, CURLMOPT_TIMERFUNCTION, curlTimerCallback); + multi_setopt(m, CURLMOPT_TIMERDATA, &timeout); + + multi_add_handle(m, curl); + + while (!checkForCompletion(m, &success)) + { + fd_set readSet, writeSet; + curl_socket_t maxFd = 0; + struct timeval tv = {10, 0}; + + FD_ZERO(&readSet); + FD_ZERO(&writeSet); + updateFdSet(&sockets.read, &readSet, &maxFd); + updateFdSet(&sockets.write, &writeSet, &maxFd); + + if (timeout.tv_sec != -1) + { + int usTimeout = getMicroSecondTimeout(&timeout); + tv.tv_sec = usTimeout / 1000000; + tv.tv_usec = usTimeout % 1000000; + } + else if (maxFd <= 0) + { + tv.tv_sec = 0; + tv.tv_usec = 100000; + } + + select_test(maxFd, &readSet, &writeSet, NULL, &tv); + + /* Check the sockets for reading / writing */ + checkFdSet(m, &sockets.read, &readSet, CURL_CSELECT_IN, "read"); + checkFdSet(m, &sockets.write, &writeSet, CURL_CSELECT_OUT, "write"); + + if (timeout.tv_sec != -1 && getMicroSecondTimeout(&timeout) == 0) + { + /* Curl's timer has elapsed. */ + notifyCurl(m, CURL_SOCKET_TIMEOUT, 0, "timeout"); + } + + abort_on_test_timeout(); + } + + if (!success) + { + fprintf(stderr, "Error uploading file.\n"); + res = TEST_ERR_MAJOR_BAD; + } + +test_cleanup: + + /* proper cleanup sequence - type PB */ + + curl_multi_remove_handle(m, curl); + curl_easy_cleanup(curl); + curl_multi_cleanup(m); + curl_global_cleanup(); + + /* close the local file */ + fclose(hd_src); + + /* free local memory */ + if(sockets.read.sockets) + free(sockets.read.sockets); + if(sockets.write.sockets) + free(sockets.write.sockets); + + return res; +} diff --git a/tests/libtest/lib583.c b/tests/libtest/lib583.c new file mode 100644 index 000000000..ad5a5cea7 --- /dev/null +++ b/tests/libtest/lib583.c @@ -0,0 +1,84 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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. + * + ***************************************************************************/ +/* + * This test case is based on the sample code provided by Saqib Ali + * http://curl.haxx.se/mail/lib-2011-03/0066.html + */ + +#include "test.h" + +#include <sys/stat.h> + +#include "memdebug.h" + +int test(char *URL) +{ + int stillRunning; + CURLM* multiHandle = NULL; + CURL* curl = NULL; + int res = 0; + + global_init(CURL_GLOBAL_ALL); + + multi_init(multiHandle); + + easy_init(curl); + + easy_setopt(curl, CURLOPT_USERPWD, libtest_arg2); + easy_setopt(curl, CURLOPT_SSH_PUBLIC_KEYFILE, "curl_client_key.pub"); + easy_setopt(curl, CURLOPT_SSH_PRIVATE_KEYFILE, "curl_client_key"); + + easy_setopt(curl, CURLOPT_UPLOAD, 1L); + easy_setopt(curl, CURLOPT_VERBOSE, 1L); + + easy_setopt(curl, CURLOPT_URL, URL); + easy_setopt(curl, CURLOPT_INFILESIZE, (long)5); + + multi_add_handle(multiHandle, curl); + + /* this tests if removing an easy handle immediately after multi + perform has been called succeeds or not. */ + + fprintf(stderr, "curl_multi_perform()...\n"); + + multi_perform(multiHandle, &stillRunning); + + fprintf(stderr, "curl_multi_perform() succeeded\n"); + + fprintf(stderr, "curl_multi_remove_handle()...\n"); + res = (int) curl_multi_remove_handle(multiHandle, curl); + if(res) + fprintf(stderr, "curl_multi_remove_handle() failed, " + "with code %d\n", res); + else + fprintf(stderr, "curl_multi_remove_handle() succeeded\n"); + +test_cleanup: + + /* undocumented cleanup sequence - type UB */ + + curl_easy_cleanup(curl); + curl_multi_cleanup(multiHandle); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib586.c b/tests/libtest/lib586.c new file mode 100644 index 000000000..2cf04fe85 --- /dev/null +++ b/tests/libtest/lib586.c @@ -0,0 +1,246 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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 <curl/mprintf.h> + +#include "memdebug.h" + +#define THREADS 2 + +/* struct containing data of a thread */ +struct Tdata { + CURLSH *share; + char *url; +}; + +struct userdata { + char *text; + int counter; +}; + +/* lock callback */ +static void my_lock(CURL *handle, curl_lock_data data, curl_lock_access laccess, + void *useptr ) +{ + const char *what; + struct userdata *user = (struct userdata *)useptr; + + (void)handle; + (void)laccess; + + switch ( data ) { + case CURL_LOCK_DATA_SHARE: + what = "share"; + break; + case CURL_LOCK_DATA_DNS: + what = "dns"; + break; + case CURL_LOCK_DATA_COOKIE: + what = "cookie"; + break; + case CURL_LOCK_DATA_SSL_SESSION: + what = "ssl_session"; + break; + default: + fprintf(stderr, "lock: no such data: %d\n", (int)data); + return; + } + printf("lock: %-6s [%s]: %d\n", what, user->text, user->counter); + user->counter++; +} + +/* unlock callback */ +static void my_unlock(CURL *handle, curl_lock_data data, void *useptr ) +{ + const char *what; + struct userdata *user = (struct userdata *)useptr; + (void)handle; + switch ( data ) { + case CURL_LOCK_DATA_SHARE: + what = "share"; + break; + case CURL_LOCK_DATA_DNS: + what = "dns"; + break; + case CURL_LOCK_DATA_COOKIE: + what = "cookie"; + break; + case CURL_LOCK_DATA_SSL_SESSION: + what = "ssl_session"; + break; + default: + fprintf(stderr, "unlock: no such data: %d\n", (int)data); + return; + } + printf("unlock: %-6s [%s]: %d\n", what, user->text, user->counter); + user->counter++; +} + +/* the dummy thread function */ +static void *fire(void *ptr) +{ + CURLcode code; + struct Tdata *tdata = (struct Tdata*)ptr; + CURL *curl; + int i=0; + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + return NULL; + } + + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); + curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); + curl_easy_setopt(curl, CURLOPT_URL, tdata->url); + printf( "CURLOPT_SHARE\n" ); + curl_easy_setopt(curl, CURLOPT_SHARE, tdata->share); + + printf( "PERFORM\n" ); + code = curl_easy_perform(curl); + if( code != CURLE_OK ) { + fprintf(stderr, "perform url '%s' repeat %d failed, curlcode %d\n", + tdata->url, i, (int)code); + } + + printf( "CLEANUP\n" ); + curl_easy_cleanup(curl); + + return NULL; +} + +/* test function */ +int test(char *URL) +{ + int res; + CURLSHcode scode = CURLSHE_OK; + char *url; + struct Tdata tdata; + CURL *curl; + CURLSH *share; + int i; + struct userdata user; + + user.text = (char *)"Pigs in space"; + user.counter = 0; + + printf( "GLOBAL_INIT\n" ); + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + /* prepare share */ + printf( "SHARE_INIT\n" ); + if ((share = curl_share_init()) == NULL) { + fprintf(stderr, "curl_share_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + if ( CURLSHE_OK == scode ) { + printf( "CURLSHOPT_LOCKFUNC\n" ); + scode = curl_share_setopt( share, CURLSHOPT_LOCKFUNC, my_lock); + } + if ( CURLSHE_OK == scode ) { + printf( "CURLSHOPT_UNLOCKFUNC\n" ); + scode = curl_share_setopt( share, CURLSHOPT_UNLOCKFUNC, my_unlock); + } + if ( CURLSHE_OK == scode ) { + printf( "CURLSHOPT_USERDATA\n" ); + scode = curl_share_setopt( share, CURLSHOPT_USERDATA, &user); + } + if ( CURLSHE_OK == scode ) { + printf( "CURL_LOCK_DATA_SSL_SESSION\n" ); + scode = curl_share_setopt( share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION); + } + + if ( CURLSHE_OK != scode ) { + fprintf(stderr, "curl_share_setopt() failed\n"); + curl_share_cleanup(share); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + + res = 0; + + /* start treads */ + for (i=1; i<=THREADS; i++ ) { + + /* set thread data */ + tdata.url = URL; + tdata.share = share; + + /* simulate thread, direct call of "thread" function */ + printf( "*** run %d\n",i ); + fire( &tdata ); + } + + + /* fetch a another one */ + printf( "*** run %d\n", i ); + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_share_cleanup(share); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + url = URL; + test_setopt( curl, CURLOPT_URL, url ); + printf( "CURLOPT_SHARE\n" ); + test_setopt( curl, CURLOPT_SHARE, share ); + + printf( "PERFORM\n" ); + curl_easy_perform( curl ); + + /* try to free share, expect to fail because share is in use*/ + printf( "try SHARE_CLEANUP...\n" ); + scode = curl_share_cleanup( share ); + if ( scode==CURLSHE_OK ) + { + fprintf(stderr, "curl_share_cleanup succeed but error expected\n"); + share = NULL; + } else { + printf( "SHARE_CLEANUP failed, correct\n" ); + } + +test_cleanup: + + /* clean up last handle */ + printf( "CLEANUP\n" ); + curl_easy_cleanup( curl ); + + /* free share */ + printf( "SHARE_CLEANUP\n" ); + scode = curl_share_cleanup( share ); + if ( scode!=CURLSHE_OK ) + fprintf(stderr, "curl_share_cleanup failed, code errno %d\n", + (int)scode); + + printf( "GLOBAL_CLEANUP\n" ); + curl_global_cleanup(); + + return res; +} + diff --git a/tests/libtest/lib590.c b/tests/libtest/lib590.c new file mode 100644 index 000000000..68603c65e --- /dev/null +++ b/tests/libtest/lib590.c @@ -0,0 +1,71 @@ +/*************************************************************************** + * _ _ ____ _ + * 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" + +/* + Based on a bug report recipe by Rene Bernhardt in + http://curl.haxx.se/mail/lib-2011-10/0323.html + + It is reproducible by the following steps: + + - Use a proxy that offers NTLM and Negotiate ( CURLOPT_PROXY and + CURLOPT_PROXYPORT ) + - Tell libcurl NOT to use Negotiate CURL_EASY_SETOPT(CURLOPT_PROXYAUTH, + CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_NTLM ) + - Start the request +*/ + +#include "memdebug.h" + +int test(char *URL) +{ + CURLcode res; + CURL *curl; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_HEADER, 1L); + test_setopt(curl, CURLOPT_PROXYAUTH, + (long) (CURLAUTH_BASIC | CURLAUTH_DIGEST | CURLAUTH_NTLM)); + test_setopt(curl, CURLOPT_PROXY, libtest_arg2); /* set in first.c */ + test_setopt(curl, CURLOPT_PROXYUSERPWD, "me:password"); + + res = curl_easy_perform(curl); + + test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} + diff --git a/tests/libtest/lib591.c b/tests/libtest/lib591.c new file mode 100644 index 000000000..5cd4644e3 --- /dev/null +++ b/tests/libtest/lib591.c @@ -0,0 +1,149 @@ +/*************************************************************************** + * _ _ ____ _ + * 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" + +/* lib591 is used for test cases 591, 592, 593 and 594 */ + +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif + +#include <fcntl.h> + +#include "testutil.h" +#include "warnless.h" +#include "memdebug.h" + +#define TEST_HANG_TIMEOUT 60 * 1000 + +int test(char *URL) +{ + CURL *easy = NULL; + CURLM *multi = NULL; + int res = 0; + int running; + int msgs_left; + CURLMsg *msg; + FILE *upload = NULL; + int error; + + start_test_timing(); + + upload = fopen(libtest_arg3, "rb"); + if(!upload) { + error = ERRNO; + fprintf(stderr, "fopen() failed with error: %d (%s)\n", + error, strerror(error)); + fprintf(stderr, "Error opening file: (%s)\n", libtest_arg3); + return TEST_ERR_FOPEN; + } + + res_global_init(CURL_GLOBAL_ALL); + if(res) { + fclose(upload); + return res; + } + + easy_init(easy); + + /* go verbose */ + easy_setopt(easy, CURLOPT_VERBOSE, 1L); + + /* specify target */ + easy_setopt(easy, CURLOPT_URL, URL); + + /* enable uploading */ + easy_setopt(easy, CURLOPT_UPLOAD, 1L); + + /* data pointer for the file read function */ + easy_setopt(easy, CURLOPT_READDATA, upload); + + /* use active mode FTP */ + easy_setopt(easy, CURLOPT_FTPPORT, "-"); + + /* server connection timeout */ + easy_setopt(easy, CURLOPT_ACCEPTTIMEOUT_MS, + strtol(libtest_arg2, NULL, 10)*1000); + + multi_init(multi); + + multi_add_handle(multi, easy); + + for(;;) { + struct timeval interval; + fd_set fdread; + fd_set fdwrite; + fd_set fdexcep; + long timeout = -99; + int maxfd = -99; + + multi_perform(multi, &running); + + abort_on_test_timeout(); + + if(!running) + break; /* done */ + + FD_ZERO(&fdread); + FD_ZERO(&fdwrite); + FD_ZERO(&fdexcep); + + multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd); + + /* At this point, maxfd is guaranteed to be greater or equal than -1. */ + + multi_timeout(multi, &timeout); + + /* At this point, timeout is guaranteed to be greater or equal than -1. */ + + if(timeout != -1L) { + int itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout; + interval.tv_sec = itimeout/1000; + interval.tv_usec = (itimeout%1000)*1000; + } + else { + interval.tv_sec = 0; + interval.tv_usec = 100000L; /* 100 ms */ + } + + select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &interval); + + abort_on_test_timeout(); + } + + msg = curl_multi_info_read(multi, &msgs_left); + if(msg) + res = msg->data.result; + +test_cleanup: + + /* undocumented cleanup sequence - type UA */ + + curl_multi_cleanup(multi); + curl_easy_cleanup(easy); + curl_global_cleanup(); + + /* close the local file */ + fclose(upload); + + return res; +} diff --git a/tests/libtest/lib597.c b/tests/libtest/lib597.c new file mode 100644 index 000000000..a27cefd5b --- /dev/null +++ b/tests/libtest/lib597.c @@ -0,0 +1,150 @@ +/*************************************************************************** + * _ _ ____ _ + * 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" + +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif + +#include "testutil.h" +#include "warnless.h" +#include "memdebug.h" + +#define TEST_HANG_TIMEOUT 5 * 1000 + +/* + * Test case for below scenario: + * - Connect to an FTP server using CONNECT_ONLY option + * - transfer some files with re-using the connection (omitted in test case) + * - Disconnect from FTP server with sending QUIT command + * + * The test case originated for verifying CONNECT_ONLY option shall not + * block after protocol connect is done, but it returns the message + * with function curl_multi_info_read(). + */ + +enum { + CONNECT_ONLY_PHASE = 0, + QUIT_PHASE, + LAST_PHASE +}; + +int test(char *URL) +{ + CURL *easy = NULL; + CURLM *multi = NULL; + int res = 0; + int running; + int msgs_left; + int phase; + CURLMsg *msg; + + start_test_timing(); + + res_global_init(CURL_GLOBAL_ALL); + if(res) { + return res; + } + + easy_init(easy); + + multi_init(multi); + + for (phase = CONNECT_ONLY_PHASE; phase < LAST_PHASE; ++phase) { + /* go verbose */ + easy_setopt(easy, CURLOPT_VERBOSE, 1L); + + /* specify target */ + easy_setopt(easy, CURLOPT_URL, URL); + + /* enable 'CONNECT_ONLY' option when in connect phase */ + if (phase == CONNECT_ONLY_PHASE) + easy_setopt(easy, CURLOPT_CONNECT_ONLY, 1L); + + /* enable 'NOBODY' option to send 'QUIT' command in quit phase */ + if (phase == QUIT_PHASE) { + easy_setopt(easy, CURLOPT_CONNECT_ONLY, 0L); + easy_setopt(easy, CURLOPT_NOBODY, 1L); + easy_setopt(easy, CURLOPT_FORBID_REUSE, 1L); + } + + multi_add_handle(multi, easy); + + for(;;) { + struct timeval interval; + fd_set fdread; + fd_set fdwrite; + fd_set fdexcep; + long timeout = -99; + int maxfd = -99; + + multi_perform(multi, &running); + + abort_on_test_timeout(); + + if(!running) + break; /* done */ + + FD_ZERO(&fdread); + FD_ZERO(&fdwrite); + FD_ZERO(&fdexcep); + + multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd); + + /* At this point, maxfd is guaranteed to be greater or equal than -1. */ + + multi_timeout(multi, &timeout); + + /* At this point, timeout is guaranteed to be greater or equal than -1. */ + + if(timeout != -1L) { + int itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout; + interval.tv_sec = itimeout/1000; + interval.tv_usec = (itimeout%1000)*1000; + } + else { + interval.tv_sec = TEST_HANG_TIMEOUT/1000+1; + interval.tv_usec = 0; + } + + select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &interval); + + abort_on_test_timeout(); + } + + msg = curl_multi_info_read(multi, &msgs_left); + if(msg) + res = msg->data.result; + + multi_remove_handle(multi, easy); + } + +test_cleanup: + + /* undocumented cleanup sequence - type UA */ + + curl_multi_cleanup(multi); + curl_easy_cleanup(easy); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib598.c b/tests/libtest/lib598.c new file mode 100644 index 000000000..e9c1ad776 --- /dev/null +++ b/tests/libtest/lib598.c @@ -0,0 +1,72 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "memdebug.h" + +int test(char *URL) +{ + CURLcode res; + CURL *curl; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_HEADER, 1L); + test_setopt(curl, CURLOPT_REFERER, "http://example.com/the-moo"); + test_setopt(curl, CURLOPT_USERAGENT, "the-moo agent next generation"); + test_setopt(curl, CURLOPT_COOKIE, "name=moo"); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + res = curl_easy_perform(curl); + if(res) { + fprintf(stderr, "retrieve 1 failed\n"); + goto test_cleanup; + } + + curl_easy_reset(curl); + + test_setopt(curl, CURLOPT_URL, URL); + test_setopt(curl, CURLOPT_HEADER, 1L); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + res = curl_easy_perform(curl); + if(res) + fprintf(stderr, "retrieve 2 failed\n"); + +test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} + diff --git a/tests/libtest/lib599.c b/tests/libtest/lib599.c new file mode 100644 index 000000000..6b092677a --- /dev/null +++ b/tests/libtest/lib599.c @@ -0,0 +1,84 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "memdebug.h" + +static int progress_callback(void *clientp, double dltotal, + double dlnow, double ultotal, double ulnow) +{ + (void)clientp; + (void)ulnow; + (void)ultotal; + + if((dltotal > 0.0) && (dlnow > dltotal)) { + /* this should not happen with test case 599 */ + printf("%.0f > %.0f !!\n", dltotal, dlnow); + return -1; + } + + return 0; +} + +int test(char *URL) +{ + CURL *curl; + CURLcode res=CURLE_OK; + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + /* First set the URL that is about to receive our POST. */ + test_setopt(curl, CURLOPT_URL, URL); + + /* we want to use our own progress function */ + test_setopt(curl, CURLOPT_NOPROGRESS, 0L); + test_setopt(curl, CURLOPT_PROGRESSFUNCTION, progress_callback); + + /* get verbose debug output please */ + test_setopt(curl, CURLOPT_VERBOSE, 1L); + + /* follow redirects */ + test_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + + /* include headers in the output */ + test_setopt(curl, CURLOPT_HEADER, 1L); + + /* Perform the request, res will get the return code */ + res = curl_easy_perform(curl); + +test_cleanup: + + /* always cleanup */ + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/libauthretry.c b/tests/libtest/libauthretry.c new file mode 100644 index 000000000..95761325a --- /dev/null +++ b/tests/libtest/libauthretry.c @@ -0,0 +1,153 @@ +/*************************************************************************** + * _ _ ____ _ + * 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. + * + ***************************************************************************/ +/* argv1 = URL + * argv2 = main auth type + * argv3 = second auth type + */ + +#include "test.h" +#include "strequal.h" +#include "memdebug.h" + +static CURLcode send_request(CURL *curl, const char *url, int seq, + long auth_scheme, const char *userpwd) +{ + CURLcode res; + char* full_url = malloc(strlen(url) + 4 + 1); + if (!full_url) { + fprintf(stderr, "Not enough memory for full url\n"); + res = CURLE_OUT_OF_MEMORY; + goto test_cleanup; + } + + sprintf(full_url, "%s%04d", url, seq); + fprintf(stderr, "Sending new request %d to %s with credential %s " + "(auth %ld)\n", seq, full_url, userpwd, auth_scheme); + test_setopt(curl, CURLOPT_URL, full_url); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_HEADER, 1L); + test_setopt(curl, CURLOPT_HTTPGET, 1L); + test_setopt(curl, CURLOPT_USERPWD, userpwd); + test_setopt(curl, CURLOPT_HTTPAUTH, auth_scheme); + + res = curl_easy_perform(curl); + +test_cleanup: + free(full_url); + return res; +} + +static CURLcode send_wrong_password(CURL *curl, const char *url, int seq, + long auth_scheme) +{ + return send_request(curl, url, seq, auth_scheme, "testuser:wrongpass"); +} + +static CURLcode send_right_password(CURL *curl, const char *url, int seq, + long auth_scheme) +{ + return send_request(curl, url, seq, auth_scheme, "testuser:testpass"); +} + +static long parse_auth_name(const char *arg) +{ + if (!arg) + return CURLAUTH_NONE; + if (strequal(arg, "basic")) + return CURLAUTH_BASIC; + if (strequal(arg, "digest")) + return CURLAUTH_DIGEST; + if (strequal(arg, "ntlm")) + return CURLAUTH_NTLM; + return CURLAUTH_NONE; +} + +int test(char *url) +{ + CURLcode res; + CURL *curl = NULL; + + long main_auth_scheme = parse_auth_name(libtest_arg2); + long fallback_auth_scheme = parse_auth_name(libtest_arg3); + + if (main_auth_scheme == CURLAUTH_NONE || + fallback_auth_scheme == CURLAUTH_NONE) { + fprintf(stderr, "auth schemes not found on commandline\n"); + return TEST_ERR_MAJOR_BAD; + } + + if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + /* Send wrong password, then right password */ + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + res = send_wrong_password(curl, url, 100, main_auth_scheme); + if (res != CURLE_OK) + goto test_cleanup; + curl_easy_reset(curl); + + res = send_right_password(curl, url, 200, fallback_auth_scheme); + if (res != CURLE_OK) + goto test_cleanup; + curl_easy_reset(curl); + + curl_easy_cleanup(curl); + + /* Send wrong password twice, then right password */ + + if ((curl = curl_easy_init()) == NULL) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + res = send_wrong_password(curl, url, 300, main_auth_scheme); + if (res != CURLE_OK) + goto test_cleanup; + curl_easy_reset(curl); + + res = send_wrong_password(curl, url, 400, fallback_auth_scheme); + if (res != CURLE_OK) + goto test_cleanup; + curl_easy_reset(curl); + + res = send_right_password(curl, url, 500, fallback_auth_scheme); + if (res != CURLE_OK) + goto test_cleanup; + curl_easy_reset(curl); + +test_cleanup: + + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return (int)res; +} + diff --git a/tests/libtest/libntlmconnect.c b/tests/libtest/libntlmconnect.c new file mode 100644 index 000000000..66d09e936 --- /dev/null +++ b/tests/libtest/libntlmconnect.c @@ -0,0 +1,275 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 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" + +#ifdef HAVE_LIMITS_H +#include <limits.h> +#endif +#include <assert.h> + +#include "testutil.h" +#include "warnless.h" +#include "memdebug.h" + +#define TEST_HANG_TIMEOUT 5 * 1000 +#define MAX_EASY_HANDLES 3 + +/* On Windows INVALID_SOCKET represents an invalid socket, not -1: + http://msdn.microsoft.com/en-us/library/windows/desktop/ms740516.aspx */ +#ifndef INVALID_SOCKET +#define INVALID_SOCKET -1 +#endif + +CURL *easy[MAX_EASY_HANDLES]; +curl_socket_t sockets[MAX_EASY_HANDLES]; +int res = 0; + +static size_t callback(char* ptr, size_t size, size_t nmemb, void* data) +{ + ssize_t idx = ((CURL **) data) - easy; + curl_socket_t sock; + long lastsock; + + char *output = malloc(size * nmemb + 1); + memcpy(output, ptr, size * nmemb); + output[size * nmemb] = '\0'; + fprintf(stdout, "%s", output); + free(output); + + res = curl_easy_getinfo(easy[idx], CURLINFO_LASTSOCKET, &lastsock); + if (CURLE_OK != res) { + fprintf(stderr, "Error reading CURLINFO_LASTSOCKET\n"); + return 0; + } + if (lastsock == -1) { + sock = INVALID_SOCKET; + } + else { + sock = (curl_socket_t)lastsock; + } + /* sock will only be set for NTLM requests; for others it is -1 */ + if (sock != INVALID_SOCKET) { + if (sockets[idx] == INVALID_SOCKET) { + /* Data was written for this request before the socket was detected by + multi_fdset. Record the socket now. */ + sockets[idx] = sock; + } + else if (sock != sockets[idx]) { + fprintf(stderr, "Handle %d started on socket %d and moved to %d\n", + curlx_sztosi(idx), (int)sockets[idx], (int)sock); + res = TEST_ERR_MAJOR_BAD; + return 0; + } + } + return size * nmemb; +} + +enum HandleState { + ReadyForNewHandle, + NeedSocketForNewHandle, + NoMoreHandles +}; + +int test(char *url) +{ + CURLM *multi = NULL; + int running; + int i, j; + int num_handles = 0; + enum HandleState state = ReadyForNewHandle; + char* full_url = malloc(strlen(url) + 4 + 1); + + start_test_timing(); + + if (!full_url) { + fprintf(stderr, "Not enough memory for full url\n"); + return CURLE_OUT_OF_MEMORY; + } + + for (i = 0; i < MAX_EASY_HANDLES; ++i) { + easy[i] = NULL; + sockets[i] = -1; + } + + res = 0; + res_global_init(CURL_GLOBAL_ALL); + if(res) { + return res; + } + + multi_init(multi); + + for(;;) { + struct timeval interval; + fd_set fdread; + fd_set fdwrite; + fd_set fdexcep; + long timeout = -99; + curl_socket_t curfd, maxfd = INVALID_SOCKET; + bool found_new_socket = FALSE; + + /* Start a new handle if we aren't at the max */ + if (state == ReadyForNewHandle) { + easy_init(easy[num_handles]); + + if (num_handles % 3 == 2) { + sprintf(full_url, "%s0200", url); + easy_setopt(easy[num_handles], CURLOPT_HTTPAUTH, CURLAUTH_NTLM); + } else { + sprintf(full_url, "%s0100", url); + easy_setopt(easy[num_handles], CURLOPT_HTTPAUTH, CURLAUTH_BASIC); + } + easy_setopt(easy[num_handles], CURLOPT_FRESH_CONNECT, 1L); + easy_setopt(easy[num_handles], CURLOPT_URL, full_url); + easy_setopt(easy[num_handles], CURLOPT_VERBOSE, 1L); + easy_setopt(easy[num_handles], CURLOPT_HTTPGET, 1L); + easy_setopt(easy[num_handles], CURLOPT_USERPWD, "testuser:testpass"); + easy_setopt(easy[num_handles], CURLOPT_WRITEFUNCTION, callback); + easy_setopt(easy[num_handles], CURLOPT_WRITEDATA, easy + num_handles); + easy_setopt(easy[num_handles], CURLOPT_HEADER, 1L); + + multi_add_handle(multi, easy[num_handles]); + num_handles += 1; + state = NeedSocketForNewHandle; + } + + multi_perform(multi, &running); + if (0 != res) + break; + + abort_on_test_timeout(); + + if(!running && state == NoMoreHandles) + break; /* done */ + + FD_ZERO(&fdread); + FD_ZERO(&fdwrite); + FD_ZERO(&fdexcep); + + multi_fdset(multi, &fdread, &fdwrite, &fdexcep, (int *)&maxfd); + + /* At this point, maxfd is guaranteed to be greater or equal than -1. */ + + /* Any socket which is new in fdread is associated with the new handle */ + for (curfd = 0; curfd <= maxfd; ++curfd) { + bool socket_exists = FALSE; + if (!FD_ISSET(curfd, &fdread)) { + continue; + } + + /* Check if this socket was already detected for an earlier handle (or + for this handle, num_handles-1, in the callback */ + for (j = 0; j < num_handles; ++j) { + if (sockets[j] == curfd) { + socket_exists = TRUE; + break; + } + } + if (socket_exists) { + continue; + } + + if (found_new_socket || state != NeedSocketForNewHandle) { + fprintf(stderr, "Unexpected new socket\n"); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + + /* Now we know the socket is for the most recent handle, num_handles-1 */ + if (sockets[num_handles-1] != INVALID_SOCKET) { + /* A socket for this handle was already detected in the callback; if it + matched socket_exists should be true and we would never get here */ + assert(curfd != sockets[num_handles-1]); + fprintf(stderr, "Handle %d wrote to socket %d then detected on %d\n", + num_handles-1, (int)sockets[num_handles-1], (int)curfd); + res = TEST_ERR_MAJOR_BAD; + goto test_cleanup; + } + else { + sockets[num_handles-1] = curfd; + found_new_socket = TRUE; + /* continue to make sure there's only one new handle */ + } + } + + if (state == NeedSocketForNewHandle) { + if(maxfd != -1 && !found_new_socket) { + fprintf(stderr, "Warning: socket did not open immediately for new " + "handle (trying again)\n"); + continue; + } + state = num_handles < MAX_EASY_HANDLES ? ReadyForNewHandle + : NoMoreHandles; + } + + multi_timeout(multi, &timeout); + + /* At this point, timeout is guaranteed to be greater or equal than -1. */ + + fprintf(stderr, "%s:%d num_handles %d timeout %ld\n", + __FILE__, __LINE__, num_handles, timeout); + + if(timeout != -1L) { + int itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout; + interval.tv_sec = itimeout/1000; + interval.tv_usec = (itimeout%1000)*1000; + } + else { + interval.tv_sec = TEST_HANG_TIMEOUT/1000+1; + interval.tv_usec = 0; + + /* if there's no timeout and we get here on the last handle, we may + already have read the last part of the stream so waiting makes no + sense */ + if(!running && num_handles == MAX_EASY_HANDLES) { + break; + } + } + + select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &interval); + + abort_on_test_timeout(); + } + +test_cleanup: + + for (i = 0; i < MAX_EASY_HANDLES; ++i) { + if (easy[i]) { + if (multi) { + curl_multi_remove_handle(multi, easy[i]); + } + curl_easy_cleanup(easy[i]); + } + } + + if (multi) { + curl_multi_cleanup(multi); + } + + curl_global_cleanup(); + + if (full_url) { + free(full_url); + } + + return res; +} diff --git a/tests/libtest/notexists.pl b/tests/libtest/notexists.pl new file mode 100755 index 000000000..31b9851ec --- /dev/null +++ b/tests/libtest/notexists.pl @@ -0,0 +1,15 @@ +#!/usr/bin/env perl +# Check that given arguments do not exist on filesystem. +my $code = 0; +if ($#ARGV < 0) { + print "Usage: $0 file1 [fileN]\n"; + exit 2; +} +while (@ARGV) { + my $fname = shift @ARGV; + if (-e $fname) { + print "Found '$fname' when not supposed to exist.\n"; + $code = 1; + } +} +exit $code; diff --git a/tests/libtest/sethostname.c b/tests/libtest/sethostname.c new file mode 100644 index 000000000..f131fe9fb --- /dev/null +++ b/tests/libtest/sethostname.c @@ -0,0 +1,41 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "setup.h" + +#include "sethostname.h" + +/* + * we force our own host name, in order to make some tests machine independent + */ + +int gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen) +{ + const char *force_hostname = getenv("CURL_GETHOSTNAME"); + if(force_hostname) { + strncpy(name, force_hostname, namelen); + name[namelen-1] = '\0'; + return 0; + } + + /* LD_PRELOAD used, but no hostname set, we'll just return a failure */ + return -1; +} diff --git a/tests/libtest/sethostname.h b/tests/libtest/sethostname.h new file mode 100644 index 000000000..e2633dd7f --- /dev/null +++ b/tests/libtest/sethostname.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, 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. + * + ***************************************************************************/ + +#if (defined(WIN32) || defined(__SYMBIAN32__)) && !defined(CURL_STATICLIB) +# if defined(BUILDING_LIBCURL) +# define LIBHOSTNAME_EXTERN __declspec(dllexport) +# else +# define LIBHOSTNAME_EXTERN __declspec(dllimport) +# endif +#else +# ifdef CURL_HIDDEN_SYMBOLS +# define LIBHOSTNAME_EXTERN CURL_EXTERN_SYMBOL +# else +# define LIBHOSTNAME_EXTERN +# endif +#endif + +#ifdef USE_WINSOCK +# define FUNCALLCONV __stdcall +#else +# define FUNCALLCONV +#endif + +LIBHOSTNAME_EXTERN int FUNCALLCONV + gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen); + diff --git a/tests/libtest/test.h b/tests/libtest/test.h new file mode 100644 index 000000000..ffa4be166 --- /dev/null +++ b/tests/libtest/test.h @@ -0,0 +1,436 @@ +/*************************************************************************** + * _ _ ____ _ + * 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. + * + ***************************************************************************/ + +/* Now include the setup.h file from libcurl's private libdir (the source + version, but that might include "curl_config.h" from the build dir so we + need both of them in the include path), so that we get good in-depth + knowledge about the system we're building this on */ + +#define CURL_NO_OLDIES + +#include "setup.h" + +#include <curl/curl.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif +#ifdef HAVE_SYS_SELECT_H +/* since so many tests use select(), we can just as well include it here */ +#include <sys/select.h> +#endif +#ifdef HAVE_UNISTD_H +/* at least somewhat oldish FreeBSD systems need this for select() */ +#include <unistd.h> +#endif + +#ifdef TPF +# include "select.h" +#endif + +#define test_setopt(A,B,C) \ + if((res = curl_easy_setopt((A),(B),(C))) != CURLE_OK) goto test_cleanup + +#define test_multi_setopt(A,B,C) \ + if((res = curl_multi_setopt((A),(B),(C))) != CURLE_OK) goto test_cleanup + +extern char *libtest_arg2; /* set by first.c to the argv[2] or NULL */ +extern char *libtest_arg3; /* set by first.c to the argv[3] or NULL */ + +/* argc and argv as passed in to the main() function */ +extern int test_argc; +extern char **test_argv; + +extern struct timeval tv_test_start; /* for test timing */ + +extern int select_wrapper(int nfds, fd_set *rd, fd_set *wr, fd_set *exc, + struct timeval *tv); + +extern int test(char *URL); /* the actual test function provided by each + individual libXXX.c file */ + +#ifdef UNITTESTS +extern int unitfail; +#endif + +/* +** TEST_ERR_* values must be greater than CURL_LAST CURLcode in order +** to avoid confusion with any CURLcode or CURLMcode. These TEST_ERR_* +** codes are returned to signal test specific situations and should +** not get mixed with CURLcode or CURLMcode values. +** +** For portability reasons TEST_ERR_* values should be less than 127. +*/ + +#define TEST_ERR_MAJOR_BAD 126 +#define TEST_ERR_RUNS_FOREVER 125 +#define TEST_ERR_EASY_INIT 124 +#define TEST_ERR_MULTI_INIT 123 +#define TEST_ERR_NUM_HANDLES 122 +#define TEST_ERR_SELECT 121 +#define TEST_ERR_SUCCESS 120 +#define TEST_ERR_FAILURE 119 +#define TEST_ERR_USAGE 118 +#define TEST_ERR_FOPEN 117 +#define TEST_ERR_FSTAT 116 +#define TEST_ERR_BAD_TIMEOUT 115 + +/* +** Macros for test source code readability/maintainability. +** +** All of the following macros require that an int data type 'res' variable +** exists in scope where macro is used, and that it has been initialized to +** zero before the macro is used. +** +** exe_* and chk_* macros are helper macros not intended to be used from +** outside of this header file. Arguments 'Y' and 'Z' of these represent +** source code file and line number, while Arguments 'A', 'B', etc, are +** the arguments used to actually call a libcurl function. +** +** All easy_* and multi_* macros call a libcurl function and evaluate if +** the function has succeeded or failed. When the function succeeds 'res' +** variable is not set nor cleared and program continues normal flow. On +** the other hand if function fails 'res' variable is set and a jump to +** label 'test_cleanup' is performed. +** +** Every easy_* and multi_* macros have a res_easy_* and res_multi_* macro +** counterpart that operates in tha same way with the exception that no +** jump takes place in case of failure. res_easy_* and res_multi_* macros +** should be immediately followed by checking if 'res' variable has been +** set. +** +** 'res' variable when set will hold a CURLcode, CURLMcode, or any of the +** TEST_ERR_* values defined above. It is advisable to return this value +** as test result. +*/ + +/* ---------------------------------------------------------------- */ + +#define exe_easy_init(A,Y,Z) do { \ + if(((A) = curl_easy_init()) == NULL) { \ + fprintf(stderr, "%s:%d curl_easy_init() failed\n", (Y), (Z)); \ + res = TEST_ERR_EASY_INIT; \ + } \ +} WHILE_FALSE + +#define res_easy_init(A) \ + exe_easy_init((A),(__FILE__),(__LINE__)) + +#define chk_easy_init(A,Y,Z) do { \ + exe_easy_init((A),(Y),(Z)); \ + if(res) \ + goto test_cleanup; \ +} WHILE_FALSE + +#define easy_init(A) \ + chk_easy_init((A),(__FILE__),(__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_multi_init(A,Y,Z) do { \ + if(((A) = curl_multi_init()) == NULL) { \ + fprintf(stderr, "%s:%d curl_multi_init() failed\n", (Y), (Z)); \ + res = TEST_ERR_MULTI_INIT; \ + } \ +} WHILE_FALSE + +#define res_multi_init(A) \ + exe_multi_init((A),(__FILE__),(__LINE__)) + +#define chk_multi_init(A,Y,Z) do { \ + exe_multi_init((A),(Y),(Z)); \ + if(res) \ + goto test_cleanup; \ +} WHILE_FALSE + +#define multi_init(A) \ + chk_multi_init((A),(__FILE__),(__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_easy_setopt(A,B,C,Y,Z) do { \ + CURLcode ec; \ + if((ec = curl_easy_setopt((A),(B),(C))) != CURLE_OK) { \ + fprintf(stderr, "%s:%d curl_easy_setopt() failed, " \ + "with code %d (%s)\n", \ + (Y), (Z), (int)ec, curl_easy_strerror(ec)); \ + res = (int)ec; \ + } \ +} WHILE_FALSE + +#define res_easy_setopt(A,B,C) \ + exe_easy_setopt((A),(B),(C),(__FILE__),(__LINE__)) + +#define chk_easy_setopt(A,B,C,Y,Z) do { \ + exe_easy_setopt((A),(B),(C),(Y),(Z)); \ + if(res) \ + goto test_cleanup; \ +} WHILE_FALSE + +#define easy_setopt(A,B,C) \ + chk_easy_setopt((A),(B),(C),(__FILE__),(__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_multi_setopt(A,B,C,Y,Z) do { \ + CURLMcode ec; \ + if((ec = curl_multi_setopt((A),(B),(C))) != CURLM_OK) { \ + fprintf(stderr, "%s:%d curl_multi_setopt() failed, " \ + "with code %d (%s)\n", \ + (Y), (Z), (int)ec, curl_multi_strerror(ec)); \ + res = (int)ec; \ + } \ +} WHILE_FALSE + +#define res_multi_setopt(A,B,C) \ + exe_multi_setopt((A),(B),(C),(__FILE__),(__LINE__)) + +#define chk_multi_setopt(A,B,C,Y,Z) do { \ + exe_multi_setopt((A),(B),(C),(Y),(Z)); \ + if(res) \ + goto test_cleanup; \ +} WHILE_FALSE + +#define multi_setopt(A,B,C) \ + chk_multi_setopt((A),(B),(C),(__FILE__),(__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_multi_add_handle(A,B,Y,Z) do { \ + CURLMcode ec; \ + if((ec = curl_multi_add_handle((A),(B))) != CURLM_OK) { \ + fprintf(stderr, "%s:%d curl_multi_add_handle() failed, " \ + "with code %d (%s)\n", \ + (Y), (Z), (int)ec, curl_multi_strerror(ec)); \ + res = (int)ec; \ + } \ +} WHILE_FALSE + +#define res_multi_add_handle(A,B) \ + exe_multi_add_handle((A),(B),(__FILE__),(__LINE__)) + +#define chk_multi_add_handle(A,B,Y,Z) do { \ + exe_multi_add_handle((A),(B),(Y),(Z)); \ + if(res) \ + goto test_cleanup; \ +} WHILE_FALSE + +#define multi_add_handle(A,B) \ + chk_multi_add_handle((A),(B),(__FILE__),(__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_multi_remove_handle(A,B,Y,Z) do { \ + CURLMcode ec; \ + if((ec = curl_multi_remove_handle((A),(B))) != CURLM_OK) { \ + fprintf(stderr, "%s:%d curl_multi_remove_handle() failed, " \ + "with code %d (%s)\n", \ + (Y), (Z), (int)ec, curl_multi_strerror(ec)); \ + res = (int)ec; \ + } \ +} WHILE_FALSE + +#define res_multi_remove_handle(A,B) \ + exe_multi_remove_handle((A),(B),(__FILE__),(__LINE__)) + +#define chk_multi_remove_handle(A,B,Y,Z) do { \ + exe_multi_remove_handle((A),(B),(Y),(Z)); \ + if(res) \ + goto test_cleanup; \ +} WHILE_FALSE + + +#define multi_remove_handle(A,B) \ + chk_multi_remove_handle((A),(B),(__FILE__),(__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_multi_perform(A,B,Y,Z) do { \ + CURLMcode ec; \ + if((ec = curl_multi_perform((A),(B))) != CURLM_OK) { \ + fprintf(stderr, "%s:%d curl_multi_perform() failed, " \ + "with code %d (%s)\n", \ + (Y), (Z), (int)ec, curl_multi_strerror(ec)); \ + res = (int)ec; \ + } \ + else if(*((B)) < 0) { \ + fprintf(stderr, "%s:%d curl_multi_perform() succeeded, " \ + "but returned invalid running_handles value (%d)\n", \ + (Y), (Z), (int)*((B))); \ + res = TEST_ERR_NUM_HANDLES; \ + } \ +} WHILE_FALSE + +#define res_multi_perform(A,B) \ + exe_multi_perform((A),(B),(__FILE__),(__LINE__)) + +#define chk_multi_perform(A,B,Y,Z) do { \ + exe_multi_perform((A),(B),(Y),(Z)); \ + if(res) \ + goto test_cleanup; \ +} WHILE_FALSE + +#define multi_perform(A,B) \ + chk_multi_perform((A),(B),(__FILE__),(__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_multi_fdset(A,B,C,D,E,Y,Z) do { \ + CURLMcode ec; \ + if((ec = curl_multi_fdset((A),(B),(C),(D),(E))) != CURLM_OK) { \ + fprintf(stderr, "%s:%d curl_multi_fdset() failed, " \ + "with code %d (%s)\n", \ + (Y), (Z), (int)ec, curl_multi_strerror(ec)); \ + res = (int)ec; \ + } \ + else if(*((E)) < -1) { \ + fprintf(stderr, "%s:%d curl_multi_fdset() succeeded, " \ + "but returned invalid max_fd value (%d)\n", \ + (Y), (Z), (int)*((E))); \ + res = TEST_ERR_NUM_HANDLES; \ + } \ +} WHILE_FALSE + +#define res_multi_fdset(A,B,C,D,E) \ + exe_multi_fdset((A),(B),(C),(D),(E),(__FILE__),(__LINE__)) + +#define chk_multi_fdset(A,B,C,D,E,Y,Z) do { \ + exe_multi_fdset((A),(B),(C),(D),(E),(Y),(Z)); \ + if(res) \ + goto test_cleanup; \ +} WHILE_FALSE + +#define multi_fdset(A,B,C,D,E) \ + chk_multi_fdset((A),(B),(C),(D),(E),(__FILE__),(__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_multi_timeout(A,B,Y,Z) do { \ + CURLMcode ec; \ + if((ec = curl_multi_timeout((A),(B))) != CURLM_OK) { \ + fprintf(stderr, "%s:%d curl_multi_timeout() failed, " \ + "with code %d (%s)\n", \ + (Y), (Z), (int)ec, curl_multi_strerror(ec)); \ + res = (int)ec; \ + } \ + else if(*((B)) < -1L) { \ + fprintf(stderr, "%s:%d curl_multi_timeout() succeeded, " \ + "but returned invalid timeout value (%ld)\n", \ + (Y), (Z), (long)*((B))); \ + res = TEST_ERR_BAD_TIMEOUT; \ + } \ +} WHILE_FALSE + +#define res_multi_timeout(A,B) \ + exe_multi_timeout((A),(B),(__FILE__),(__LINE__)) + +#define chk_multi_timeout(A,B,Y,Z) do { \ + exe_multi_timeout((A),(B),(Y),(Z)); \ + if(res) \ + goto test_cleanup; \ +} WHILE_FALSE + +#define multi_timeout(A,B) \ + chk_multi_timeout((A),(B),(__FILE__),(__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_select_test(A,B,C,D,E,Y,Z) do { \ + int ec; \ + if(select_wrapper((A),(B),(C),(D),(E)) == -1 ) { \ + ec = SOCKERRNO; \ + fprintf(stderr, "%s:%d select() failed, with " \ + "errno %d (%s)\n", \ + (Y), (Z), ec, strerror(ec)); \ + res = TEST_ERR_SELECT; \ + } \ +} WHILE_FALSE + +#define res_select_test(A,B,C,D,E) \ + exe_select_test((A),(B),(C),(D),(E),(__FILE__),(__LINE__)) + +#define chk_select_test(A,B,C,D,E,Y,Z) do { \ + exe_select_test((A),(B),(C),(D),(E),(Y),(Z)); \ + if(res) \ + goto test_cleanup; \ +} WHILE_FALSE + +#define select_test(A,B,C,D,E) \ + chk_select_test((A),(B),(C),(D),(E),(__FILE__),(__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define start_test_timing() do { \ + tv_test_start = tutil_tvnow(); \ +} WHILE_FALSE + +#define exe_test_timedout(Y,Z) do { \ + if(tutil_tvdiff(tutil_tvnow(), tv_test_start) > TEST_HANG_TIMEOUT) { \ + fprintf(stderr, "%s:%d ABORTING TEST, since it seems " \ + "that it would have run forever.\n", (Y), (Z)); \ + res = TEST_ERR_RUNS_FOREVER; \ + } \ +} WHILE_FALSE + +#define res_test_timedout() \ + exe_test_timedout((__FILE__),(__LINE__)) + +#define chk_test_timedout(Y,Z) do { \ + exe_test_timedout(Y,Z); \ + if(res) \ + goto test_cleanup; \ +} WHILE_FALSE + +#define abort_on_test_timeout() \ + chk_test_timedout((__FILE__),(__LINE__)) + +/* ---------------------------------------------------------------- */ + +#define exe_global_init(A,Y,Z) do { \ + CURLcode ec; \ + if((ec = curl_global_init((A))) != CURLE_OK) { \ + fprintf(stderr, "%s:%d curl_global_init() failed, " \ + "with code %d (%s)\n", \ + (Y), (Z), (int)ec, curl_easy_strerror(ec)); \ + res = (int)ec; \ + } \ +} WHILE_FALSE + +#define res_global_init(A) \ + exe_global_init((A),(__FILE__),(__LINE__)) + +#define chk_global_init(A,Y,Z) do { \ + exe_global_init((A),(Y),(Z)); \ + if(res) \ + return res; \ +} WHILE_FALSE + +/* global_init() is different than other macros. In case of + failure it 'return's instead of going to 'test_cleanup'. */ + +#define global_init(A) \ + chk_global_init((A),(__FILE__),(__LINE__)) + +/* ---------------------------------------------------------------- */ diff --git a/tests/libtest/test1013.pl b/tests/libtest/test1013.pl new file mode 100755 index 000000000..15e121415 --- /dev/null +++ b/tests/libtest/test1013.pl @@ -0,0 +1,50 @@ +#!/usr/bin/env perl +# Determine if curl-config --protocols/--features matches the +# curl --version protocols/features +if ( $#ARGV != 2 ) +{ + print "Usage: $0 curl-config-script curl-version-output-file features|protocols\n"; + exit 3; +} + +my $what=$ARGV[2]; + +# Read the output of curl --version +my $curl_protocols=""; +open(CURL, "$ARGV[1]") || die "Can't get curl $what list\n"; +while( <CURL> ) +{ + $curl_protocols = lc($_) if ( /$what:/i ); +} +close CURL; + +$curl_protocols =~ s/\r//; +$curl_protocols =~ /\w+: (.*)$/; +@curl = split / /,$1; + +# These features are not supported by curl-config +@curl = grep(!/^(Debug|TrackMemory|Metalink|Largefile|CharConv|GSS-Negotiate|SPNEGO)$/i, @curl); +@curl = sort @curl; + +# Read the output of curl-config +my @curl_config; +open(CURLCONFIG, "sh $ARGV[0] --$what|") || die "Can't get curl-config $what list\n"; +while( <CURLCONFIG> ) +{ + chomp; + push @curl_config, lc($_); +} +close CURLCONFIG; + +@curl_config = sort @curl_config; + +my $curlproto = join ' ', @curl; +my $curlconfigproto = join ' ', @curl_config; + +my $different = $curlproto ne $curlconfigproto; +if ($different) { + print "Mismatch in $what lists:\n"; + print "curl: $curlproto\n"; + print "curl-config: $curlconfigproto\n"; +} +exit $different; diff --git a/tests/libtest/test1022.pl b/tests/libtest/test1022.pl new file mode 100755 index 000000000..377808c73 --- /dev/null +++ b/tests/libtest/test1022.pl @@ -0,0 +1,54 @@ +#!/usr/bin/env perl +# Determine if curl-config --version matches the curl --version +if ( $#ARGV != 2 ) +{ + print "Usage: $0 curl-config-script curl-version-output-file version|vernum\n"; + exit 3; +} + +my $what=$ARGV[2]; + +# Read the output of curl --version +open(CURL, "$ARGV[1]") || die "Can't open curl --version list in $ARGV[1]\n"; +$_ = <CURL>; +chomp; +/libcurl\/([\.\d]+((-DEV)|(-\d+))?)/; +my $version = $1; +close CURL; + +my $curlconfigversion; + +# Read the output of curl-config --version/--vernum +open(CURLCONFIG, "sh $ARGV[0] --$what|") || die "Can't get curl-config --$what list\n"; +$_ = <CURLCONFIG>; +chomp; +my $filever=$_; +if ( $what eq "version" ) { + if($filever =~ /^libcurl ([\.\d]+((-DEV)|(-\d+))?)$/) { + $curlconfigversion = $1; + } + else { + $curlconfigversion = "illegal value"; + } +} +else { # "vernum" case + # Convert hex version to decimal for comparison's sake + if($filever =~ /^(..)(..)(..)$/) { + $curlconfigversion = hex($1) . "." . hex($2) . "." . hex($3); + } + else { + $curlconfigversion = "illegal value"; + } + + # Strip off the -DEV from the curl version if it's there + $version =~ s/-\w*$//; +} +close CURLCONFIG; + +my $different = $version ne $curlconfigversion; +if ($different || !$version) { + print "Mismatch in --version:\n"; + print "curl: $version\n"; + print "curl-config: $curlconfigversion\n"; + exit 1; +} diff --git a/tests/libtest/test307.pl b/tests/libtest/test307.pl new file mode 100755 index 000000000..469af3c21 --- /dev/null +++ b/tests/libtest/test307.pl @@ -0,0 +1,19 @@ +#!/usr/bin/env perl +# Determine if the given curl executable supports the 'openssl' SSL engine +if ( $#ARGV != 0 ) +{ + print "Usage: $0 curl-executable\n"; + exit 3; +} +if (!open(CURL, "@ARGV[0] -s --engine list|")) +{ + print "Can't get SSL engine list\n"; + exit 2; +} +while( <CURL> ) +{ + exit 0 if ( /openssl/ ); +} +close CURL; +print "openssl engine not supported\n"; +exit 1; diff --git a/tests/libtest/test610.pl b/tests/libtest/test610.pl new file mode 100755 index 000000000..a900d94b4 --- /dev/null +++ b/tests/libtest/test610.pl @@ -0,0 +1,33 @@ +#!/usr/bin/env perl +# Perform simple file and directory manipulation in a portable way +if ( $#ARGV <= 0 ) +{ + print "Usage: $0 mkdir|rmdir|rm|move|gone path1 [path2] [more commands...]\n"; + exit 1; +} + +use File::Copy; +while(@ARGV) { + my $cmd = shift @ARGV; + my $arg = shift @ARGV; + if ($cmd eq "mkdir") { + mkdir $arg || die "$!"; + } + elsif ($cmd eq "rmdir") { + rmdir $arg || die "$!"; + } + elsif ($cmd eq "rm") { + unlink $arg || die "$!"; + } + elsif ($cmd eq "move") { + my $arg2 = shift @ARGV; + move($arg,$arg2) || die "$!"; + } + elsif ($cmd eq "gone") { + ! -e $arg || die "Path $arg exists"; + } else { + print "Unsupported command $cmd\n"; + exit 1; + } +} +exit 0; diff --git a/tests/libtest/test613.pl b/tests/libtest/test613.pl new file mode 100755 index 000000000..b4caaae07 --- /dev/null +++ b/tests/libtest/test613.pl @@ -0,0 +1,105 @@ +#!/usr/bin/env perl +# Prepare a directory with known files and clean up afterwards +use Time::Local; + +if ( $#ARGV < 1 ) +{ + print "Usage: $0 prepare|postprocess dir [logfile]\n"; + exit 1; +} + +# <precheck> expects an error message on stdout +sub errout { + print $_[0] . "\n"; + exit 1; +} + +if ($ARGV[0] eq "prepare") +{ + my $dirname = $ARGV[1]; + mkdir $dirname || errout "$!"; + chdir $dirname; + + # Create the files in alphabetical order, to increase the chances + # of receiving a consistent set of directory contents regardless + # of whether the server alphabetizes the results or not. + mkdir "asubdir" || errout "$!"; + chmod 0777, "asubdir"; + + open(FILE, ">plainfile.txt") || errout "$!"; + binmode FILE; + print FILE "Test file to support curl test suite\n"; + close(FILE); + utime time, timegm(0,0,12,1,0,100), "plainfile.txt"; + chmod 0666, "plainfile.txt"; + + open(FILE, ">rofile.txt") || errout "$!"; + binmode FILE; + print FILE "Read-only test file to support curl test suite\n"; + close(FILE); + utime time, timegm(0,0,12,31,11,100), "rofile.txt"; + chmod 0444, "rofile.txt"; + + exit 0; +} +elsif ($ARGV[0] eq "postprocess") +{ + my $dirname = $ARGV[1]; + my $logfile = $ARGV[2]; + + # Clean up the test directory + unlink "$dirname/rofile.txt"; + unlink "$dirname/plainfile.txt"; + rmdir "$dirname/asubdir"; + + rmdir $dirname || die "$!"; + + if ($logfile) { + # Process the directory file to remove all information that + # could be inconsistent from one test run to the next (e.g. + # file date) or may be unsupported on some platforms (e.g. + # Windows). Also, since 7.17.0, the sftp directory listing + # format can be dependent on the server (with a recent + # enough version of libssh2) so this script must also + # canonicalize the format. Here are examples of the general + # format supported: + # -r--r--r-- 12 ausername grp 47 Dec 31 2000 rofile.txt + # -r--r--r-- 1 1234 4321 47 Dec 31 2000 rofile.txt + # The "canonical" format is similar to the first (which is + # the one generated on a typical Linux installation): + # -r-?r-?r-? 12 U U 47 Dec 31 2000 rofile.txt + + my @canondir; + open(IN, "<$logfile") || die "$!"; + while (<IN>) { + /^(.)(..).(..).(..).\s*(\S+)\s+\S+\s+\S+\s+(\S+)\s+(\S+\s+\S+\s+\S+)(.*)$/; + if ($1 eq "d") { + # Erase all directory metadata except for the name, as it is not + # consistent for across all test systems and filesystems + push @canondir, "d????????? N U U N ??? N NN:NN$8\n"; + } elsif ($1 eq "-") { + # Erase user and group names, as they are not consistent across + # all test systems + my $line = sprintf("%s%s?%s?%s?%5d U U %15d %s%s\n", $1,$2,$3,$4,$5,$6,$7,$8); + push @canondir, $line; + } else { + # Unexpected format; just pass it through and let the test fail + push @canondir, $_; + } + } + close(IN); + + @canondir = sort {substr($a,57) cmp substr($b,57)} @canondir; + my $newfile = $logfile . ".new"; + open(OUT, ">$newfile") || die "$!"; + print OUT join('', @canondir); + close(OUT); + + unlink $logfile; + rename $newfile, $logfile; + } + + exit 0; +} +print "Unsupported command $ARGV[0]\n"; +exit 1; diff --git a/tests/libtest/test75.pl b/tests/libtest/test75.pl new file mode 100755 index 000000000..31cdfb8cc --- /dev/null +++ b/tests/libtest/test75.pl @@ -0,0 +1,13 @@ +#!/usr/bin/env perl +# Check that the length of a given URL is correct +if ( $#ARGV != 1 ) +{ + print "Usage: $0 string length\n"; + exit 3; +} +if (length(@ARGV[0]) != @ARGV[1]) +{ + print "Given host IP and port not supported\n"; + exit 1; +} +exit 0; diff --git a/tests/libtest/testtrace.c b/tests/libtest/testtrace.c new file mode 100644 index 000000000..c977d2105 --- /dev/null +++ b/tests/libtest/testtrace.c @@ -0,0 +1,146 @@ +/*************************************************************************** + * _ _ ____ _ + * 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" + +#define _MPRINTF_REPLACE /* use our functions only */ +#include <curl/mprintf.h> + +#include "testutil.h" +#include "testtrace.h" +#include "memdebug.h" + +struct libtest_trace_cfg libtest_debug_config; + +static time_t epoch_offset; /* for test time tracing */ +static int known_offset; /* for test time tracing */ + +static +void libtest_debug_dump(const char *timebuf, const char *text, FILE *stream, + const unsigned char *ptr, size_t size, int nohex) +{ + size_t i; + size_t c; + + unsigned int width = 0x10; + + if(nohex) + /* without the hex output, we can fit more on screen */ + width = 0x40; + + fprintf(stream, "%s%s, %d bytes (0x%x)\n", timebuf, text, + (int)size, (int)size); + + for(i = 0; i < size; i += width) { + + fprintf(stream, "%04x: ", (int)i); + + if(!nohex) { + /* hex not disabled, show it */ + for(c = 0; c < width; c++) + if(i+c < size) + fprintf(stream, "%02x ", ptr[i+c]); + else + fputs(" ", stream); + } + + for(c = 0; (c < width) && (i+c < size); c++) { + /* check for 0D0A; if found, skip past and start a new line of output */ + if(nohex && + (i+c+1 < size) && (ptr[i+c] == 0x0D) && (ptr[i+c+1] == 0x0A)) { + i += (c+2-width); + break; + } + fprintf(stream, "%c", ((ptr[i+c] >= 0x20) && (ptr[i+c] < 0x80)) ? + ptr[i+c] : '.'); + /* check again for 0D0A, to avoid an extra \n if it's at width */ + if(nohex && + (i+c+2 < size) && (ptr[i+c+1] == 0x0D) && (ptr[i+c+2] == 0x0A)) { + i += (c+3-width); + break; + } + } + fputc('\n', stream); /* newline */ + } + fflush(stream); +} + +int libtest_debug_cb(CURL *handle, curl_infotype type, + unsigned char *data, size_t size, + void *userp) +{ + + struct libtest_trace_cfg *trace_cfg = userp; + const char *text; + struct timeval tv; + struct tm *now; + char timebuf[20]; + char *timestr; + time_t secs; + + (void)handle; + + timebuf[0] = '\0'; + timestr = &timebuf[0]; + + if(trace_cfg->tracetime) { + tv = tutil_tvnow(); + if(!known_offset) { + epoch_offset = time(NULL) - tv.tv_sec; + known_offset = 1; + } + secs = epoch_offset + tv.tv_sec; + now = localtime(&secs); /* not thread safe but we don't care */ + snprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06ld ", + now->tm_hour, now->tm_min, now->tm_sec, (long)tv.tv_usec); + } + + switch (type) { + case CURLINFO_TEXT: + fprintf(stderr, "%s== Info: %s", timestr, (char *)data); + default: /* in case a new one is introduced to shock us */ + return 0; + + case CURLINFO_HEADER_OUT: + text = "=> Send header"; + break; + case CURLINFO_DATA_OUT: + text = "=> Send data"; + break; + case CURLINFO_SSL_DATA_OUT: + text = "=> Send SSL data"; + break; + case CURLINFO_HEADER_IN: + text = "<= Recv header"; + break; + case CURLINFO_DATA_IN: + text = "<= Recv data"; + break; + case CURLINFO_SSL_DATA_IN: + text = "<= Recv SSL data"; + break; + } + + libtest_debug_dump(timebuf, text, stderr, data, size, trace_cfg->nohex); + return 0; +} + diff --git a/tests/libtest/testtrace.h b/tests/libtest/testtrace.h new file mode 100644 index 000000000..73d2489a4 --- /dev/null +++ b/tests/libtest/testtrace.h @@ -0,0 +1,37 @@ +#ifndef HEADER_LIBTEST_TESTTRACE_H +#define HEADER_LIBTEST_TESTTRACE_H +/*************************************************************************** + * _ _ ____ _ + * 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. + * + ***************************************************************************/ + +struct libtest_trace_cfg { + int tracetime; /* 0 represents FALSE, anything else TRUE */ + int nohex; /* 0 represents FALSE, anything else TRUE */ +}; + +extern struct libtest_trace_cfg libtest_debug_config; + +int libtest_debug_cb(CURL *handle, curl_infotype type, + unsigned char *data, size_t size, + void *userp); + +#endif /* HEADER_LIBTEST_TESTTRACE_H */ + diff --git a/tests/libtest/testutil.c b/tests/libtest/testutil.c new file mode 100644 index 000000000..3ad18c987 --- /dev/null +++ b/tests/libtest/testutil.c @@ -0,0 +1,137 @@ +/*************************************************************************** + * _ _ ____ _ + * 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 "setup.h" + +#include "testutil.h" +#include "memdebug.h" + +#if defined(WIN32) && !defined(MSDOS) + +struct timeval tutil_tvnow(void) +{ + /* + ** GetTickCount() is available on _all_ Windows versions from W95 up + ** to nowadays. Returns milliseconds elapsed since last system boot, + ** increases monotonically and wraps once 49.7 days have elapsed. + */ + struct timeval now; + DWORD milliseconds = GetTickCount(); + now.tv_sec = milliseconds / 1000; + now.tv_usec = (milliseconds % 1000) * 1000; + return now; +} + +#elif defined(HAVE_CLOCK_GETTIME_MONOTONIC) + +struct timeval tutil_tvnow(void) +{ + /* + ** clock_gettime() is granted to be increased monotonically when the + ** monotonic clock is queried. Time starting point is unspecified, it + ** could be the system start-up time, the Epoch, or something else, + ** in any case the time starting point does not change once that the + ** system has started up. + */ + struct timeval now; + struct timespec tsnow; + if(0 == clock_gettime(CLOCK_MONOTONIC, &tsnow)) { + now.tv_sec = tsnow.tv_sec; + now.tv_usec = tsnow.tv_nsec / 1000; + } + /* + ** Even when the configure process has truly detected monotonic clock + ** availability, it might happen that it is not actually available at + ** run-time. When this occurs simply fallback to other time source. + */ +#ifdef HAVE_GETTIMEOFDAY + else + (void)gettimeofday(&now, NULL); +#else + else { + now.tv_sec = (long)time(NULL); + now.tv_usec = 0; + } +#endif + return now; +} + +#elif defined(HAVE_GETTIMEOFDAY) + +struct timeval tutil_tvnow(void) +{ + /* + ** gettimeofday() is not granted to be increased monotonically, due to + ** clock drifting and external source time synchronization it can jump + ** forward or backward in time. + */ + struct timeval now; + (void)gettimeofday(&now, NULL); + return now; +} + +#else + +struct timeval tutil_tvnow(void) +{ + /* + ** time() returns the value of time in seconds since the Epoch. + */ + struct timeval now; + now.tv_sec = (long)time(NULL); + now.tv_usec = 0; + return now; +} + +#endif + +/* + * Make sure that the first argument is the more recent time, as otherwise + * we'll get a weird negative time-diff back... + * + * Returns: the time difference in number of milliseconds. + */ +long tutil_tvdiff(struct timeval newer, struct timeval older) +{ + return (newer.tv_sec-older.tv_sec)*1000+ + (newer.tv_usec-older.tv_usec)/1000; +} + +/* + * Same as tutil_tvdiff but with full usec resolution. + * + * Returns: the time difference in seconds with subsecond resolution. + */ +double tutil_tvdiff_secs(struct timeval newer, struct timeval older) +{ + if(newer.tv_sec != older.tv_sec) + return (double)(newer.tv_sec-older.tv_sec)+ + (double)(newer.tv_usec-older.tv_usec)/1000000.0; + else + return (double)(newer.tv_usec-older.tv_usec)/1000000.0; +} + +/* return the number of seconds in the given input timeval struct */ +long tutil_tvlong(struct timeval t1) +{ + return t1.tv_sec; +} + diff --git a/tests/libtest/testutil.h b/tests/libtest/testutil.h new file mode 100644 index 000000000..0c6be2fc4 --- /dev/null +++ b/tests/libtest/testutil.h @@ -0,0 +1,47 @@ +#ifndef HEADER_CURL_LIBTEST_TESTUTIL_H +#define HEADER_CURL_LIBTEST_TESTUTIL_H +/*************************************************************************** + * _ _ ____ _ + * 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 "setup.h" + +struct timeval tutil_tvnow(void); + +/* + * Make sure that the first argument (t1) is the more recent time and t2 is + * the older time, as otherwise you get a weird negative time-diff back... + * + * Returns: the time difference in number of milliseconds. + */ +long tutil_tvdiff(struct timeval t1, struct timeval t2); + +/* + * Same as tutil_tvdiff but with full usec resolution. + * + * Returns: the time difference in seconds with subsecond resolution. + */ +double tutil_tvdiff_secs(struct timeval t1, struct timeval t2); + +long tutil_tvlong(struct timeval t1); + + +#endif /* HEADER_CURL_LIBTEST_TESTUTIL_H */ + |