Imported libcurl source code.
This commit is contained in:
@@ -0,0 +1,172 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2008, Daniel Stenberg, <[email protected]>, 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.
|
||||
#
|
||||
# $Id: Makefile.am,v 1.78 2008-11-11 21:59:25 bagder Exp $
|
||||
###########################################################################
|
||||
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 is for libcurl's generated curl/curlbuild.h file
|
||||
# $(top_srcdir)/include is for libcurl's external include files
|
||||
# $(top_builddir)/lib is for libcurl's generated lib/config.h file
|
||||
# $(top_srcdir)/lib is for libcurl's lib/setup.h and other "borrowed" files
|
||||
|
||||
INCLUDES = -I$(top_builddir)/include \
|
||||
-I$(top_srcdir)/include \
|
||||
-I$(top_builddir)/lib \
|
||||
-I$(top_srcdir)/lib
|
||||
|
||||
LIBDIR = $(top_builddir)/lib
|
||||
|
||||
EXTRA_DIST = test75.pl test307.pl test610.pl test613.pl test1013.pl test1022.pl
|
||||
|
||||
# files used only in some libcurl test programs
|
||||
TESTUTIL = testutil.c testutil.h
|
||||
|
||||
# these files are used in every single test program below
|
||||
SUPPORTFILES = first.c test.h
|
||||
|
||||
# These are all libcurl test programs
|
||||
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 lib558 lib559 lib560
|
||||
|
||||
# Dependencies (may need to be overriden)
|
||||
LDADD = $(LIBDIR)/libcurl.la
|
||||
DEPENDENCIES = $(LIBDIR)/libcurl.la
|
||||
|
||||
|
||||
lib500_SOURCES = lib500.c $(SUPPORTFILES)
|
||||
|
||||
lib501_SOURCES = lib501.c $(SUPPORTFILES)
|
||||
|
||||
lib502_SOURCES = lib502.c $(SUPPORTFILES) $(TESTUTIL)
|
||||
|
||||
lib503_SOURCES = lib503.c $(SUPPORTFILES) $(TESTUTIL)
|
||||
|
||||
lib504_SOURCES = lib504.c $(SUPPORTFILES) $(TESTUTIL)
|
||||
|
||||
lib505_SOURCES = lib505.c $(SUPPORTFILES)
|
||||
|
||||
lib506_SOURCES = lib506.c $(SUPPORTFILES)
|
||||
|
||||
lib507_SOURCES = lib507.c $(SUPPORTFILES) $(TESTUTIL)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
lib526_SOURCES = lib526.c $(SUPPORTFILES) $(TESTUTIL)
|
||||
lib526_CFLAGS = -DLIB526
|
||||
|
||||
lib527_SOURCES = lib526.c $(SUPPORTFILES) $(TESTUTIL)
|
||||
lib527_CFLAGS = -DLIB527
|
||||
|
||||
lib529_SOURCES = lib525.c $(SUPPORTFILES) $(TESTUTIL)
|
||||
lib529_CFLAGS = -DLIB529
|
||||
|
||||
lib530_SOURCES = lib530.c $(SUPPORTFILES) $(TESTUTIL)
|
||||
lib530_CFLAGS = -DLIB530
|
||||
|
||||
lib532_SOURCES = lib526.c $(SUPPORTFILES) $(TESTUTIL)
|
||||
lib532_CFLAGS = -DLIB532
|
||||
|
||||
lib533_SOURCES = lib533.c $(SUPPORTFILES) $(TESTUTIL)
|
||||
|
||||
lib536_SOURCES = lib536.c $(SUPPORTFILES) $(TESTUTIL)
|
||||
|
||||
lib537_SOURCES = lib537.c $(SUPPORTFILES)
|
||||
|
||||
lib539_SOURCES = lib539.c $(SUPPORTFILES)
|
||||
|
||||
lib540_SOURCES = lib540.c $(SUPPORTFILES)
|
||||
|
||||
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_CFLAGS = -DLIB545
|
||||
|
||||
lib547_SOURCES = lib547.c $(SUPPORTFILES)
|
||||
|
||||
lib548_SOURCES = lib547.c $(SUPPORTFILES)
|
||||
lib548_CFLAGS = -DLIB548
|
||||
|
||||
lib549_SOURCES = lib549.c $(SUPPORTFILES)
|
||||
|
||||
lib555_SOURCES = lib555.c $(SUPPORTFILES) $(TESTUTIL)
|
||||
|
||||
lib552_SOURCES = lib552.c $(SUPPORTFILES)
|
||||
|
||||
lib553_SOURCES = lib553.c $(SUPPORTFILES)
|
||||
|
||||
lib554_SOURCES = lib554.c $(SUPPORTFILES)
|
||||
|
||||
lib556_SOURCES = lib556.c $(SUPPORTFILES)
|
||||
|
||||
lib557_SOURCES = lib557.c $(SUPPORTFILES)
|
||||
|
||||
lib558_SOURCES = lib558.c $(SUPPORTFILES)
|
||||
lib558_CFLAGS = -DLIB558
|
||||
|
||||
lib559_SOURCES = lib558.c $(SUPPORTFILES)
|
||||
lib559_CFLAGS = -DLIB559
|
||||
|
||||
lib560_SOURCES = lib560.c $(SUPPORTFILES)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,82 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: first.c,v 1.19 2008-09-20 04:26:55 yangtse Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
# define MEMDEBUG_NODEFINES
|
||||
# include "memdebug.h"
|
||||
#endif
|
||||
|
||||
int select_test (int num_fds, fd_set *rd, fd_set *wr, fd_set *exc,
|
||||
struct timeval *tv)
|
||||
{
|
||||
#ifdef USE_WINSOCK
|
||||
/* Winsock doesn't like no socket set in 'rd', 'wr' or 'exc'. This is
|
||||
* case when 'num_fds <= 0. So sleep.
|
||||
*/
|
||||
if (num_fds <= 0) {
|
||||
Sleep(1000*tv->tv_sec + tv->tv_usec/1000);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return select(num_fds, rd, wr, exc, tv);
|
||||
}
|
||||
|
||||
char *libtest_arg2=NULL;
|
||||
char *libtest_arg3=NULL;
|
||||
int test_argc;
|
||||
char **test_argv;
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *URL;
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
/* this sends all memory debug messages to a logfile named memdump */
|
||||
char *env = curl_getenv("CURL_MEMDEBUG");
|
||||
if(env) {
|
||||
/* use the value as file name */
|
||||
char *s = strdup(env);
|
||||
curl_free(env);
|
||||
curl_memdebug(s);
|
||||
free(s);
|
||||
/* this weird strdup() and stuff here is to make the curl_free() get
|
||||
called before the memdebug() as otherwise the memdebug tracing will
|
||||
with tracing a free() without an alloc! */
|
||||
}
|
||||
/* this enables the fail-on-alloc-number-N functionality */
|
||||
env = curl_getenv("CURL_MEMLIMIT");
|
||||
if(env) {
|
||||
curl_memlimit(atoi(env));
|
||||
curl_free(env);
|
||||
}
|
||||
#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);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib500.c,v 1.9 2008-09-20 04:26:56 yangtse Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include "memdebug.h"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
|
||||
|
||||
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) {
|
||||
fprintf(moo, "IP: %s\n", ipstr);
|
||||
fclose(moo);
|
||||
}
|
||||
}
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib501.c,v 1.7 2008-09-20 04:26:56 yangtse Exp $
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib502.c,v 1.8 2008-09-20 04:26:56 yangtse Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include "testutil.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
||||
|
||||
/*
|
||||
* Get a single URL without select().
|
||||
*/
|
||||
|
||||
int test(char *URL)
|
||||
{
|
||||
CURL *c;
|
||||
CURLM *m;
|
||||
int res = 0;
|
||||
int running=1;
|
||||
struct timeval mp_start;
|
||||
char mp_timedout = FALSE;
|
||||
|
||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
||||
fprintf(stderr, "curl_global_init() failed\n");
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if ((c = curl_easy_init()) == NULL) {
|
||||
fprintf(stderr, "curl_easy_init() failed\n");
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
curl_easy_setopt(c, CURLOPT_URL, URL);
|
||||
|
||||
if ((m = curl_multi_init()) == NULL) {
|
||||
fprintf(stderr, "curl_multi_init() failed\n");
|
||||
curl_easy_cleanup(c);
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if ((res = (int)curl_multi_add_handle(m, c)) != CURLM_OK) {
|
||||
fprintf(stderr, "curl_multi_add_handle() failed, "
|
||||
"with code %d\n", res);
|
||||
curl_multi_cleanup(m);
|
||||
curl_easy_cleanup(c);
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
mp_timedout = FALSE;
|
||||
mp_start = tutil_tvnow();
|
||||
|
||||
while (running) {
|
||||
res = (int)curl_multi_perform(m, &running);
|
||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
||||
mp_timedout = TRUE;
|
||||
break;
|
||||
}
|
||||
if (running <= 0) {
|
||||
fprintf(stderr, "nothing left running.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mp_timedout) {
|
||||
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
|
||||
fprintf(stderr, "ABORTING TEST, since it seems "
|
||||
"that it would have run forever.\n");
|
||||
res = TEST_ERR_RUNS_FOREVER;
|
||||
}
|
||||
|
||||
curl_multi_remove_handle(m, c);
|
||||
curl_easy_cleanup(c);
|
||||
curl_multi_cleanup(m);
|
||||
curl_global_cleanup();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib503.c,v 1.19 2008-09-20 04:26:56 yangtse Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "testutil.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
||||
#define MULTI_PERFORM_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;
|
||||
CURLM *m;
|
||||
int res = 0;
|
||||
int running;
|
||||
char done = FALSE;
|
||||
struct timeval ml_start;
|
||||
struct timeval mp_start;
|
||||
char ml_timedout = FALSE;
|
||||
char mp_timedout = FALSE;
|
||||
|
||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
||||
fprintf(stderr, "curl_global_init() failed\n");
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if ((c = curl_easy_init()) == NULL) {
|
||||
fprintf(stderr, "curl_easy_init() failed\n");
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
curl_easy_setopt(c, CURLOPT_PROXY, libtest_arg2); /* set in first.c */
|
||||
curl_easy_setopt(c, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(c, CURLOPT_USERPWD, "test:ing");
|
||||
curl_easy_setopt(c, CURLOPT_PROXYUSERPWD, "test:ing");
|
||||
curl_easy_setopt(c, CURLOPT_HTTPPROXYTUNNEL, 1L);
|
||||
curl_easy_setopt(c, CURLOPT_HEADER, 1L);
|
||||
|
||||
if ((m = curl_multi_init()) == NULL) {
|
||||
fprintf(stderr, "curl_multi_init() failed\n");
|
||||
curl_easy_cleanup(c);
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if ((res = (int)curl_multi_add_handle(m, c)) != CURLM_OK) {
|
||||
fprintf(stderr, "curl_multi_add_handle() failed, "
|
||||
"with code %d\n", res);
|
||||
curl_multi_cleanup(m);
|
||||
curl_easy_cleanup(c);
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
ml_timedout = FALSE;
|
||||
ml_start = tutil_tvnow();
|
||||
|
||||
while(!done) {
|
||||
fd_set rd, wr, exc;
|
||||
int max_fd;
|
||||
struct timeval interval;
|
||||
|
||||
interval.tv_sec = 1;
|
||||
interval.tv_usec = 0;
|
||||
|
||||
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
|
||||
MAIN_LOOP_HANG_TIMEOUT) {
|
||||
ml_timedout = TRUE;
|
||||
break;
|
||||
}
|
||||
mp_timedout = FALSE;
|
||||
mp_start = tutil_tvnow();
|
||||
|
||||
while (res == CURLM_CALL_MULTI_PERFORM) {
|
||||
res = (int)curl_multi_perform(m, &running);
|
||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
||||
mp_timedout = TRUE;
|
||||
break;
|
||||
}
|
||||
if (running <= 0) {
|
||||
done = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mp_timedout || done)
|
||||
break;
|
||||
|
||||
if (res != CURLM_OK) {
|
||||
fprintf(stderr, "not okay???\n");
|
||||
break;
|
||||
}
|
||||
|
||||
FD_ZERO(&rd);
|
||||
FD_ZERO(&wr);
|
||||
FD_ZERO(&exc);
|
||||
max_fd = 0;
|
||||
|
||||
if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
|
||||
fprintf(stderr, "unexpected failured of fdset.\n");
|
||||
res = 89;
|
||||
break;
|
||||
}
|
||||
|
||||
if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
|
||||
fprintf(stderr, "bad select??\n");
|
||||
res = 95;
|
||||
break;
|
||||
}
|
||||
|
||||
res = CURLM_CALL_MULTI_PERFORM;
|
||||
}
|
||||
|
||||
if (ml_timedout || mp_timedout) {
|
||||
if (ml_timedout) fprintf(stderr, "ml_timedout\n");
|
||||
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
|
||||
fprintf(stderr, "ABORTING TEST, since it seems "
|
||||
"that it would have run forever.\n");
|
||||
res = TEST_ERR_RUNS_FOREVER;
|
||||
}
|
||||
|
||||
curl_multi_remove_handle(m, c);
|
||||
curl_easy_cleanup(c);
|
||||
curl_multi_cleanup(m);
|
||||
curl_global_cleanup();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib504.c,v 1.28 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "testutil.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
||||
#define MULTI_PERFORM_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;
|
||||
int ret=0;
|
||||
CURLM *m;
|
||||
fd_set rd, wr, exc;
|
||||
CURLMcode res;
|
||||
char done = FALSE;
|
||||
int running;
|
||||
int max_fd;
|
||||
int rc;
|
||||
struct timeval ml_start;
|
||||
struct timeval mp_start;
|
||||
char ml_timedout = FALSE;
|
||||
char mp_timedout = FALSE;
|
||||
|
||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
||||
fprintf(stderr, "curl_global_init() failed\n");
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if ((c = curl_easy_init()) == NULL) {
|
||||
fprintf(stderr, "curl_easy_init() failed\n");
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
/* the point here being that there must not run anything on the given
|
||||
proxy port */
|
||||
curl_easy_setopt(c, CURLOPT_PROXY, libtest_arg2);
|
||||
curl_easy_setopt(c, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(c, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
if ((m = curl_multi_init()) == NULL) {
|
||||
fprintf(stderr, "curl_multi_init() failed\n");
|
||||
curl_easy_cleanup(c);
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if ((res = curl_multi_add_handle(m, c)) != CURLM_OK) {
|
||||
fprintf(stderr, "curl_multi_add_handle() failed, "
|
||||
"with code %d\n", res);
|
||||
curl_multi_cleanup(m);
|
||||
curl_easy_cleanup(c);
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
ml_timedout = FALSE;
|
||||
ml_start = tutil_tvnow();
|
||||
|
||||
while (!done) {
|
||||
struct timeval interval;
|
||||
|
||||
interval.tv_sec = 1;
|
||||
interval.tv_usec = 0;
|
||||
|
||||
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
|
||||
MAIN_LOOP_HANG_TIMEOUT) {
|
||||
ml_timedout = TRUE;
|
||||
break;
|
||||
}
|
||||
mp_timedout = FALSE;
|
||||
mp_start = tutil_tvnow();
|
||||
|
||||
fprintf(stderr, "curl_multi_perform()\n");
|
||||
|
||||
res = CURLM_CALL_MULTI_PERFORM;
|
||||
|
||||
while (res == CURLM_CALL_MULTI_PERFORM) {
|
||||
res = curl_multi_perform(m, &running);
|
||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
||||
mp_timedout = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mp_timedout)
|
||||
break;
|
||||
|
||||
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)
|
||||
ret = 100; /* this is where we should be */
|
||||
else
|
||||
ret = 99; /* not correct */
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, "running == %d, res == %d\n", running, res);
|
||||
|
||||
if (res != CURLM_OK) {
|
||||
ret = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
FD_ZERO(&rd);
|
||||
FD_ZERO(&wr);
|
||||
FD_ZERO(&exc);
|
||||
max_fd = 0;
|
||||
|
||||
fprintf(stderr, "curl_multi_fdset()\n");
|
||||
if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
|
||||
fprintf(stderr, "unexpected failured of fdset.\n");
|
||||
ret = 3;
|
||||
break;
|
||||
}
|
||||
rc = select_test(max_fd+1, &rd, &wr, &exc, &interval);
|
||||
fprintf(stderr, "select returned %d\n", rc);
|
||||
}
|
||||
|
||||
if (ml_timedout || mp_timedout) {
|
||||
if (ml_timedout) fprintf(stderr, "ml_timedout\n");
|
||||
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
|
||||
fprintf(stderr, "ABORTING TEST, since it seems "
|
||||
"that it would have run forever.\n");
|
||||
ret = TEST_ERR_RUNS_FOREVER;
|
||||
}
|
||||
|
||||
curl_multi_remove_handle(m, c);
|
||||
curl_easy_cleanup(c);
|
||||
curl_multi_cleanup(m);
|
||||
curl_global_cleanup();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib505.c,v 1.15 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#include "setup.h" /* struct_stat etc. */
|
||||
#include "test.h"
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.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;
|
||||
}
|
||||
|
||||
/* get the file size of the local file */
|
||||
hd = stat(libtest_arg2, &file_info);
|
||||
if(hd == -1) {
|
||||
/* can't open file, bail out */
|
||||
error = ERRNO;
|
||||
fprintf(stderr, "stat() failed with error: %d %s\n",
|
||||
error, strerror(error));
|
||||
fprintf(stderr, "WARNING: cannot open file %s\n", libtest_arg2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(! file_info.st_size) {
|
||||
fprintf(stderr, "WARNING: file %s has no size!\n", libtest_arg2);
|
||||
return -4;
|
||||
}
|
||||
|
||||
/* get a FILE * of the same file, could also be made with
|
||||
fdopen() from the previous descriptor, but hey this is just
|
||||
an example! */
|
||||
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 */
|
||||
}
|
||||
|
||||
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 */
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
/* enable verbose */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* specify target */
|
||||
curl_easy_setopt(curl,CURLOPT_URL, URL);
|
||||
|
||||
/* pass in that last of FTP commands to run after the transfer */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTQUOTE, headerlist);
|
||||
|
||||
/* now specify which file to upload */
|
||||
curl_easy_setopt(curl, CURLOPT_INFILE, hd_src);
|
||||
|
||||
/* and give the size of the upload (optional) */
|
||||
curl_easy_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);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib506.c,v 1.22 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.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("%s000%c", base, 48+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 );
|
||||
curl_easy_setopt( curl, CURLOPT_HTTPHEADER, headers );
|
||||
curl_easy_setopt( curl, CURLOPT_URL, url );
|
||||
printf( "CURLOPT_SHARE\n" );
|
||||
curl_easy_setopt( curl, CURLOPT_SHARE, share );
|
||||
printf( "CURLOPT_COOKIEJAR\n" );
|
||||
curl_easy_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" );
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib507.c,v 1.17 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include "testutil.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
||||
|
||||
int test(char *URL)
|
||||
{
|
||||
CURL* curls;
|
||||
CURLM* multi;
|
||||
int still_running;
|
||||
int i = -1;
|
||||
CURLMsg *msg;
|
||||
CURLMcode res;
|
||||
struct timeval ml_start;
|
||||
struct timeval mp_start;
|
||||
char ml_timedout = FALSE;
|
||||
char mp_timedout = FALSE;
|
||||
|
||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
||||
fprintf(stderr, "curl_global_init() failed\n");
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if ((multi = curl_multi_init()) == NULL) {
|
||||
fprintf(stderr, "curl_multi_init() failed\n");
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if ((curls = curl_easy_init()) == NULL) {
|
||||
fprintf(stderr, "curl_easy_init() failed\n");
|
||||
curl_multi_cleanup(multi);
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curls, CURLOPT_URL, URL);
|
||||
|
||||
if ((res = curl_multi_add_handle(multi, curls)) != CURLM_OK) {
|
||||
fprintf(stderr, "curl_multi_add_handle() failed, "
|
||||
"with code %d\n", res);
|
||||
curl_easy_cleanup(curls);
|
||||
curl_multi_cleanup(multi);
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
mp_timedout = FALSE;
|
||||
mp_start = tutil_tvnow();
|
||||
|
||||
do {
|
||||
res = curl_multi_perform(multi, &still_running);
|
||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
||||
mp_timedout = TRUE;
|
||||
break;
|
||||
}
|
||||
} while (res == CURLM_CALL_MULTI_PERFORM);
|
||||
|
||||
ml_timedout = FALSE;
|
||||
ml_start = tutil_tvnow();
|
||||
|
||||
while ((!ml_timedout) && (!mp_timedout) && (still_running)) {
|
||||
struct timeval timeout;
|
||||
int rc;
|
||||
fd_set fdread;
|
||||
fd_set fdwrite;
|
||||
fd_set fdexcep;
|
||||
int maxfd;
|
||||
|
||||
FD_ZERO(&fdread);
|
||||
FD_ZERO(&fdwrite);
|
||||
FD_ZERO(&fdexcep);
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
|
||||
MAIN_LOOP_HANG_TIMEOUT) {
|
||||
ml_timedout = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
rc = select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
switch(rc) {
|
||||
case -1:
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
mp_timedout = FALSE;
|
||||
mp_start = tutil_tvnow();
|
||||
do {
|
||||
res = curl_multi_perform(multi, &still_running);
|
||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
||||
mp_timedout = TRUE;
|
||||
break;
|
||||
}
|
||||
} while (res == CURLM_CALL_MULTI_PERFORM);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ml_timedout || mp_timedout) {
|
||||
if (ml_timedout) fprintf(stderr, "ml_timedout\n");
|
||||
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
|
||||
fprintf(stderr, "ABORTING TEST, since it seems "
|
||||
"that it would have run forever.\n");
|
||||
i = TEST_ERR_RUNS_FOREVER;
|
||||
}
|
||||
else {
|
||||
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;
|
||||
}
|
||||
|
||||
curl_multi_cleanup(multi);
|
||||
curl_easy_cleanup(curls);
|
||||
curl_global_cleanup();
|
||||
|
||||
return i; /* return the final return code */
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib508.c,v 1.8 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#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. */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
|
||||
/* Now specify we want to POST data */
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||
|
||||
/* Set the expected POST size */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)pooh.sizeleft);
|
||||
|
||||
/* we want to use our own read function */
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
|
||||
/* pointer to pass to our read function */
|
||||
curl_easy_setopt(curl, CURLOPT_INFILE, &pooh);
|
||||
|
||||
/* get verbose debug output please */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* include headers in the output */
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib510.c,v 1.7 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#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. */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
|
||||
/* Now specify we want to POST data */
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||
|
||||
/* we want to use our own read function */
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
|
||||
/* pointer to pass to our read function */
|
||||
curl_easy_setopt(curl, CURLOPT_INFILE, &pooh);
|
||||
|
||||
/* get verbose debug output please */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* include headers in the output */
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
|
||||
|
||||
/* enforce chunked transfer by setting the header */
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* clean up the headers list */
|
||||
if(slist)
|
||||
curl_slist_free_all(slist);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib511.c,v 1.7 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(curl, CURLOPT_FILETIME, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib512.c,v 1.6 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib513.c,v 1.5 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#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. */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
|
||||
/* Now specify we want to POST data */
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||
|
||||
/* Set the expected POST size */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 1L);
|
||||
|
||||
/* we want to use our own read function */
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
|
||||
/* pointer to pass to our read function */
|
||||
curl_easy_setopt(curl, CURLOPT_INFILE, NULL);
|
||||
|
||||
/* get verbose debug output please */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* include headers in the output */
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib514.c,v 1.5 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#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. */
|
||||
curl_easy_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'.
|
||||
|
||||
*/
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "moo");
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 3L);
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||
|
||||
/* this is where transfer 1 would take place, but skip that and change
|
||||
options right away instead */
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); /* show verbose for debug */
|
||||
curl_easy_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);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib515.c,v 1.5 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#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. */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, NULL);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); /* show verbose for debug */
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 1L); /* include header */
|
||||
|
||||
/* Now, we should be making a zero byte POST request */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib516.c,v 1.5 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#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. */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPPOST, NULL);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); /* show verbose for debug */
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 1L); /* include header */
|
||||
|
||||
/* Now, we should be making a zero byte POST request */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib517.c,v 1.6 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include "memdebug.h"
|
||||
|
||||
static const char *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 */
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,508 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib518.c,v 1.36 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#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
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
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) */
|
||||
@@ -0,0 +1,49 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib519.c,v 1.5 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(curl, CURLOPT_USERPWD, "monster:underbed");
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* get first page */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_USERPWD, "anothermonster:inwardrobe");
|
||||
|
||||
/* get second page */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib520.c,v 1.5 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(curl, CURLOPT_FILETIME, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib521.c,v 1.6 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(curl, CURLOPT_PORT, atoi(libtest_arg2));
|
||||
curl_easy_setopt(curl, CURLOPT_USERPWD, "xxx:yyy");
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib523.c,v 1.6 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_PROXY, libtest_arg2);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(curl, CURLOPT_PORT, 19999L);
|
||||
curl_easy_setopt(curl, CURLOPT_USERPWD, "xxx:yyy");
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib524.c,v 1.5 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib525.c,v 1.19 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "testutil.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
||||
|
||||
int test(char *URL)
|
||||
{
|
||||
int res = 0;
|
||||
CURL *curl;
|
||||
FILE *hd_src ;
|
||||
int hd ;
|
||||
int error;
|
||||
struct_stat file_info;
|
||||
int running;
|
||||
char done=FALSE;
|
||||
CURLM *m;
|
||||
struct timeval ml_start;
|
||||
struct timeval mp_start;
|
||||
char ml_timedout = FALSE;
|
||||
char mp_timedout = FALSE;
|
||||
|
||||
if (!libtest_arg2) {
|
||||
fprintf(stderr, "Usage: lib525 [url] [uploadfile]\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get the file size of the local file */
|
||||
hd = open(libtest_arg2, O_RDONLY) ;
|
||||
fstat(hd, &file_info);
|
||||
close(hd) ;
|
||||
|
||||
/* get a FILE * of the same file, could also be made with
|
||||
fdopen() from the previous descriptor, but hey this is just
|
||||
an example! */
|
||||
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_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
||||
fprintf(stderr, "curl_global_init() failed\n");
|
||||
fclose(hd_src);
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if ((curl = curl_easy_init()) == NULL) {
|
||||
fprintf(stderr, "curl_easy_init() failed\n");
|
||||
fclose(hd_src);
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
/* enable uploading */
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
/* specify target */
|
||||
curl_easy_setopt(curl,CURLOPT_URL, URL);
|
||||
|
||||
/* go verbose */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* use active FTP */
|
||||
curl_easy_setopt(curl, CURLOPT_FTPPORT, "-");
|
||||
|
||||
/* now specify which file to upload */
|
||||
curl_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. */
|
||||
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
|
||||
(curl_off_t)file_info.st_size);
|
||||
|
||||
if ((m = curl_multi_init()) == NULL) {
|
||||
fprintf(stderr, "curl_multi_init() failed\n");
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
fclose(hd_src);
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if ((res = (int)curl_multi_add_handle(m, curl)) != CURLM_OK) {
|
||||
fprintf(stderr, "curl_multi_add_handle() failed, "
|
||||
"with code %d\n", res);
|
||||
curl_multi_cleanup(m);
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
fclose(hd_src);
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
ml_timedout = FALSE;
|
||||
ml_start = tutil_tvnow();
|
||||
|
||||
while (!done) {
|
||||
fd_set rd, wr, exc;
|
||||
int max_fd;
|
||||
struct timeval interval;
|
||||
|
||||
interval.tv_sec = 1;
|
||||
interval.tv_usec = 0;
|
||||
|
||||
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
|
||||
MAIN_LOOP_HANG_TIMEOUT) {
|
||||
ml_timedout = TRUE;
|
||||
break;
|
||||
}
|
||||
mp_timedout = FALSE;
|
||||
mp_start = tutil_tvnow();
|
||||
|
||||
while (res == CURLM_CALL_MULTI_PERFORM) {
|
||||
res = (int)curl_multi_perform(m, &running);
|
||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
||||
mp_timedout = TRUE;
|
||||
break;
|
||||
}
|
||||
if (running <= 0) {
|
||||
done = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mp_timedout || done)
|
||||
break;
|
||||
|
||||
if (res != CURLM_OK) {
|
||||
fprintf(stderr, "not okay???\n");
|
||||
break;
|
||||
}
|
||||
|
||||
FD_ZERO(&rd);
|
||||
FD_ZERO(&wr);
|
||||
FD_ZERO(&exc);
|
||||
max_fd = 0;
|
||||
|
||||
if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
|
||||
fprintf(stderr, "unexpected failured of fdset.\n");
|
||||
res = 189;
|
||||
break;
|
||||
}
|
||||
|
||||
if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
|
||||
fprintf(stderr, "bad select??\n");
|
||||
res = 195;
|
||||
break;
|
||||
}
|
||||
|
||||
res = CURLM_CALL_MULTI_PERFORM;
|
||||
}
|
||||
|
||||
if (ml_timedout || mp_timedout) {
|
||||
if (ml_timedout) fprintf(stderr, "ml_timedout\n");
|
||||
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
|
||||
fprintf(stderr, "ABORTING TEST, since it seems "
|
||||
"that it would have run forever.\n");
|
||||
res = TEST_ERR_RUNS_FOREVER;
|
||||
}
|
||||
|
||||
#ifdef LIB529
|
||||
/* test 529 */
|
||||
curl_multi_remove_handle(m, curl);
|
||||
curl_multi_cleanup(m);
|
||||
curl_easy_cleanup(curl);
|
||||
#else
|
||||
/* test 525 */
|
||||
curl_multi_remove_handle(m, curl);
|
||||
curl_easy_cleanup(curl);
|
||||
curl_multi_cleanup(m);
|
||||
#endif
|
||||
|
||||
fclose(hd_src); /* close the local file */
|
||||
|
||||
curl_global_cleanup();
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib526.c,v 1.15 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "testutil.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
||||
|
||||
#define NUM_HANDLES 4
|
||||
|
||||
int test(char *URL)
|
||||
{
|
||||
int res = 0;
|
||||
CURL *curl[NUM_HANDLES];
|
||||
int running;
|
||||
char done=FALSE;
|
||||
CURLM *m;
|
||||
int current=0;
|
||||
int i, j;
|
||||
struct timeval ml_start;
|
||||
struct timeval mp_start;
|
||||
char ml_timedout = FALSE;
|
||||
char mp_timedout = FALSE;
|
||||
|
||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
||||
fprintf(stderr, "curl_global_init() failed\n");
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
/* get NUM_HANDLES easy handles */
|
||||
for(i=0; i < NUM_HANDLES; i++) {
|
||||
curl[i] = curl_easy_init();
|
||||
if(!curl[i]) {
|
||||
fprintf(stderr, "curl_easy_init() failed "
|
||||
"on handle #%d\n", i);
|
||||
for (j=i-1; j >= 0; j--) {
|
||||
curl_easy_cleanup(curl[j]);
|
||||
}
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD + i;
|
||||
}
|
||||
curl_easy_setopt(curl[i], CURLOPT_URL, URL);
|
||||
|
||||
/* go verbose */
|
||||
curl_easy_setopt(curl[i], CURLOPT_VERBOSE, 1L);
|
||||
}
|
||||
|
||||
if ((m = curl_multi_init()) == NULL) {
|
||||
fprintf(stderr, "curl_multi_init() failed\n");
|
||||
for(i=0; i < NUM_HANDLES; i++) {
|
||||
curl_easy_cleanup(curl[i]);
|
||||
}
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if ((res = (int)curl_multi_add_handle(m, curl[current])) != CURLM_OK) {
|
||||
fprintf(stderr, "curl_multi_add_handle() failed, "
|
||||
"with code %d\n", res);
|
||||
curl_multi_cleanup(m);
|
||||
for(i=0; i < NUM_HANDLES; i++) {
|
||||
curl_easy_cleanup(curl[i]);
|
||||
}
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
ml_timedout = FALSE;
|
||||
ml_start = tutil_tvnow();
|
||||
|
||||
fprintf(stderr, "Start at URL 0\n");
|
||||
|
||||
while (!done) {
|
||||
fd_set rd, wr, exc;
|
||||
int max_fd;
|
||||
struct timeval interval;
|
||||
|
||||
interval.tv_sec = 1;
|
||||
interval.tv_usec = 0;
|
||||
|
||||
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
|
||||
MAIN_LOOP_HANG_TIMEOUT) {
|
||||
ml_timedout = TRUE;
|
||||
break;
|
||||
}
|
||||
mp_timedout = FALSE;
|
||||
mp_start = tutil_tvnow();
|
||||
|
||||
while (res == CURLM_CALL_MULTI_PERFORM) {
|
||||
res = (int)curl_multi_perform(m, &running);
|
||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
||||
mp_timedout = TRUE;
|
||||
break;
|
||||
}
|
||||
if (running <= 0) {
|
||||
#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]);
|
||||
#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]);
|
||||
curl_easy_setopt(curl[0], CURLOPT_URL, URL);
|
||||
curl_easy_setopt(curl[0], CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* re-add it */
|
||||
res = (int)curl_multi_add_handle(m, curl[0]);
|
||||
#else
|
||||
res = (int)curl_multi_add_handle(m, curl[current]);
|
||||
#endif
|
||||
if(res) {
|
||||
fprintf(stderr, "add handle failed: %d.\n", res);
|
||||
res = 243;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
done = TRUE; /* bail out */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mp_timedout || done)
|
||||
break;
|
||||
|
||||
if (res != CURLM_OK) {
|
||||
fprintf(stderr, "not okay???\n");
|
||||
break;
|
||||
}
|
||||
|
||||
FD_ZERO(&rd);
|
||||
FD_ZERO(&wr);
|
||||
FD_ZERO(&exc);
|
||||
max_fd = 0;
|
||||
|
||||
if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
|
||||
fprintf(stderr, "unexpected failured of fdset.\n");
|
||||
res = 189;
|
||||
break;
|
||||
}
|
||||
|
||||
if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
|
||||
fprintf(stderr, "bad select??\n");
|
||||
res = 195;
|
||||
break;
|
||||
}
|
||||
|
||||
res = CURLM_CALL_MULTI_PERFORM;
|
||||
}
|
||||
|
||||
if (ml_timedout || mp_timedout) {
|
||||
if (ml_timedout) fprintf(stderr, "ml_timedout\n");
|
||||
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
|
||||
fprintf(stderr, "ABORTING TEST, since it seems "
|
||||
"that it would have run forever.\n");
|
||||
res = TEST_ERR_RUNS_FOREVER;
|
||||
}
|
||||
|
||||
#ifndef LIB527
|
||||
/* get NUM_HANDLES easy handles */
|
||||
for(i=0; i < NUM_HANDLES; i++) {
|
||||
#ifdef LIB526
|
||||
curl_multi_remove_handle(m, curl[i]);
|
||||
#endif
|
||||
curl_easy_cleanup(curl[i]);
|
||||
}
|
||||
#endif
|
||||
curl_multi_cleanup(m);
|
||||
|
||||
curl_global_cleanup();
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib530.c,v 1.18 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include "testutil.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
||||
|
||||
#define NUM_HANDLES 4
|
||||
|
||||
int test(char *URL)
|
||||
{
|
||||
int res = 0;
|
||||
CURL *curl[NUM_HANDLES];
|
||||
int running;
|
||||
char done=FALSE;
|
||||
CURLM *m;
|
||||
int i, j;
|
||||
struct timeval ml_start;
|
||||
struct timeval mp_start;
|
||||
char ml_timedout = FALSE;
|
||||
char mp_timedout = FALSE;
|
||||
char target_url[256];
|
||||
|
||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
||||
fprintf(stderr, "curl_global_init() failed\n");
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if ((m = curl_multi_init()) == NULL) {
|
||||
fprintf(stderr, "curl_multi_init() failed\n");
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
/* get NUM_HANDLES easy handles */
|
||||
for(i=0; i < NUM_HANDLES; i++) {
|
||||
curl[i] = curl_easy_init();
|
||||
if(!curl[i]) {
|
||||
fprintf(stderr, "curl_easy_init() failed "
|
||||
"on handle #%d\n", i);
|
||||
for (j=i-1; j >= 0; j--) {
|
||||
curl_multi_remove_handle(m, curl[j]);
|
||||
curl_easy_cleanup(curl[j]);
|
||||
}
|
||||
curl_multi_cleanup(m);
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD + i;
|
||||
}
|
||||
sprintf(target_url, "%s%04i", URL, i + 1);
|
||||
target_url[sizeof(target_url) - 1] = '\0';
|
||||
curl_easy_setopt(curl[i], CURLOPT_URL, target_url);
|
||||
|
||||
/* go verbose */
|
||||
curl_easy_setopt(curl[i], CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* include headers */
|
||||
curl_easy_setopt(curl[i], CURLOPT_HEADER, 1L);
|
||||
|
||||
/* add handle to multi */
|
||||
if ((res = (int)curl_multi_add_handle(m, curl[i])) != CURLM_OK) {
|
||||
fprintf(stderr, "curl_multi_add_handle() failed, "
|
||||
"on handle #%d with code %d\n", i, res);
|
||||
curl_easy_cleanup(curl[i]);
|
||||
for (j=i-1; j >= 0; j--) {
|
||||
curl_multi_remove_handle(m, curl[j]);
|
||||
curl_easy_cleanup(curl[j]);
|
||||
}
|
||||
curl_multi_cleanup(m);
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD + i;
|
||||
}
|
||||
}
|
||||
|
||||
curl_multi_setopt(m, CURLMOPT_PIPELINING, 1L);
|
||||
|
||||
ml_timedout = FALSE;
|
||||
ml_start = tutil_tvnow();
|
||||
|
||||
fprintf(stderr, "Start at URL 0\n");
|
||||
|
||||
while (!done) {
|
||||
fd_set rd, wr, exc;
|
||||
int max_fd;
|
||||
struct timeval interval;
|
||||
|
||||
interval.tv_sec = 1;
|
||||
interval.tv_usec = 0;
|
||||
|
||||
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
|
||||
MAIN_LOOP_HANG_TIMEOUT) {
|
||||
ml_timedout = TRUE;
|
||||
break;
|
||||
}
|
||||
mp_timedout = FALSE;
|
||||
mp_start = tutil_tvnow();
|
||||
|
||||
while (res == CURLM_CALL_MULTI_PERFORM) {
|
||||
res = (int)curl_multi_perform(m, &running);
|
||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
||||
mp_timedout = TRUE;
|
||||
break;
|
||||
}
|
||||
if (running <= 0) {
|
||||
done = TRUE; /* bail out */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mp_timedout || done)
|
||||
break;
|
||||
|
||||
if (res != CURLM_OK) {
|
||||
fprintf(stderr, "not okay???\n");
|
||||
break;
|
||||
}
|
||||
|
||||
FD_ZERO(&rd);
|
||||
FD_ZERO(&wr);
|
||||
FD_ZERO(&exc);
|
||||
max_fd = 0;
|
||||
|
||||
if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
|
||||
fprintf(stderr, "unexpected failured of fdset.\n");
|
||||
res = 189;
|
||||
break;
|
||||
}
|
||||
|
||||
if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
|
||||
fprintf(stderr, "bad select??\n");
|
||||
res = 195;
|
||||
break;
|
||||
}
|
||||
|
||||
res = CURLM_CALL_MULTI_PERFORM;
|
||||
}
|
||||
|
||||
if (ml_timedout || mp_timedout) {
|
||||
if (ml_timedout) fprintf(stderr, "ml_timedout\n");
|
||||
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
|
||||
fprintf(stderr, "ABORTING TEST, since it seems "
|
||||
"that it would have run forever.\n");
|
||||
res = TEST_ERR_RUNS_FOREVER;
|
||||
}
|
||||
|
||||
/* cleanup NUM_HANDLES easy handles */
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib533.c,v 1.16 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
/* used for test case 533, 534 and 535 */
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "testutil.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
||||
|
||||
int test(char *URL)
|
||||
{
|
||||
int res = 0;
|
||||
CURL *curl;
|
||||
int running;
|
||||
char done=FALSE;
|
||||
CURLM *m;
|
||||
int current=0;
|
||||
struct timeval ml_start;
|
||||
struct timeval mp_start;
|
||||
char ml_timedout = FALSE;
|
||||
char mp_timedout = FALSE;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
|
||||
|
||||
if ((m = curl_multi_init()) == NULL) {
|
||||
fprintf(stderr, "curl_multi_init() failed\n");
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if ((res = (int)curl_multi_add_handle(m, curl)) != CURLM_OK) {
|
||||
fprintf(stderr, "curl_multi_add_handle() failed, "
|
||||
"with code %d\n", res);
|
||||
curl_multi_cleanup(m);
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
ml_timedout = FALSE;
|
||||
ml_start = tutil_tvnow();
|
||||
|
||||
fprintf(stderr, "Start at URL 0\n");
|
||||
|
||||
while (!done) {
|
||||
fd_set rd, wr, exc;
|
||||
int max_fd;
|
||||
struct timeval interval;
|
||||
|
||||
interval.tv_sec = 1;
|
||||
interval.tv_usec = 0;
|
||||
|
||||
if (tutil_tvdiff(tutil_tvnow(), ml_start) >
|
||||
MAIN_LOOP_HANG_TIMEOUT) {
|
||||
ml_timedout = TRUE;
|
||||
break;
|
||||
}
|
||||
mp_timedout = FALSE;
|
||||
mp_start = tutil_tvnow();
|
||||
|
||||
while (res == CURLM_CALL_MULTI_PERFORM) {
|
||||
res = (int)curl_multi_perform(m, &running);
|
||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
||||
mp_timedout = TRUE;
|
||||
break;
|
||||
}
|
||||
if (running <= 0) {
|
||||
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);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, libtest_arg2);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
|
||||
|
||||
/* re-add it */
|
||||
res = (int)curl_multi_add_handle(m, curl);
|
||||
if(res) {
|
||||
fprintf(stderr, "add handle failed: %d.\n", res);
|
||||
res = 243;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
done = TRUE; /* bail out */
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (mp_timedout || done)
|
||||
break;
|
||||
|
||||
if (res != CURLM_OK) {
|
||||
fprintf(stderr, "not okay???\n");
|
||||
break;
|
||||
}
|
||||
|
||||
FD_ZERO(&rd);
|
||||
FD_ZERO(&wr);
|
||||
FD_ZERO(&exc);
|
||||
max_fd = 0;
|
||||
|
||||
if (curl_multi_fdset(m, &rd, &wr, &exc, &max_fd) != CURLM_OK) {
|
||||
fprintf(stderr, "unexpected failured of fdset.\n");
|
||||
res = 189;
|
||||
break;
|
||||
}
|
||||
|
||||
if (select_test(max_fd+1, &rd, &wr, &exc, &interval) == -1) {
|
||||
fprintf(stderr, "bad select??\n");
|
||||
res = 195;
|
||||
break;
|
||||
}
|
||||
|
||||
res = CURLM_CALL_MULTI_PERFORM;
|
||||
}
|
||||
|
||||
if (ml_timedout || mp_timedout) {
|
||||
if (ml_timedout) fprintf(stderr, "ml_timedout\n");
|
||||
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
|
||||
fprintf(stderr, "ABORTING TEST, since it seems "
|
||||
"that it would have run forever.\n");
|
||||
res = TEST_ERR_RUNS_FOREVER;
|
||||
}
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
curl_multi_cleanup(m);
|
||||
curl_global_cleanup();
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib536.c,v 1.14 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "testutil.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
#define MAIN_LOOP_HANG_TIMEOUT 90 * 1000
|
||||
#define MULTI_PERFORM_HANG_TIMEOUT 60 * 1000
|
||||
|
||||
static CURLMcode perform(CURLM * multi)
|
||||
{
|
||||
int handles, maxfd;
|
||||
CURLMcode code;
|
||||
fd_set fdread, fdwrite, fdexcep;
|
||||
struct timeval mp_start;
|
||||
char mp_timedout = FALSE;
|
||||
|
||||
mp_timedout = FALSE;
|
||||
mp_start = tutil_tvnow();
|
||||
|
||||
for (;;) {
|
||||
code = curl_multi_perform(multi, &handles);
|
||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
||||
mp_timedout = TRUE;
|
||||
break;
|
||||
}
|
||||
if (handles <= 0)
|
||||
return CURLM_OK;
|
||||
|
||||
switch (code) {
|
||||
case CURLM_OK:
|
||||
break;
|
||||
case CURLM_CALL_MULTI_PERFORM:
|
||||
continue;
|
||||
default:
|
||||
return code;
|
||||
}
|
||||
|
||||
FD_ZERO(&fdread);
|
||||
FD_ZERO(&fdwrite);
|
||||
FD_ZERO(&fdexcep);
|
||||
curl_multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
if (maxfd < 0)
|
||||
return (CURLMcode) ~CURLM_OK;
|
||||
if (select(maxfd + 1, &fdread, &fdwrite, &fdexcep, 0) == -1)
|
||||
return (CURLMcode) ~CURLM_OK;
|
||||
}
|
||||
|
||||
/* We only reach this point if (mp_timedout) */
|
||||
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
|
||||
fprintf(stderr, "ABORTING TEST, since it seems "
|
||||
"that it would have run forever.\n");
|
||||
return (CURLMcode) ~CURLM_OK;
|
||||
}
|
||||
|
||||
int test(char *URL)
|
||||
{
|
||||
CURLM *multi;
|
||||
CURL *easy;
|
||||
int res = 0;
|
||||
|
||||
if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
|
||||
fprintf(stderr, "curl_global_init() failed\n");
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if ((multi = curl_multi_init()) == NULL) {
|
||||
fprintf(stderr, "curl_multi_init() failed\n");
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if ((easy = curl_easy_init()) == NULL) {
|
||||
fprintf(stderr, "curl_easy_init() failed\n");
|
||||
curl_multi_cleanup(multi);
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
curl_multi_setopt(multi, CURLMOPT_PIPELINING, 1L);
|
||||
|
||||
curl_easy_setopt(easy, CURLOPT_WRITEFUNCTION, fwrite);
|
||||
curl_easy_setopt(easy, CURLOPT_FAILONERROR, 1L);
|
||||
curl_easy_setopt(easy, CURLOPT_URL, URL);
|
||||
|
||||
if (curl_multi_add_handle(multi, easy) != CURLM_OK) {
|
||||
printf("curl_multi_add_handle() failed\n");
|
||||
res = TEST_ERR_MAJOR_BAD;
|
||||
} else {
|
||||
if (perform(multi) != CURLM_OK)
|
||||
printf("retrieve 1 failed\n");
|
||||
|
||||
curl_multi_remove_handle(multi, easy);
|
||||
}
|
||||
curl_easy_reset(easy);
|
||||
|
||||
curl_easy_setopt(easy, CURLOPT_FAILONERROR, 1L);
|
||||
curl_easy_setopt(easy, CURLOPT_URL, libtest_arg2);
|
||||
|
||||
if (curl_multi_add_handle(multi, easy) != CURLM_OK) {
|
||||
printf("curl_multi_add_handle() 2 failed\n");
|
||||
res = TEST_ERR_MAJOR_BAD;
|
||||
} else {
|
||||
if (perform(multi) != CURLM_OK)
|
||||
printf("retrieve 2 failed\n");
|
||||
|
||||
curl_multi_remove_handle(multi, easy);
|
||||
}
|
||||
curl_easy_cleanup(easy);
|
||||
curl_multi_cleanup(multi);
|
||||
curl_global_cleanup();
|
||||
|
||||
printf("Finished!\n");
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,511 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib537.c,v 1.21 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#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
|
||||
#ifdef HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
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) */
|
||||
@@ -0,0 +1,78 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib539.c,v 1.3 2008-09-22 17:20:29 danf Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include "memdebug.h"
|
||||
|
||||
int test(char *URL)
|
||||
{
|
||||
CURLcode res;
|
||||
CURL *curl;
|
||||
char *newURL;
|
||||
struct curl_slist *slist;
|
||||
|
||||
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.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_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;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, newURL);
|
||||
curl_easy_setopt(curl, CURLOPT_FTP_FILEMETHOD, (long) CURLFTPMETHOD_NOCWD);
|
||||
curl_easy_setopt(curl, CURLOPT_QUOTE, slist);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
curl_slist_free_all(slist);
|
||||
free(newURL);
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib540.c,v 1.7 2008-09-20 04:26:57 yangtse Exp $
|
||||
*
|
||||
* 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"
|
||||
|
||||
#include "memdebug.h"
|
||||
|
||||
#define PROXY libtest_arg2
|
||||
#define PROXYUSERPWD libtest_arg3
|
||||
#define HOST test_argv[4]
|
||||
|
||||
static void init(CURLM *cm, const char* url, const char* userpwd,
|
||||
struct curl_slist *headers)
|
||||
{
|
||||
CURL *eh = curl_easy_init();
|
||||
|
||||
curl_easy_setopt(eh, CURLOPT_URL, url);
|
||||
curl_easy_setopt(eh, CURLOPT_PROXY, PROXY);
|
||||
curl_easy_setopt(eh, CURLOPT_PROXYUSERPWD, userpwd);
|
||||
curl_easy_setopt(eh, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY);
|
||||
curl_easy_setopt(eh, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(eh, CURLOPT_HEADER, 1L);
|
||||
curl_easy_setopt(eh, CURLOPT_HTTPHEADER, headers); /* custom Host: */
|
||||
|
||||
curl_multi_add_handle(cm, eh);
|
||||
}
|
||||
|
||||
static int loop(CURLM *cm, const char* url, const char* userpwd,
|
||||
struct curl_slist *headers)
|
||||
{
|
||||
CURLMsg *msg;
|
||||
long L;
|
||||
int M, Q, U = -1;
|
||||
fd_set R, W, E;
|
||||
struct timeval T;
|
||||
|
||||
init(cm, url, userpwd, headers);
|
||||
|
||||
while (U) {
|
||||
while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(cm, &U));
|
||||
|
||||
if (U) {
|
||||
FD_ZERO(&R);
|
||||
FD_ZERO(&W);
|
||||
FD_ZERO(&E);
|
||||
|
||||
if (curl_multi_fdset(cm, &R, &W, &E, &M)) {
|
||||
fprintf(stderr, "E: curl_multi_fdset\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
/* In a real-world program you OF COURSE check the return that maxfd is
|
||||
bigger than -1 so that the call to select() below makes sense! */
|
||||
|
||||
if (curl_multi_timeout(cm, &L)) {
|
||||
fprintf(stderr, "E: curl_multi_timeout\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if(L != -1) {
|
||||
T.tv_sec = L/1000;
|
||||
T.tv_usec = (L%1000)*1000;
|
||||
}
|
||||
else {
|
||||
T.tv_sec = 5;
|
||||
T.tv_usec = 0;
|
||||
}
|
||||
|
||||
if (0 > select(M+1, &R, &W, &E, &T)) {
|
||||
fprintf(stderr, "E: select\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
while ((msg = curl_multi_info_read(cm, &Q))) {
|
||||
if (msg->msg == CURLMSG_DONE) {
|
||||
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);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "E: CURLMsg (%d)\n", (int)msg->msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int test(char *URL)
|
||||
{
|
||||
CURLM *cm;
|
||||
struct curl_slist *headers = NULL;
|
||||
char buffer[246]; /* naively fixed-size */
|
||||
|
||||
if(test_argc < 4)
|
||||
return 99;
|
||||
|
||||
sprintf(buffer, "Host: %s", HOST);
|
||||
|
||||
/* now add a custom Host: header */
|
||||
headers = curl_slist_append(headers, buffer);
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
cm = curl_multi_init();
|
||||
loop(cm, URL, PROXYUSERPWD, headers);
|
||||
|
||||
fprintf(stderr, "lib540: now we do the request again\n");
|
||||
loop(cm, URL, PROXYUSERPWD, headers);
|
||||
|
||||
curl_multi_cleanup(cm);
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
curl_slist_free_all(headers);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib541.c,v 1.4 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#include "setup.h" /* struct_stat etc. */
|
||||
#include "test.h"
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.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;
|
||||
}
|
||||
|
||||
/* get the file size of the local file */
|
||||
hd = stat(libtest_arg2, &file_info);
|
||||
if(hd == -1) {
|
||||
/* can't open file, bail out */
|
||||
error = ERRNO;
|
||||
fprintf(stderr, "stat() failed with error: %d %s\n",
|
||||
error, strerror(error));
|
||||
fprintf(stderr, "WARNING: cannot open file %s\n", libtest_arg2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(! file_info.st_size) {
|
||||
fprintf(stderr, "WARNING: file %s has no size!\n", libtest_arg2);
|
||||
return -4;
|
||||
}
|
||||
|
||||
/* get a FILE * of the same file, could also be made with
|
||||
fdopen() from the previous descriptor, but hey this is just
|
||||
an example! */
|
||||
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 */
|
||||
}
|
||||
|
||||
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 */
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
/* enable verbose */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* specify target */
|
||||
curl_easy_setopt(curl,CURLOPT_URL, URL);
|
||||
|
||||
/* now specify which file to upload */
|
||||
curl_easy_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);
|
||||
|
||||
/* close the local file */
|
||||
fclose(hd_src);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib542.c,v 1.4 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#include "setup.h" /* struct_stat etc. */
|
||||
#include "test.h"
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.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 */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* enable NOBODY */
|
||||
curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
|
||||
|
||||
/* disable HEADER */
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 0L);
|
||||
|
||||
/* specify target */
|
||||
curl_easy_setopt(curl,CURLOPT_URL, URL);
|
||||
|
||||
/* Now run off and do what you've been told! */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib543.c,v 1.2 2008-09-20 04:26:57 yangtse Exp $
|
||||
*
|
||||
* Based on Alex Fishman's bug report on September 30, 2007
|
||||
*/
|
||||
|
||||
#include "setup.h"
|
||||
#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 = curl_easy_init();
|
||||
char* s = curl_easy_escape(easy, (char*)a, sizeof(a));
|
||||
(void)URL;
|
||||
|
||||
printf("%s\n", s);
|
||||
|
||||
curl_free(s);
|
||||
curl_easy_cleanup(easy);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib544.c,v 1.3 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include "memdebug.h"
|
||||
|
||||
static char teststring[] =
|
||||
"This\0 is test binary data with an embedded NUL byte\n";
|
||||
|
||||
|
||||
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. */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
|
||||
#ifdef LIB545
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) sizeof teststring - 1);
|
||||
#endif
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_COPYPOSTFIELDS, teststring);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); /* show verbose for debug */
|
||||
curl_easy_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);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib547.c,v 1.6 2008-09-20 04:26:57 yangtse Exp $
|
||||
*
|
||||
* argv1 = URL
|
||||
* argv2 = proxy
|
||||
* argv3 = proxyuser:password
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#include "memdebug.h"
|
||||
|
||||
#define UPLOADTHIS "this is the blurb we want to upload\n"
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
|
||||
#ifdef LIB548
|
||||
/* set the data to POST with a mere pointer to a zero-terminated string */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, UPLOADTHIS);
|
||||
#else
|
||||
/* 547 style, which means reading the POST data from a callback */
|
||||
curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctlcallback);
|
||||
curl_easy_setopt(curl, CURLOPT_IOCTLDATA, &counter);
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, readcallback);
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, &counter);
|
||||
/* We CANNOT do the POST fine without setting the size (or choose chunked)! */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(UPLOADTHIS));
|
||||
#endif
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_PROXY, libtest_arg2);
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, libtest_arg3);
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYAUTH,
|
||||
(long) (CURLAUTH_NTLM | CURLAUTH_DIGEST | CURLAUTH_BASIC) );
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib549.c,v 1.3 2008-09-20 04:26:57 yangtse Exp $
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_PROXY, libtest_arg2);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(curl, CURLOPT_PROXY_TRANSFER_MODE, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
if(libtest_arg3)
|
||||
/* enable ascii/text mode */
|
||||
curl_easy_setopt(curl, CURLOPT_TRANSFERTEXT, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib552.c,v 1.7 2008-09-20 04:26:57 yangtse Exp $
|
||||
*
|
||||
* argv1 = URL
|
||||
* argv2 = proxy with embedded user+password
|
||||
*/
|
||||
|
||||
#include "test.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)
|
||||
{
|
||||
printf("%.*s", (int)(size * nmemb), (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 */
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_DEBUGFUNCTION, my_trace);
|
||||
curl_easy_setopt(curl, CURLOPT_DEBUGDATA, &config);
|
||||
/* the DEBUGFUNCTION has no effect until we enable VERBOSE */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* setup repeated data string */
|
||||
for (i=0; i < sizeof(databuf); ++i)
|
||||
databuf[i] = fill[i % sizeof fill];
|
||||
|
||||
/* Post */
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||
|
||||
/* Setup read callback */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long) sizeof(databuf));
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
|
||||
/* Write callback */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
|
||||
|
||||
/* Ioctl function */
|
||||
curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctl_callback);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_PROXY, libtest_arg2);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
|
||||
/* Accept any auth. But for this bug configure proxy with DIGEST, basic might work too, not NTLM */
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
fprintf(stderr, "curl_easy_perform = %d\n", (int)res);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
curl_global_cleanup();
|
||||
return (int)res;
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib553.c,v 1.5 2008-10-01 17:34:25 danf Exp $
|
||||
*
|
||||
* 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;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
curl = curl_easy_init();
|
||||
|
||||
if(curl) {
|
||||
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 errout;
|
||||
headerlist = hl;
|
||||
}
|
||||
hl = curl_slist_append(headerlist, "Expect: ");
|
||||
if (!hl)
|
||||
goto errout;
|
||||
headerlist = hl;
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)POSTLEN);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, myreadfunc);
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
errout:
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
curl_slist_free_all(headerlist);
|
||||
}
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib554.c,v 1.5 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#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;
|
||||
CURLFORMcode formrc;
|
||||
|
||||
struct curl_httppost *formpost=NULL;
|
||||
struct curl_httppost *lastptr=NULL;
|
||||
struct WriteThis pooh;
|
||||
|
||||
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, pooh.sizeleft,
|
||||
CURLFORM_FILENAME, "postit2.c",
|
||||
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",
|
||||
CURLFORM_COPYCONTENTS, "postit2.c",
|
||||
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",
|
||||
CURLFORM_COPYCONTENTS, "send",
|
||||
CURLFORM_END);
|
||||
|
||||
if(formrc)
|
||||
printf("curl_formadd(3) = %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. */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
|
||||
/* Now specify we want to POST data */
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||
|
||||
/* Set the expected POST size */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)pooh.sizeleft);
|
||||
|
||||
/* we want to use our own read function */
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
|
||||
/* pointer to pass to our read function */
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, &pooh);
|
||||
|
||||
/* send a multi-part formpost */
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
|
||||
|
||||
/* get verbose debug output please */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* include headers in the output */
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
/* now cleanup the formpost chain */
|
||||
curl_formfree(formpost);
|
||||
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib555.c,v 1.4 2008-09-20 04:26:57 yangtse Exp $
|
||||
*
|
||||
* 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 "memdebug.h"
|
||||
|
||||
#define MULTI_PERFORM_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;
|
||||
CURL *curl;
|
||||
int counter=0;
|
||||
CURLM *m;
|
||||
int running=1;
|
||||
struct timeval mp_start;
|
||||
char mp_timedout = FALSE;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
|
||||
|
||||
/* read the POST data from a callback */
|
||||
curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, ioctlcallback);
|
||||
curl_easy_setopt(curl, CURLOPT_IOCTLDATA, &counter);
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, readcallback);
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, &counter);
|
||||
/* We CANNOT do the POST fine without setting the size (or choose chunked)! */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, strlen(UPLOADTHIS));
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_PROXY, libtest_arg2);
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, libtest_arg3);
|
||||
curl_easy_setopt(curl, CURLOPT_PROXYAUTH,
|
||||
(long) (CURLAUTH_NTLM | CURLAUTH_DIGEST | CURLAUTH_BASIC) );
|
||||
|
||||
if ((m = curl_multi_init()) == NULL) {
|
||||
fprintf(stderr, "curl_multi_init() failed\n");
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
if ((res = (int)curl_multi_add_handle(m, curl)) != CURLM_OK) {
|
||||
fprintf(stderr, "curl_multi_add_handle() failed, "
|
||||
"with code %d\n", res);
|
||||
curl_multi_cleanup(m);
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
mp_timedout = FALSE;
|
||||
mp_start = tutil_tvnow();
|
||||
|
||||
while (running) {
|
||||
res = (int)curl_multi_perform(m, &running);
|
||||
if (tutil_tvdiff(tutil_tvnow(), mp_start) >
|
||||
MULTI_PERFORM_HANG_TIMEOUT) {
|
||||
mp_timedout = TRUE;
|
||||
break;
|
||||
}
|
||||
if (running <= 0) {
|
||||
fprintf(stderr, "nothing left running.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mp_timedout) {
|
||||
if (mp_timedout) fprintf(stderr, "mp_timedout\n");
|
||||
fprintf(stderr, "ABORTING TEST, since it seems "
|
||||
"that it would have run forever.\n");
|
||||
res = TEST_ERR_RUNS_FOREVER;
|
||||
}
|
||||
|
||||
curl_multi_remove_handle(m, curl);
|
||||
curl_easy_cleanup(curl);
|
||||
curl_multi_cleanup(m);
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib556.c,v 1.4 2008-09-20 04:26:57 yangtse Exp $
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
if(!res) {
|
||||
/* we are connected, now get a HTTP document the raw way */
|
||||
const char *request = "GET /556 HTTP/1.2\r\n"
|
||||
"Host: ninja\r\n\r\n";
|
||||
size_t iolen;
|
||||
char buf[1024];
|
||||
|
||||
res = curl_easy_send(curl, request, strlen(request), &iolen);
|
||||
|
||||
if(!res) {
|
||||
/* we assume that sending always work */
|
||||
int total=0;
|
||||
|
||||
do {
|
||||
/* busy-read like crazy */
|
||||
res = curl_easy_recv(curl, buf, 1024, &iolen);
|
||||
|
||||
if(iolen)
|
||||
/* send received stuff to stdout */
|
||||
write(STDOUT_FILENO, buf, iolen);
|
||||
|
||||
total += iolen;
|
||||
|
||||
} while(((res == CURLE_OK) || (res == CURLE_AGAIN)) && (total < 129));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,181 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib558.c,v 1.9 2008-11-07 12:22:43 yangtse Exp $
|
||||
*/
|
||||
|
||||
#include "test.h"
|
||||
|
||||
#ifdef HAVE_SYS_SOCKET_H
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
#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
|
||||
|
||||
#define ENABLE_CURLX_PRINTF
|
||||
#include "curlx.h"
|
||||
|
||||
#include "hash.h"
|
||||
#include "hostip.h"
|
||||
|
||||
#include "memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
/* This source file is used for test # 558 and 559 */
|
||||
|
||||
/*
|
||||
* This hacky test bypasses the library external API,
|
||||
* using internal only libcurl functions. So don't be
|
||||
* surprised if we cannot run it when the library has
|
||||
* been built with hidden symbols, exporting only the
|
||||
* ones in the public API.
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(CURL_HIDDEN_SYMBOLS)
|
||||
|
||||
#ifdef LIB559
|
||||
static Curl_addrinfo *fake_ai(void)
|
||||
{
|
||||
Curl_addrinfo *ai;
|
||||
int ss_size;
|
||||
|
||||
ss_size = sizeof (struct sockaddr_in);
|
||||
|
||||
if((ai = calloc(1, sizeof(Curl_addrinfo))) == NULL)
|
||||
return NULL;
|
||||
|
||||
if((ai->ai_canonname = strdup("dummy")) == NULL) {
|
||||
free(ai);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if((ai->ai_addr = calloc(1, ss_size)) == NULL) {
|
||||
free(ai->ai_canonname);
|
||||
free(ai);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ai->ai_family = AF_INET;
|
||||
ai->ai_addrlen = ss_size;
|
||||
|
||||
return ai;
|
||||
}
|
||||
#endif /* LIB559 */
|
||||
|
||||
|
||||
int test(char *URL)
|
||||
{
|
||||
CURL *easyh = NULL;
|
||||
struct curl_hash *hp = NULL;
|
||||
int result = 0;
|
||||
|
||||
if(!strcmp(URL, "check")) {
|
||||
/* test harness script verifying if this test can run */
|
||||
return 0; /* sure, run this! */
|
||||
}
|
||||
|
||||
easyh = curl_easy_init();
|
||||
if(!easyh) {
|
||||
fprintf(stdout, "easy handle init failed\n");
|
||||
result = TEST_ERR_MAJOR_BAD;
|
||||
goto cleanup;
|
||||
}
|
||||
fprintf(stdout, "easy handle init OK\n");
|
||||
|
||||
fprintf(stdout, "creating hash...\n");
|
||||
hp = Curl_mk_dnscache();
|
||||
if(!hp) {
|
||||
fprintf(stdout, "hash creation failed\n");
|
||||
result = TEST_ERR_MAJOR_BAD;
|
||||
goto cleanup;
|
||||
}
|
||||
fprintf(stdout, "hash creation OK\n");
|
||||
|
||||
/**/
|
||||
#ifdef LIB559
|
||||
{
|
||||
char *data_key;
|
||||
struct Curl_dns_entry *data_node;
|
||||
struct Curl_dns_entry *nodep;
|
||||
size_t key_len;
|
||||
|
||||
data_key = aprintf("%s:%d", "dummy", 0);
|
||||
if(!data_key) {
|
||||
fprintf(stdout, "data key creation failed\n");
|
||||
result = TEST_ERR_MAJOR_BAD;
|
||||
goto cleanup;
|
||||
}
|
||||
key_len = strlen(data_key);
|
||||
|
||||
data_node = calloc(1, sizeof(struct Curl_dns_entry));
|
||||
if(!data_node) {
|
||||
fprintf(stdout, "data node creation failed\n");
|
||||
result = TEST_ERR_MAJOR_BAD;
|
||||
free(data_key);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
data_node->addr = fake_ai();
|
||||
if(!data_node->addr) {
|
||||
fprintf(stdout, "actual data creation failed\n");
|
||||
result = TEST_ERR_MAJOR_BAD;
|
||||
free(data_node);
|
||||
free(data_key);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
nodep = Curl_hash_add(hp, data_key, key_len+1, (void *)data_node);
|
||||
if(!nodep) {
|
||||
fprintf(stdout, "insertion into hash failed\n");
|
||||
result = TEST_ERR_MAJOR_BAD;
|
||||
Curl_freeaddrinfo(data_node->addr);
|
||||
free(data_node);
|
||||
free(data_key);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
free(data_key);
|
||||
}
|
||||
#endif /* LIB559 */
|
||||
/**/
|
||||
|
||||
cleanup:
|
||||
|
||||
fprintf(stdout, "destroying hash...\n");
|
||||
Curl_hash_destroy(hp);
|
||||
fprintf(stdout, "hash destruction OK\n");
|
||||
|
||||
fprintf(stdout, "destroying easy handle...\n");
|
||||
curl_easy_cleanup(easyh);
|
||||
fprintf(stdout, "easy handle destruction OK\n");
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#else /* !defined(CURL_HIDDEN_SYMBOLS) */
|
||||
|
||||
|
||||
int test(char *URL)
|
||||
{
|
||||
(void)URL;
|
||||
fprintf(stdout, "libcurl built with hidden symbols");
|
||||
return 1; /* skip test */
|
||||
}
|
||||
|
||||
|
||||
#endif /* !defined(CURL_HIDDEN_SYMBOLS) */
|
||||
@@ -0,0 +1,98 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: lib560.c,v 1.2 2008-11-12 22:26:06 danf Exp $
|
||||
*
|
||||
*/
|
||||
#include "test.h"
|
||||
|
||||
/*
|
||||
* 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;
|
||||
CURLM *multi_handle;
|
||||
|
||||
int still_running; /* keep number of running handles */
|
||||
|
||||
http_handle = curl_easy_init();
|
||||
if (!http_handle)
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
|
||||
/* set options */
|
||||
curl_easy_setopt(http_handle, CURLOPT_URL, URL);
|
||||
curl_easy_setopt(http_handle, CURLOPT_HEADER, 1L);
|
||||
curl_easy_setopt(http_handle, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt(http_handle, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
if (!multi_handle) {
|
||||
curl_easy_cleanup(http_handle);
|
||||
return TEST_ERR_MAJOR_BAD;
|
||||
}
|
||||
|
||||
/* add the individual transfers */
|
||||
curl_multi_add_handle(multi_handle, http_handle);
|
||||
|
||||
/* we start some action by calling perform right away */
|
||||
while(CURLM_CALL_MULTI_PERFORM ==
|
||||
curl_multi_perform(multi_handle, &still_running));
|
||||
|
||||
while(still_running) {
|
||||
struct timeval timeout;
|
||||
int rc; /* select() return code */
|
||||
|
||||
fd_set fdread;
|
||||
fd_set fdwrite;
|
||||
fd_set fdexcep;
|
||||
int maxfd;
|
||||
|
||||
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 */
|
||||
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, *and* you make sure that maxfd is bigger than -1 so
|
||||
that the call to select() below makes sense! */
|
||||
|
||||
rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
|
||||
switch(rc) {
|
||||
case -1:
|
||||
/* select error */
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
/* timeout or readable/writable sockets */
|
||||
while(CURLM_CALL_MULTI_PERFORM ==
|
||||
curl_multi_perform(multi_handle, &still_running));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
curl_easy_cleanup(http_handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*****************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* $Id: test.h,v 1.21 2008-09-18 16:21:09 yangtse Exp $
|
||||
*/
|
||||
|
||||
/* Now include the setup.h file from libcurl's private libdir (the source
|
||||
version, but that might include "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 */
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.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
|
||||
|
||||
#define TEST_ERR_MAJOR_BAD 100
|
||||
#define TEST_ERR_RUNS_FOREVER 99
|
||||
|
||||
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 int select_test(int num_fds, 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 */
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
#!/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 =~ /\w+: (.*)$/;
|
||||
@curl = split / /,$1;
|
||||
|
||||
# These features are not supported by curl-config
|
||||
@curl = grep(!/^(Debug|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;
|
||||
@@ -0,0 +1,45 @@
|
||||
#!/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]+(-CVS)?)/;
|
||||
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;
|
||||
if ( $what eq "version" ) {
|
||||
/^libcurl ([\.\d]+(-CVS)?)$/ ;
|
||||
$curlconfigversion = $1;
|
||||
}
|
||||
else {
|
||||
# Convert hex version to decimal for comparison's sake
|
||||
/^(..)(..)(..)$/ ;
|
||||
$curlconfigversion = hex($1) . "." . hex($2) . "." . hex($3);
|
||||
|
||||
# Strip off the -CVS from the curl version if it's there
|
||||
$version =~ s/-CVS$//;
|
||||
}
|
||||
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;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -0,0 +1,136 @@
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2008, Daniel Stenberg, <[email protected]>, 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.
|
||||
*
|
||||
* $Id: testutil.c,v 1.8 2008-09-20 04:26:57 yangtse Exp $
|
||||
***************************************************************************/
|
||||
|
||||
#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)
|
||||
{
|
||||
return (double)(newer.tv_sec-older.tv_sec)+
|
||||
(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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef __LIBTEST_TESTUTIL_H
|
||||
#define __LIBTEST_TESTUTIL_H
|
||||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2007, Daniel Stenberg, <[email protected]>, 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.
|
||||
*
|
||||
* $Id: testutil.h,v 1.4 2007-02-20 12:12:27 yangtse Exp $
|
||||
***************************************************************************/
|
||||
|
||||
#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 /* __LIBTEST_TESTUTIL_H */
|
||||
|
||||
Reference in New Issue
Block a user