mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-21 04:15:36 +00:00
Update libcurl
This commit is contained in:
parent
20eb0a911a
commit
01a719ee58
3439 changed files with 529259 additions and 41492 deletions
3
Engine/lib/curl/docs/examples/.checksrc
Normal file
3
Engine/lib/curl/docs/examples/.checksrc
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
disable TYPEDEFSTRUCT
|
||||
disable SNPRINTF
|
||||
disable BANNEDFUNC
|
||||
152
Engine/lib/curl/docs/examples/10-at-a-time.c
Normal file
152
Engine/lib/curl/docs/examples/10-at-a-time.c
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Download many files in parallel, in the same thread.
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifndef WIN32
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
#include <curl/curl.h>
|
||||
|
||||
static const char *urls[] = {
|
||||
"https://www.microsoft.com",
|
||||
"https://opensource.org",
|
||||
"https://www.google.com",
|
||||
"https://www.yahoo.com",
|
||||
"https://www.ibm.com",
|
||||
"https://www.mysql.com",
|
||||
"https://www.oracle.com",
|
||||
"https://www.ripe.net",
|
||||
"https://www.iana.org",
|
||||
"https://www.amazon.com",
|
||||
"https://www.netcraft.com",
|
||||
"https://www.heise.de",
|
||||
"https://www.chip.de",
|
||||
"https://www.ca.com",
|
||||
"https://www.cnet.com",
|
||||
"https://www.mozilla.org",
|
||||
"https://www.cnn.com",
|
||||
"https://www.wikipedia.org",
|
||||
"https://www.dell.com",
|
||||
"https://www.hp.com",
|
||||
"https://www.cert.org",
|
||||
"https://www.mit.edu",
|
||||
"https://www.nist.gov",
|
||||
"https://www.ebay.com",
|
||||
"https://www.playstation.com",
|
||||
"https://www.uefa.com",
|
||||
"https://www.ieee.org",
|
||||
"https://www.apple.com",
|
||||
"https://www.symantec.com",
|
||||
"https://www.zdnet.com",
|
||||
"https://www.fujitsu.com/global/",
|
||||
"https://www.supermicro.com",
|
||||
"https://www.hotmail.com",
|
||||
"https://www.ietf.org",
|
||||
"https://www.bbc.co.uk",
|
||||
"https://news.google.com",
|
||||
"https://www.foxnews.com",
|
||||
"https://www.msn.com",
|
||||
"https://www.wired.com",
|
||||
"https://www.sky.com",
|
||||
"https://www.usatoday.com",
|
||||
"https://www.cbs.com",
|
||||
"https://www.nbc.com/",
|
||||
"https://slashdot.org",
|
||||
"https://www.informationweek.com",
|
||||
"https://apache.org",
|
||||
"https://www.un.org",
|
||||
};
|
||||
|
||||
#define MAX_PARALLEL 10 /* number of simultaneous transfers */
|
||||
#define NUM_URLS sizeof(urls)/sizeof(char *)
|
||||
|
||||
static size_t write_cb(char *data, size_t n, size_t l, void *userp)
|
||||
{
|
||||
/* take care of the data here, ignored in this example */
|
||||
(void)data;
|
||||
(void)userp;
|
||||
return n*l;
|
||||
}
|
||||
|
||||
static void add_transfer(CURLM *cm, int i)
|
||||
{
|
||||
CURL *eh = curl_easy_init();
|
||||
curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
curl_easy_setopt(eh, CURLOPT_URL, urls[i]);
|
||||
curl_easy_setopt(eh, CURLOPT_PRIVATE, urls[i]);
|
||||
curl_multi_add_handle(cm, eh);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURLM *cm;
|
||||
CURLMsg *msg;
|
||||
unsigned int transfers = 0;
|
||||
int msgs_left = -1;
|
||||
int still_alive = 1;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
cm = curl_multi_init();
|
||||
|
||||
/* Limit the amount of simultaneous connections curl should allow: */
|
||||
curl_multi_setopt(cm, CURLMOPT_MAXCONNECTS, (long)MAX_PARALLEL);
|
||||
|
||||
for(transfers = 0; transfers < MAX_PARALLEL; transfers++)
|
||||
add_transfer(cm, transfers);
|
||||
|
||||
do {
|
||||
curl_multi_perform(cm, &still_alive);
|
||||
|
||||
while((msg = curl_multi_info_read(cm, &msgs_left))) {
|
||||
if(msg->msg == CURLMSG_DONE) {
|
||||
char *url;
|
||||
CURL *e = msg->easy_handle;
|
||||
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &url);
|
||||
fprintf(stderr, "R: %d - %s <%s>\n",
|
||||
msg->data.result, curl_easy_strerror(msg->data.result), url);
|
||||
curl_multi_remove_handle(cm, e);
|
||||
curl_easy_cleanup(e);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg);
|
||||
}
|
||||
if(transfers < NUM_URLS)
|
||||
add_transfer(cm, transfers++);
|
||||
}
|
||||
if(still_alive)
|
||||
curl_multi_wait(cm, NULL, 0, 1000, NULL);
|
||||
|
||||
} while(still_alive || (transfers < NUM_URLS));
|
||||
|
||||
curl_multi_cleanup(cm);
|
||||
curl_global_cleanup();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
72
Engine/lib/curl/docs/examples/Makefile.am
Normal file
72
Engine/lib/curl/docs/examples/Makefile.am
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.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.
|
||||
#
|
||||
# SPDX-License-Identifier: curl
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
AUTOMAKE_OPTIONS = foreign nostdinc
|
||||
|
||||
EXTRA_DIST = README.md Makefile.example Makefile.inc Makefile.m32 \
|
||||
makefile.dj $(COMPLICATED_EXAMPLES) .checksrc
|
||||
|
||||
# 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_srcdir)/include is for libcurl's external include files
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
|
||||
LIBDIR = $(top_builddir)/lib
|
||||
|
||||
# Avoid libcurl obsolete stuff
|
||||
AM_CPPFLAGS += -DCURL_NO_OLDIES
|
||||
|
||||
if USE_CPPFLAG_CURL_STATICLIB
|
||||
AM_CPPFLAGS += -DCURL_STATICLIB
|
||||
endif
|
||||
|
||||
# Prevent LIBS from being used for all link targets
|
||||
LIBS = $(BLANK_AT_MAKETIME)
|
||||
|
||||
# Dependencies
|
||||
if USE_EXPLICIT_LIB_DEPS
|
||||
LDADD = $(LIBDIR)/libcurl.la @LIBCURL_LIBS@
|
||||
else
|
||||
LDADD = $(LIBDIR)/libcurl.la
|
||||
endif
|
||||
|
||||
# This might hold -Werror
|
||||
CFLAGS += @CURL_CFLAG_EXTRAS@
|
||||
|
||||
# Makefile.inc provides the check_PROGRAMS and COMPLICATED_EXAMPLES defines
|
||||
include Makefile.inc
|
||||
|
||||
all: $(check_PROGRAMS)
|
||||
|
||||
CHECKSRC = $(CS_$(V))
|
||||
CS_0 = @echo " RUN " $@;
|
||||
CS_1 =
|
||||
CS_ = $(CS_0)
|
||||
|
||||
checksrc:
|
||||
$(CHECKSRC)(@PERL@ $(top_srcdir)/scripts/checksrc.pl -D$(srcdir) $(srcdir)/*.c)
|
||||
55
Engine/lib/curl/docs/examples/Makefile.example
Normal file
55
Engine/lib/curl/docs/examples/Makefile.example
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.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.
|
||||
#
|
||||
# SPDX-License-Identifier: curl
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# What to call the final executable
|
||||
TARGET = example
|
||||
|
||||
# Which object files that the executable consists of
|
||||
OBJS= ftpget.o
|
||||
|
||||
# What compiler to use
|
||||
CC = gcc
|
||||
|
||||
# Compiler flags, -g for debug, -c to make an object file
|
||||
CFLAGS = -c -g
|
||||
|
||||
# This should point to a directory that holds libcurl, if it isn't
|
||||
# in the system's standard lib dir
|
||||
# We also set a -L to include the directory where we have the openssl
|
||||
# libraries
|
||||
LDFLAGS = -L/home/dast/lib -L/usr/local/ssl/lib
|
||||
|
||||
# We need -lcurl for the curl stuff
|
||||
# We need -lsocket and -lnsl when on Solaris
|
||||
# We need -lssl and -lcrypto when using libcurl with SSL support
|
||||
# We need -lpthread for the pthread example
|
||||
LIBS = -lcurl -lsocket -lnsl -lssl -lcrypto
|
||||
|
||||
# Link the target with all objects and libraries
|
||||
$(TARGET) : $(OBJS)
|
||||
$(CC) -o $(TARGET) $(OBJS) $(LDFLAGS) $(LIBS)
|
||||
|
||||
# Compile the source files into object files
|
||||
ftpget.o : ftpget.c
|
||||
$(CC) $(CFLAGS) $<
|
||||
2236
Engine/lib/curl/docs/examples/Makefile.in
Normal file
2236
Engine/lib/curl/docs/examples/Makefile.in
Normal file
File diff suppressed because it is too large
Load diff
144
Engine/lib/curl/docs/examples/Makefile.inc
Normal file
144
Engine/lib/curl/docs/examples/Makefile.inc
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.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.
|
||||
#
|
||||
# SPDX-License-Identifier: curl
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# These are all libcurl example programs to be test compiled
|
||||
check_PROGRAMS = \
|
||||
10-at-a-time \
|
||||
altsvc \
|
||||
anyauthput \
|
||||
certinfo \
|
||||
chkspeed \
|
||||
cookie_interface \
|
||||
debug \
|
||||
externalsocket \
|
||||
fileupload \
|
||||
ftp-wildcard \
|
||||
ftpget \
|
||||
ftpgetinfo \
|
||||
ftpgetresp \
|
||||
ftpsget \
|
||||
ftpupload \
|
||||
ftpuploadfrommem \
|
||||
ftpuploadresume \
|
||||
getinfo \
|
||||
getinmemory \
|
||||
getredirect \
|
||||
getreferrer \
|
||||
headerapi \
|
||||
http-post \
|
||||
http2-download \
|
||||
http2-pushinmemory \
|
||||
http2-serverpush \
|
||||
http2-upload \
|
||||
http3 \
|
||||
http3-present \
|
||||
httpcustomheader \
|
||||
httpput \
|
||||
httpput-postfields \
|
||||
https \
|
||||
imap-append \
|
||||
imap-authzid \
|
||||
imap-copy \
|
||||
imap-create \
|
||||
imap-delete \
|
||||
imap-examine \
|
||||
imap-fetch \
|
||||
imap-list \
|
||||
imap-lsub \
|
||||
imap-multi \
|
||||
imap-noop \
|
||||
imap-search \
|
||||
imap-ssl \
|
||||
imap-store \
|
||||
imap-tls \
|
||||
multi-app \
|
||||
multi-debugcallback \
|
||||
multi-double \
|
||||
multi-formadd \
|
||||
multi-legacy \
|
||||
multi-post \
|
||||
multi-single \
|
||||
parseurl \
|
||||
persistent \
|
||||
pop3-authzid \
|
||||
pop3-dele \
|
||||
pop3-list \
|
||||
pop3-multi \
|
||||
pop3-noop \
|
||||
pop3-retr \
|
||||
pop3-ssl \
|
||||
pop3-stat \
|
||||
pop3-tls \
|
||||
pop3-top \
|
||||
pop3-uidl \
|
||||
post-callback \
|
||||
postinmemory \
|
||||
postit2 \
|
||||
postit2-formadd \
|
||||
progressfunc \
|
||||
resolve \
|
||||
sendrecv \
|
||||
sepheaders \
|
||||
sftpget \
|
||||
sftpuploadresume \
|
||||
shared-connection-cache \
|
||||
simple \
|
||||
simplepost \
|
||||
simplessl \
|
||||
smtp-authzid \
|
||||
smtp-expn \
|
||||
smtp-mail \
|
||||
smtp-mime \
|
||||
smtp-multi \
|
||||
smtp-ssl \
|
||||
smtp-tls \
|
||||
smtp-vrfy \
|
||||
sslbackend \
|
||||
url2file \
|
||||
urlapi
|
||||
|
||||
# These examples require external dependencies that may not be commonly
|
||||
# available on POSIX systems, so don't bother attempting to compile them here.
|
||||
COMPLICATED_EXAMPLES = \
|
||||
cacertinmem.c \
|
||||
crawler.c \
|
||||
curlgtk.c \
|
||||
ephiperfifo.c \
|
||||
evhiperfifo.c \
|
||||
ghiper.c \
|
||||
hiperfifo.c \
|
||||
href_extractor.c \
|
||||
htmltidy.c \
|
||||
htmltitle.cpp \
|
||||
multi-event.c \
|
||||
multi-uv.c \
|
||||
multithread.c \
|
||||
opensslthreadlock.c \
|
||||
sessioninfo.c \
|
||||
smooth-gtk-thread.c \
|
||||
synctime.c \
|
||||
threaded-ssl.c \
|
||||
usercertinmem.c \
|
||||
version-check.pl \
|
||||
xmlstream.c
|
||||
415
Engine/lib/curl/docs/examples/Makefile.m32
Normal file
415
Engine/lib/curl/docs/examples/Makefile.m32
Normal file
|
|
@ -0,0 +1,415 @@
|
|||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.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.
|
||||
#
|
||||
# SPDX-License-Identifier: curl
|
||||
#
|
||||
#***************************************************************************
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
## Makefile for building curl examples with MingW (GCC-3.2 or later)
|
||||
## and optionally OpenSSL (1.0.2a), libssh2 (1.5), zlib (1.2.8), librtmp (2.4),
|
||||
## brotli (1.0.1), zstd (1.4.5)
|
||||
##
|
||||
## Usage: mingw32-make -f Makefile.m32 CFG=-feature1[-feature2][-feature3][...]
|
||||
## Example: mingw32-make -f Makefile.m32 CFG=-zlib-ssl-sspi-winidn
|
||||
##
|
||||
## Hint: you can also set environment vars to control the build, f.e.:
|
||||
## set ZLIB_PATH=c:/zlib-1.2.8
|
||||
## set ZLIB=1
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
# Edit the path below to point to the base of your Zlib sources.
|
||||
ifndef ZLIB_PATH
|
||||
ZLIB_PATH = ../../../zlib-1.2.8
|
||||
endif
|
||||
# Edit the path below to point to the base of your Zstandard sources.
|
||||
ifndef ZSTD_PATH
|
||||
ZSTD_PATH = ../../../zstd-1.4.5
|
||||
endif
|
||||
# Edit the path below to point to the base of your Brotli sources.
|
||||
ifndef BROTLI_PATH
|
||||
BROTLI_PATH = ../../../brotli-1.0.1
|
||||
endif
|
||||
# Edit the path below to point to the base of your OpenSSL package.
|
||||
ifndef OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../../openssl-1.0.2a
|
||||
endif
|
||||
# Edit the path below to point to the base of your LibSSH2 package.
|
||||
ifndef LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../../libssh2-1.5.0
|
||||
endif
|
||||
# Edit the path below to point to the base of your librtmp package.
|
||||
ifndef LIBRTMP_PATH
|
||||
LIBRTMP_PATH = ../../../librtmp-2.4
|
||||
endif
|
||||
# Edit the path below to point to the base of your libexpat package.
|
||||
ifndef LIBEXPAT_PATH
|
||||
LIBEXPAT_PATH = ../../../expat-2.1.0
|
||||
endif
|
||||
# Edit the path below to point to the base of your libxml2 package.
|
||||
ifndef LIBXML2_PATH
|
||||
LIBXML2_PATH = ../../../libxml2-2.9.2
|
||||
endif
|
||||
# Edit the path below to point to the base of your libgsasl package.
|
||||
ifndef LIBGSASL_PATH
|
||||
LIBGSASL_PATH = ../../../libgsasl-1.10.0
|
||||
endif
|
||||
# Edit the path below to point to the base of your libidn2 package.
|
||||
ifndef LIBIDN2_PATH
|
||||
LIBIDN2_PATH = ../../../libidn2-2.0.3
|
||||
endif
|
||||
# Edit the path below to point to the base of your MS IDN package.
|
||||
# Microsoft Internationalized Domain Names (IDN) Mitigation APIs 1.1
|
||||
# https://www.microsoft.com/en-us/download/details.aspx?id=734
|
||||
ifndef WINIDN_PATH
|
||||
WINIDN_PATH = ../../../Microsoft IDN Mitigation APIs
|
||||
endif
|
||||
# Edit the path below to point to the base of your Novell LDAP NDK.
|
||||
ifndef LDAP_SDK
|
||||
LDAP_SDK = c:/novell/ndk/cldapsdk/win32
|
||||
endif
|
||||
# Edit the path below to point to the base of your nghttp2 package.
|
||||
ifndef NGHTTP2_PATH
|
||||
NGHTTP2_PATH = ../../../nghttp2-1.0.0
|
||||
endif
|
||||
# Edit the path below to point to the base of your nghttp3 package.
|
||||
ifndef NGHTTP3_PATH
|
||||
NGHTTP3_PATH = ../../../nghttp3-1.0.0
|
||||
endif
|
||||
# Edit the path below to point to the base of your ngtcp2 package.
|
||||
ifndef NGTCP2_PATH
|
||||
NGTCP2_PATH = ../../../ngtcp2-1.0.0
|
||||
endif
|
||||
|
||||
PROOT = ../..
|
||||
|
||||
# Edit the path below to point to the base of your c-ares package.
|
||||
ifndef LIBCARES_PATH
|
||||
LIBCARES_PATH = $(PROOT)/ares
|
||||
endif
|
||||
|
||||
ifeq ($(CURL_CC),)
|
||||
CURL_CC := $(CROSSPREFIX)gcc
|
||||
endif
|
||||
ifeq ($(CURL_AR),)
|
||||
CURL_AR := $(CROSSPREFIX)ar
|
||||
endif
|
||||
ifeq ($(CURL_RC),)
|
||||
CURL_RC := $(CROSSPREFIX)windres
|
||||
endif
|
||||
|
||||
CC = $(CURL_CC)
|
||||
CFLAGS = -O3 $(CURL_CFLAG_EXTRAS) -W -Wall
|
||||
LDFLAGS = $(CURL_LDFLAG_EXTRAS) $(CURL_LDFLAG_EXTRAS_EXE)
|
||||
RC = $(CURL_RC)
|
||||
RCFLAGS = --include-dir=$(PROOT)/include -O coff $(CURL_RCFLAG_EXTRAS)
|
||||
|
||||
# Set environment var ARCH to your architecture to override autodetection.
|
||||
ifndef ARCH
|
||||
ifeq ($(findstring x86_64,$(shell $(CC) -dumpmachine)),x86_64)
|
||||
ARCH = w64
|
||||
else
|
||||
ARCH = w32
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(ARCH),custom)
|
||||
ifeq ($(ARCH),w64)
|
||||
CFLAGS += -m64
|
||||
LDFLAGS += -m64
|
||||
RCFLAGS += -F pe-x86-64
|
||||
else
|
||||
CFLAGS += -m32
|
||||
LDFLAGS += -m32
|
||||
RCFLAGS += -F pe-i386
|
||||
endif
|
||||
endif
|
||||
|
||||
# Platform-dependent helper tool macros
|
||||
ifeq ($(findstring /sh,$(SHELL)),/sh)
|
||||
DEL = rm -f $1
|
||||
RMDIR = rm -fr $1
|
||||
MKDIR = mkdir -p $1
|
||||
COPY = -cp -afv $1 $2
|
||||
#COPYR = -cp -afr $1/* $2
|
||||
COPYR = -rsync -aC $1/* $2
|
||||
TOUCH = touch $1
|
||||
CAT = cat
|
||||
ECHONL = echo ""
|
||||
DL = '
|
||||
else
|
||||
ifeq "$(OS)" "Windows_NT"
|
||||
DEL = -del 2>NUL /q /f $(subst /,\,$1)
|
||||
RMDIR = -rd 2>NUL /q /s $(subst /,\,$1)
|
||||
else
|
||||
DEL = -del 2>NUL $(subst /,\,$1)
|
||||
RMDIR = -deltree 2>NUL /y $(subst /,\,$1)
|
||||
endif
|
||||
MKDIR = -md 2>NUL $(subst /,\,$1)
|
||||
COPY = -copy 2>NUL /y $(subst /,\,$1) $(subst /,\,$2)
|
||||
COPYR = -xcopy 2>NUL /q /y /e $(subst /,\,$1) $(subst /,\,$2)
|
||||
TOUCH = copy 2>&1>NUL /b $(subst /,\,$1) +,,
|
||||
CAT = type
|
||||
ECHONL = $(ComSpec) /c echo.
|
||||
endif
|
||||
|
||||
########################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
ifneq ($(findstring -dyn,$(CFG)),)
|
||||
DYN = 1
|
||||
endif
|
||||
ifneq ($(findstring -ares,$(CFG)),)
|
||||
ARES = 1
|
||||
endif
|
||||
ifneq ($(findstring -rtmp,$(CFG)),)
|
||||
RTMP = 1
|
||||
ZLIB = 1
|
||||
endif
|
||||
ifneq ($(findstring -ssh2,$(CFG)),)
|
||||
SSH2 = 1
|
||||
ZLIB = 1
|
||||
endif
|
||||
ifneq ($(findstring -ssl,$(CFG)),)
|
||||
SSL = 1
|
||||
endif
|
||||
ifneq ($(findstring -zlib,$(CFG)),)
|
||||
ZLIB = 1
|
||||
endif
|
||||
ifneq ($(findstring -zstd,$(CFG)),)
|
||||
ZSTD = 1
|
||||
endif
|
||||
ifneq ($(findstring -brotli,$(CFG)),)
|
||||
BROTLI = 1
|
||||
endif
|
||||
ifneq ($(findstring -gsasl,$(CFG)),)
|
||||
GSASL = 1
|
||||
endif
|
||||
ifneq ($(findstring -idn2,$(CFG)),)
|
||||
IDN2 = 1
|
||||
endif
|
||||
ifneq ($(findstring -winidn,$(CFG)),)
|
||||
WINIDN = 1
|
||||
endif
|
||||
ifneq ($(findstring -sspi,$(CFG)),)
|
||||
SSPI = 1
|
||||
endif
|
||||
ifneq ($(findstring -ldaps,$(CFG)),)
|
||||
LDAPS = 1
|
||||
endif
|
||||
ifneq ($(findstring -ipv6,$(CFG)),)
|
||||
IPV6 = 1
|
||||
endif
|
||||
ifneq ($(findstring -schannel,$(CFG))$(findstring -winssl,$(CFG)),)
|
||||
SCHANNEL = 1
|
||||
SSPI = 1
|
||||
endif
|
||||
ifneq ($(findstring -nghttp2,$(CFG)),)
|
||||
NGHTTP2 = 1
|
||||
endif
|
||||
ifneq ($(findstring -nghttp3,$(CFG)),)
|
||||
NGHTTP3 = 1
|
||||
endif
|
||||
ifneq ($(findstring -ngtcp2,$(CFG)),)
|
||||
NGTCP2 = 1
|
||||
endif
|
||||
|
||||
# SSH2 and RTMP require an SSL library; assume OpenSSL if none specified
|
||||
ifneq ($(SSH2)$(RTMP),)
|
||||
ifeq ($(SSL)$(SCHANNEL),)
|
||||
SSL = 1
|
||||
endif
|
||||
endif
|
||||
|
||||
INCLUDES = -I. -I$(PROOT) -I$(PROOT)/include -I$(PROOT)/lib
|
||||
|
||||
ifdef DYN
|
||||
curl_DEPENDENCIES = $(PROOT)/lib/libcurldll.a $(PROOT)/lib/libcurl.dll
|
||||
curl_LDADD = -L$(PROOT)/lib -lcurldll
|
||||
else
|
||||
curl_DEPENDENCIES = $(PROOT)/lib/libcurl.a
|
||||
curl_LDADD = -L$(PROOT)/lib -lcurl
|
||||
CFLAGS += -DCURL_STATICLIB
|
||||
LDFLAGS += -static
|
||||
endif
|
||||
ifdef ARES
|
||||
ifndef DYN
|
||||
curl_DEPENDENCIES += $(LIBCARES_PATH)/libcares.a
|
||||
endif
|
||||
CFLAGS += -DUSE_ARES
|
||||
curl_LDADD += -L"$(LIBCARES_PATH)" -lcares
|
||||
endif
|
||||
ifdef RTMP
|
||||
CFLAGS += -DUSE_LIBRTMP
|
||||
curl_LDADD += -L"$(LIBRTMP_PATH)/librtmp" -lrtmp -lwinmm
|
||||
endif
|
||||
ifdef NGHTTP2
|
||||
CFLAGS += -DUSE_NGHTTP2
|
||||
curl_LDADD += -L"$(NGHTTP2_PATH)/lib" -lnghttp2
|
||||
endif
|
||||
ifdef SSH2
|
||||
CFLAGS += -DUSE_LIBSSH2 -DHAVE_LIBSSH2_H
|
||||
curl_LDADD += -L"$(LIBSSH2_PATH)/win32" -lssh2
|
||||
ifdef SCHANNEL
|
||||
ifndef DYN
|
||||
curl_LDADD += -lcrypt32
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifdef NGHTTP3
|
||||
CFLAGS += -DUSE_NGHTTP3
|
||||
curl_LDADD += -L"$(NGHTTP3_PATH)/lib" -lnghttp3
|
||||
ifdef NGTCP2
|
||||
CFLAGS += -DUSE_NGTCP2
|
||||
curl_LDADD += -L"$(NGTCP2_PATH)/lib"
|
||||
ifdef NGTCP2_LIBS
|
||||
curl_LDADD += $(NGTCP2_LIBS)
|
||||
else
|
||||
curl_LDADD += -lngtcp2
|
||||
ifdef SSL
|
||||
curl_LDADD += -lngtcp2_crypto_openssl
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifdef SSL
|
||||
ifndef OPENSSL_INCLUDE
|
||||
ifeq "$(wildcard $(OPENSSL_PATH)/outinc)" "$(OPENSSL_PATH)/outinc"
|
||||
OPENSSL_INCLUDE = $(OPENSSL_PATH)/outinc
|
||||
endif
|
||||
ifeq "$(wildcard $(OPENSSL_PATH)/include)" "$(OPENSSL_PATH)/include"
|
||||
OPENSSL_INCLUDE = $(OPENSSL_PATH)/include
|
||||
endif
|
||||
endif
|
||||
ifneq "$(wildcard $(OPENSSL_INCLUDE)/openssl/opensslv.h)" "$(OPENSSL_INCLUDE)/openssl/opensslv.h"
|
||||
$(error Invalid path to OpenSSL package: $(OPENSSL_PATH))
|
||||
endif
|
||||
ifndef OPENSSL_LIBPATH
|
||||
OPENSSL_LIBS = -lssl -lcrypto
|
||||
ifeq "$(wildcard $(OPENSSL_PATH)/out)" "$(OPENSSL_PATH)/out"
|
||||
OPENSSL_LIBPATH = $(OPENSSL_PATH)/out
|
||||
ifdef DYN
|
||||
OPENSSL_LIBS = -lssl32 -leay32
|
||||
endif
|
||||
endif
|
||||
ifeq "$(wildcard $(OPENSSL_PATH)/lib)" "$(OPENSSL_PATH)/lib"
|
||||
OPENSSL_LIBPATH = $(OPENSSL_PATH)/lib
|
||||
endif
|
||||
endif
|
||||
ifndef DYN
|
||||
OPENSSL_LIBS += -lgdi32 -lcrypt32
|
||||
endif
|
||||
INCLUDES += -I"$(OPENSSL_INCLUDE)"
|
||||
CFLAGS += -DUSE_OPENSSL
|
||||
curl_LDADD += -L"$(OPENSSL_LIBPATH)" $(OPENSSL_LIBS)
|
||||
endif
|
||||
ifdef SCHANNEL
|
||||
CFLAGS += -DUSE_SCHANNEL
|
||||
curl_LDADD += -lcrypt32
|
||||
endif
|
||||
ifdef ZLIB
|
||||
INCLUDES += -I"$(ZLIB_PATH)"
|
||||
CFLAGS += -DHAVE_LIBZ -DHAVE_ZLIB_H
|
||||
curl_LDADD += -L"$(ZLIB_PATH)" -lz
|
||||
endif
|
||||
ifdef ZSTD
|
||||
INCLUDES += -I"$(ZSTD_PATH)/include"
|
||||
CFLAGS += -DHAVE_ZSTD
|
||||
curl_LDADD += -L"$(ZSTD_PATH)/lib"
|
||||
ifdef ZSTD_LIBS
|
||||
curl_LDADD += $(ZSTD_LIBS)
|
||||
else
|
||||
curl_LDADD += -lzstd
|
||||
endif
|
||||
endif
|
||||
ifdef BROTLI
|
||||
INCLUDES += -I"$(BROTLI_PATH)/include"
|
||||
CFLAGS += -DHAVE_BROTLI
|
||||
curl_LDADD += -L"$(BROTLI_PATH)/lib"
|
||||
ifdef BROTLI_LIBS
|
||||
curl_LDADD += $(BROTLI_LIBS)
|
||||
else
|
||||
curl_LDADD += -lbrotlidec
|
||||
endif
|
||||
endif
|
||||
ifdef GSASL
|
||||
CFLAGS += -DUSE_GSASL
|
||||
curl_LDADD += -L"$(LIBGSASL_PATH)/lib" -lgsasl
|
||||
endif
|
||||
ifdef IDN2
|
||||
CFLAGS += -DUSE_LIBIDN2
|
||||
curl_LDADD += -L"$(LIBIDN2_PATH)/lib" -lidn2
|
||||
else
|
||||
ifdef WINIDN
|
||||
CFLAGS += -DUSE_WIN32_IDN
|
||||
curl_LDADD += -L"$(WINIDN_PATH)" -lnormaliz
|
||||
endif
|
||||
endif
|
||||
ifdef SSPI
|
||||
CFLAGS += -DUSE_WINDOWS_SSPI
|
||||
endif
|
||||
ifdef IPV6
|
||||
CFLAGS += -DENABLE_IPV6
|
||||
endif
|
||||
ifdef LDAPS
|
||||
CFLAGS += -DHAVE_LDAP_SSL
|
||||
endif
|
||||
ifdef USE_LDAP_NOVELL
|
||||
CFLAGS += -DCURL_HAS_NOVELL_LDAPSDK
|
||||
curl_LDADD += -L"$(LDAP_SDK)/lib/mscvc" -lldapsdk -lldapssl -lldapx
|
||||
endif
|
||||
ifdef USE_LDAP_OPENLDAP
|
||||
CFLAGS += -DCURL_HAS_OPENLDAP_LDAPSDK
|
||||
curl_LDADD += -L"$(LDAP_SDK)/lib" -lldap -llber
|
||||
endif
|
||||
ifndef USE_LDAP_NOVELL
|
||||
ifndef USE_LDAP_OPENLDAP
|
||||
curl_LDADD += -lwldap32
|
||||
endif
|
||||
endif
|
||||
curl_LDADD += -lws2_32 -lbcrypt
|
||||
|
||||
# Makefile.inc provides the check_PROGRAMS and COMPLICATED_EXAMPLES defines
|
||||
include Makefile.inc
|
||||
|
||||
check_PROGRAMS := $(patsubst %,%.exe,$(strip $(check_PROGRAMS)))
|
||||
check_PROGRAMS += ftpuploadresume.exe synctime.exe
|
||||
|
||||
.PRECIOUS: %.o
|
||||
|
||||
|
||||
all: $(check_PROGRAMS)
|
||||
|
||||
%.exe: %.o $(curl_DEPENDENCIES)
|
||||
$(CC) $(LDFLAGS) -o $@ $< $(curl_LDADD)
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(INCLUDES) $(CFLAGS) -c $<
|
||||
|
||||
%.res: %.rc
|
||||
$(RC) $(RCFLAGS) -i $< -o $@
|
||||
|
||||
clean:
|
||||
@$(call DEL, $(check_PROGRAMS:.exe=.o))
|
||||
|
||||
distclean vclean: clean
|
||||
@$(call DEL, $(check_PROGRAMS))
|
||||
40
Engine/lib/curl/docs/examples/README.md
Normal file
40
Engine/lib/curl/docs/examples/README.md
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<!--
|
||||
Copyright (C) 1998 - 2022 Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
|
||||
SPDX-License-Identifier: curl
|
||||
-->
|
||||
|
||||
# libcurl examples
|
||||
|
||||
This directory is for libcurl programming examples. They are meant to show
|
||||
some simple steps on how you can build your own application to take full
|
||||
advantage of libcurl.
|
||||
|
||||
If you end up with other small but still useful example sources, please mail
|
||||
them for submission in future packages and on the website.
|
||||
|
||||
## Building
|
||||
|
||||
The Makefile.example is an example makefile that could be used to build these
|
||||
examples. Just edit the file according to your system and requirements first.
|
||||
|
||||
Most examples should build fine using a command line like this:
|
||||
|
||||
`curl-config --cc --cflags --libs` -o example example.c
|
||||
|
||||
Some compilers do not like having the arguments in this order but instead
|
||||
want you do reorganize them like:
|
||||
|
||||
`curl-config --cc` -o example example.c `curl-config --cflags --libs`
|
||||
|
||||
**Please** do not use the `curl.se` site as a test target for your
|
||||
libcurl applications/experiments. Even if some of the examples use that site
|
||||
as a URL at some places, it does not mean that the URLs work or that we expect
|
||||
you to actually torture our website with your tests! Thanks.
|
||||
|
||||
## Examples
|
||||
|
||||
Each example source code file is designed to be and work stand-alone and
|
||||
rather self-explanatory. The examples may at times lack the level of error
|
||||
checks you need in a real world, but that is then only for the sake of
|
||||
readability: to make the code smaller and easier to follow.
|
||||
58
Engine/lib/curl/docs/examples/altsvc.c
Normal file
58
Engine/lib/curl/docs/examples/altsvc.c
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* HTTP with Alt-Svc support
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
|
||||
|
||||
/* cache the alternatives in this file */
|
||||
curl_easy_setopt(curl, CURLOPT_ALTSVC, "altsvc.txt");
|
||||
|
||||
/* restrict which HTTP versions to use alternatives */
|
||||
curl_easy_setopt(curl, CURLOPT_ALTSVC_CTRL, (long)
|
||||
CURLALTSVC_H1|CURLALTSVC_H2|CURLALTSVC_H3);
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
173
Engine/lib/curl/docs/examples/anyauthput.c
Normal file
173
Engine/lib/curl/docs/examples/anyauthput.c
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* HTTP PUT upload with authentication using "any" method. libcurl picks the
|
||||
* one the server supports/wants.
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifdef WIN32
|
||||
# include <io.h>
|
||||
# define READ_3RD_ARG unsigned int
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# define READ_3RD_ARG size_t
|
||||
#endif
|
||||
|
||||
#if LIBCURL_VERSION_NUM < 0x070c03
|
||||
#error "upgrade your libcurl to no less than 7.12.3"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This example shows a HTTP PUT operation with authentication using "any"
|
||||
* type. It PUTs a file given as a command line argument to the URL also given
|
||||
* on the command line.
|
||||
*
|
||||
* Since libcurl 7.12.3, using "any" auth and POST/PUT requires a set ioctl
|
||||
* function.
|
||||
*
|
||||
* This example also uses its own read callback.
|
||||
*/
|
||||
|
||||
/* ioctl callback function */
|
||||
static curlioerr my_ioctl(CURL *handle, curliocmd cmd, void *userp)
|
||||
{
|
||||
int *fdp = (int *)userp;
|
||||
int fd = *fdp;
|
||||
|
||||
(void)handle; /* not used in here */
|
||||
|
||||
switch(cmd) {
|
||||
case CURLIOCMD_RESTARTREAD:
|
||||
/* mr libcurl kindly asks as to rewind the read data stream to start */
|
||||
if(-1 == lseek(fd, 0, SEEK_SET))
|
||||
/* couldn't rewind */
|
||||
return CURLIOE_FAILRESTART;
|
||||
|
||||
break;
|
||||
|
||||
default: /* ignore unknown commands */
|
||||
return CURLIOE_UNKNOWNCMD;
|
||||
}
|
||||
return CURLIOE_OK; /* success! */
|
||||
}
|
||||
|
||||
/* read callback function, fread() look alike */
|
||||
static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
ssize_t retcode;
|
||||
unsigned long nread;
|
||||
|
||||
int *fdp = (int *)stream;
|
||||
int fd = *fdp;
|
||||
|
||||
retcode = read(fd, ptr, (READ_3RD_ARG)(size * nmemb));
|
||||
|
||||
if(retcode > 0) {
|
||||
nread = (unsigned long)retcode;
|
||||
fprintf(stderr, "*** We read %lu bytes from file\n", nread);
|
||||
}
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
int hd;
|
||||
struct stat file_info;
|
||||
|
||||
char *file;
|
||||
char *url;
|
||||
|
||||
if(argc < 3)
|
||||
return 1;
|
||||
|
||||
file = argv[1];
|
||||
url = argv[2];
|
||||
|
||||
/* get the file size of the local file */
|
||||
hd = open(file, O_RDONLY);
|
||||
fstat(hd, &file_info);
|
||||
|
||||
/* In windows, this will init the winsock stuff */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* get a curl handle */
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* we want to use our own read function */
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
|
||||
/* which file to upload */
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, (void *)&hd);
|
||||
|
||||
/* set the ioctl function */
|
||||
curl_easy_setopt(curl, CURLOPT_IOCTLFUNCTION, my_ioctl);
|
||||
|
||||
/* pass the file descriptor to the ioctl callback as well */
|
||||
curl_easy_setopt(curl, CURLOPT_IOCTLDATA, (void *)&hd);
|
||||
|
||||
/* enable "uploading" (which means PUT when doing HTTP) */
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
/* specify target URL, and note that this URL should also include a file
|
||||
name, not only a directory (as you can do with GTP uploads) */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
|
||||
/* and give the size of the upload, this supports large file sizes
|
||||
on systems that have general support for it */
|
||||
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
|
||||
(curl_off_t)file_info.st_size);
|
||||
|
||||
/* tell libcurl we can use "any" auth, which lets the lib pick one, but it
|
||||
also costs one extra round-trip and possibly sending of all the PUT
|
||||
data twice!!! */
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY);
|
||||
|
||||
/* set user name and password for the authentication */
|
||||
curl_easy_setopt(curl, CURLOPT_USERPWD, "user:password");
|
||||
|
||||
/* Now run off and do what you have been told! */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
close(hd); /* close the local file */
|
||||
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
||||
183
Engine/lib/curl/docs/examples/cacertinmem.c
Normal file
183
Engine/lib/curl/docs/examples/cacertinmem.c
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* CA cert in memory with OpenSSL to get a HTTPS page.
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <curl/curl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static size_t writefunction(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
fwrite(ptr, size, nmemb, (FILE *)stream);
|
||||
return (nmemb*size);
|
||||
}
|
||||
|
||||
static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm)
|
||||
{
|
||||
CURLcode rv = CURLE_ABORTED_BY_CALLBACK;
|
||||
|
||||
/** This example uses two (fake) certificates **/
|
||||
static const char mypem[] =
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UE\n"
|
||||
"AwwJQUNDVlJBSVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQsw\n"
|
||||
"CQYDVQQGEwJFUzAeFw0xMTA1MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQ\n"
|
||||
"BgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwHUEtJQUNDVjENMAsGA1UECgwEQUND\n"
|
||||
"VjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCb\n"
|
||||
"qau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gMjmoY\n"
|
||||
"HtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWo\n"
|
||||
"G2ioPej0RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpA\n"
|
||||
"0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDGWuzndN9wrqODJerWx5eH\n"
|
||||
"k6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs78yM2x/47\n"
|
||||
"JyCpZET/LtZ1qmxNYEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+m\n"
|
||||
"AM/EKXMRNt6GGT6d7hmKG9Ww7Y49nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepD\n"
|
||||
"vV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJTS+xJlsndQAJxGJ3KQhfnlms\n"
|
||||
"tn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3sCPdK6jT2iWH\n"
|
||||
"7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h\n"
|
||||
"I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szA\n"
|
||||
"h1xA2syVP1XgNce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xF\n"
|
||||
"d3+YJ5oyXSrjhO7FmGYvliAd3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2H\n"
|
||||
"pPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3pEfbRD0tVNEYqi4Y7\n"
|
||||
"-----END CERTIFICATE-----\n"
|
||||
"-----BEGIN CERTIFICATE-----\n"
|
||||
"MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UE\n"
|
||||
"AwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00x\n"
|
||||
"CzAJBgNVBAYTAkVTMB4XDTA4MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEW\n"
|
||||
"MBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZF\n"
|
||||
"RElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC\n"
|
||||
"AgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHkWLn7\n"
|
||||
"09gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7\n"
|
||||
"XBZXehuDYAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5P\n"
|
||||
"gvoFNTPhNahXwOf9jU8/kzJPeGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKe\n"
|
||||
"I6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1PwkzQSulgUV1qzOMPPKC8W64iLgpq0i\n"
|
||||
"5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1ThCojz2GuHURwCRi\n"
|
||||
"ipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oIKiMn\n"
|
||||
"MCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZ\n"
|
||||
"o5NjEFIqnxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6\n"
|
||||
"zqylfDJKZ0DcMDQj3dcEI2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacN\n"
|
||||
"GHk0vFQYXlPKNFHtRQrmjseCNj6nOGOpMCwXEGCSn1WHElkQwg9naRHMTh5+Spqt\n"
|
||||
"r0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3otkYNbn5XOmeUwssfnHdK\n"
|
||||
"Z05phkOTOPu220+DkdRgfks+KzgHVZhepA==\n"
|
||||
"-----END CERTIFICATE-----\n";
|
||||
|
||||
BIO *cbio = BIO_new_mem_buf(mypem, sizeof(mypem));
|
||||
X509_STORE *cts = SSL_CTX_get_cert_store((SSL_CTX *)sslctx);
|
||||
int i;
|
||||
STACK_OF(X509_INFO) *inf;
|
||||
(void)curl;
|
||||
(void)parm;
|
||||
|
||||
if(!cts || !cbio) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
inf = PEM_X509_INFO_read_bio(cbio, NULL, NULL, NULL);
|
||||
|
||||
if(!inf) {
|
||||
BIO_free(cbio);
|
||||
return rv;
|
||||
}
|
||||
|
||||
for(i = 0; i < sk_X509_INFO_num(inf); i++) {
|
||||
X509_INFO *itmp = sk_X509_INFO_value(inf, i);
|
||||
if(itmp->x509) {
|
||||
X509_STORE_add_cert(cts, itmp->x509);
|
||||
}
|
||||
if(itmp->crl) {
|
||||
X509_STORE_add_crl(cts, itmp->crl);
|
||||
}
|
||||
}
|
||||
|
||||
sk_X509_INFO_pop_free(inf, X509_INFO_free);
|
||||
BIO_free(cbio);
|
||||
|
||||
rv = CURLE_OK;
|
||||
return rv;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *ch;
|
||||
CURLcode rv;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
ch = curl_easy_init();
|
||||
curl_easy_setopt(ch, CURLOPT_VERBOSE, 0L);
|
||||
curl_easy_setopt(ch, CURLOPT_HEADER, 0L);
|
||||
curl_easy_setopt(ch, CURLOPT_NOPROGRESS, 1L);
|
||||
curl_easy_setopt(ch, CURLOPT_NOSIGNAL, 1L);
|
||||
curl_easy_setopt(ch, CURLOPT_WRITEFUNCTION, writefunction);
|
||||
curl_easy_setopt(ch, CURLOPT_WRITEDATA, stdout);
|
||||
curl_easy_setopt(ch, CURLOPT_HEADERFUNCTION, writefunction);
|
||||
curl_easy_setopt(ch, CURLOPT_HEADERDATA, stderr);
|
||||
curl_easy_setopt(ch, CURLOPT_SSLCERTTYPE, "PEM");
|
||||
curl_easy_setopt(ch, CURLOPT_SSL_VERIFYPEER, 1L);
|
||||
curl_easy_setopt(ch, CURLOPT_URL, "https://www.example.com/");
|
||||
|
||||
/* Turn off the default CA locations, otherwise libcurl will load CA
|
||||
* certificates from the locations that were detected/specified at
|
||||
* build-time
|
||||
*/
|
||||
curl_easy_setopt(ch, CURLOPT_CAINFO, NULL);
|
||||
curl_easy_setopt(ch, CURLOPT_CAPATH, NULL);
|
||||
|
||||
/* first try: retrieve page without ca certificates -> should fail
|
||||
* unless libcurl was built --with-ca-fallback enabled at build-time
|
||||
*/
|
||||
rv = curl_easy_perform(ch);
|
||||
if(rv == CURLE_OK)
|
||||
printf("*** transfer succeeded ***\n");
|
||||
else
|
||||
printf("*** transfer failed ***\n");
|
||||
|
||||
/* use a fresh connection (optional)
|
||||
* this option seriously impacts performance of multiple transfers but
|
||||
* it is necessary order to demonstrate this example. recall that the
|
||||
* ssl ctx callback is only called _before_ an SSL connection is
|
||||
* established, therefore it will not affect existing verified SSL
|
||||
* connections already in the connection cache associated with this
|
||||
* handle. normally you would set the ssl ctx function before making
|
||||
* any transfers, and not use this option.
|
||||
*/
|
||||
curl_easy_setopt(ch, CURLOPT_FRESH_CONNECT, 1L);
|
||||
|
||||
/* second try: retrieve page using cacerts' certificate -> will succeed
|
||||
* load the certificate by installing a function doing the necessary
|
||||
* "modifications" to the SSL CONTEXT just before link init
|
||||
*/
|
||||
curl_easy_setopt(ch, CURLOPT_SSL_CTX_FUNCTION, sslctx_function);
|
||||
rv = curl_easy_perform(ch);
|
||||
if(rv == CURLE_OK)
|
||||
printf("*** transfer succeeded ***\n");
|
||||
else
|
||||
printf("*** transfer failed ***\n");
|
||||
|
||||
curl_easy_cleanup(ch);
|
||||
curl_global_cleanup();
|
||||
return rv;
|
||||
}
|
||||
87
Engine/lib/curl/docs/examples/certinfo.c
Normal file
87
Engine/lib/curl/docs/examples/certinfo.c
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Extract lots of TLS certificate info.
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
static size_t wrfu(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
(void)stream;
|
||||
(void)ptr;
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com/");
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, wrfu);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
if(!res) {
|
||||
struct curl_certinfo *certinfo;
|
||||
|
||||
res = curl_easy_getinfo(curl, CURLINFO_CERTINFO, &certinfo);
|
||||
|
||||
if(!res && certinfo) {
|
||||
int i;
|
||||
|
||||
printf("%d certs!\n", certinfo->num_of_certs);
|
||||
|
||||
for(i = 0; i < certinfo->num_of_certs; i++) {
|
||||
struct curl_slist *slist;
|
||||
|
||||
for(slist = certinfo->certinfo[i]; slist; slist = slist->next)
|
||||
printf("%s\n", slist->data);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
215
Engine/lib/curl/docs/examples/chkspeed.c
Normal file
215
Engine/lib/curl/docs/examples/chkspeed.c
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Show transfer timing info after download completes.
|
||||
* </DESC>
|
||||
*/
|
||||
/* Example source code to show how the callback function can be used to
|
||||
* download data into a chunk of memory instead of storing it in a file.
|
||||
* After successful download we use curl_easy_getinfo() calls to get the
|
||||
* amount of downloaded bytes, the time used for the whole download, and
|
||||
* the average download speed.
|
||||
* On Linux you can create the download test files with:
|
||||
* dd if=/dev/urandom of=file_1M.bin bs=1M count=1
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#define URL_BASE "http://speedtest.your.domain/"
|
||||
#define URL_1M URL_BASE "file_1M.bin"
|
||||
#define URL_2M URL_BASE "file_2M.bin"
|
||||
#define URL_5M URL_BASE "file_5M.bin"
|
||||
#define URL_10M URL_BASE "file_10M.bin"
|
||||
#define URL_20M URL_BASE "file_20M.bin"
|
||||
#define URL_50M URL_BASE "file_50M.bin"
|
||||
#define URL_100M URL_BASE "file_100M.bin"
|
||||
|
||||
#define CHKSPEED_VERSION "1.0"
|
||||
|
||||
static size_t WriteCallback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
/* we are not interested in the downloaded bytes itself,
|
||||
so we only return the size we would have saved ... */
|
||||
(void)ptr; /* unused */
|
||||
(void)data; /* unused */
|
||||
return (size_t)(size * nmemb);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
CURL *curl_handle;
|
||||
CURLcode res;
|
||||
int prtall = 0, prtsep = 0, prttime = 0;
|
||||
const char *url = URL_1M;
|
||||
char *appname = argv[0];
|
||||
|
||||
if(argc > 1) {
|
||||
/* parse input parameters */
|
||||
for(argc--, argv++; *argv; argc--, argv++) {
|
||||
if(strncasecmp(*argv, "-", 1) == 0) {
|
||||
if(strncasecmp(*argv, "-H", 2) == 0) {
|
||||
fprintf(stderr,
|
||||
"\rUsage: %s [-m=1|2|5|10|20|50|100] [-t] [-x] [url]\n",
|
||||
appname);
|
||||
exit(1);
|
||||
}
|
||||
else if(strncasecmp(*argv, "-V", 2) == 0) {
|
||||
fprintf(stderr, "\r%s %s - %s\n",
|
||||
appname, CHKSPEED_VERSION, curl_version());
|
||||
exit(1);
|
||||
}
|
||||
else if(strncasecmp(*argv, "-A", 2) == 0) {
|
||||
prtall = 1;
|
||||
}
|
||||
else if(strncasecmp(*argv, "-X", 2) == 0) {
|
||||
prtsep = 1;
|
||||
}
|
||||
else if(strncasecmp(*argv, "-T", 2) == 0) {
|
||||
prttime = 1;
|
||||
}
|
||||
else if(strncasecmp(*argv, "-M=", 3) == 0) {
|
||||
long m = strtol((*argv) + 3, NULL, 10);
|
||||
switch(m) {
|
||||
case 1:
|
||||
url = URL_1M;
|
||||
break;
|
||||
case 2:
|
||||
url = URL_2M;
|
||||
break;
|
||||
case 5:
|
||||
url = URL_5M;
|
||||
break;
|
||||
case 10:
|
||||
url = URL_10M;
|
||||
break;
|
||||
case 20:
|
||||
url = URL_20M;
|
||||
break;
|
||||
case 50:
|
||||
url = URL_50M;
|
||||
break;
|
||||
case 100:
|
||||
url = URL_100M;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "\r%s: invalid parameter %s\n",
|
||||
appname, *argv + 3);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "\r%s: invalid or unknown option %s\n",
|
||||
appname, *argv);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
url = *argv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* print separator line */
|
||||
if(prtsep) {
|
||||
printf("-------------------------------------------------\n");
|
||||
}
|
||||
/* print localtime */
|
||||
if(prttime) {
|
||||
time_t t = time(NULL);
|
||||
printf("Localtime: %s", ctime(&t));
|
||||
}
|
||||
|
||||
/* init libcurl */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* init the curl session */
|
||||
curl_handle = curl_easy_init();
|
||||
|
||||
/* specify URL to get */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_URL, url);
|
||||
|
||||
/* send all data to this function */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteCallback);
|
||||
|
||||
/* some servers do not like requests that are made without a user-agent
|
||||
field, so we provide one */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT,
|
||||
"libcurl-speedchecker/" CHKSPEED_VERSION);
|
||||
|
||||
/* get it! */
|
||||
res = curl_easy_perform(curl_handle);
|
||||
|
||||
if(CURLE_OK == res) {
|
||||
curl_off_t val;
|
||||
|
||||
/* check for bytes downloaded */
|
||||
res = curl_easy_getinfo(curl_handle, CURLINFO_SIZE_DOWNLOAD_T, &val);
|
||||
if((CURLE_OK == res) && (val>0))
|
||||
printf("Data downloaded: %lu bytes.\n", (unsigned long)val);
|
||||
|
||||
/* check for total download time */
|
||||
res = curl_easy_getinfo(curl_handle, CURLINFO_TOTAL_TIME_T, &val);
|
||||
if((CURLE_OK == res) && (val>0))
|
||||
printf("Total download time: %lu.%06lu sec.\n",
|
||||
(unsigned long)(val / 1000000), (unsigned long)(val % 1000000));
|
||||
|
||||
/* check for average download speed */
|
||||
res = curl_easy_getinfo(curl_handle, CURLINFO_SPEED_DOWNLOAD_T, &val);
|
||||
if((CURLE_OK == res) && (val>0))
|
||||
printf("Average download speed: %lu kbyte/sec.\n",
|
||||
(unsigned long)(val / 1024));
|
||||
|
||||
if(prtall) {
|
||||
/* check for name resolution time */
|
||||
res = curl_easy_getinfo(curl_handle, CURLINFO_NAMELOOKUP_TIME_T, &val);
|
||||
if((CURLE_OK == res) && (val>0))
|
||||
printf("Name lookup time: %lu.%06lu sec.\n",
|
||||
(unsigned long)(val / 1000000), (unsigned long)(val % 1000000));
|
||||
|
||||
/* check for connect time */
|
||||
res = curl_easy_getinfo(curl_handle, CURLINFO_CONNECT_TIME_T, &val);
|
||||
if((CURLE_OK == res) && (val>0))
|
||||
printf("Connect time: %lu.%06lu sec.\n",
|
||||
(unsigned long)(val / 1000000), (unsigned long)(val % 1000000));
|
||||
}
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Error while fetching '%s' : %s\n",
|
||||
url, curl_easy_strerror(res));
|
||||
}
|
||||
|
||||
/* cleanup curl stuff */
|
||||
curl_easy_cleanup(curl_handle);
|
||||
|
||||
/* we are done with libcurl, so clean it up */
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
142
Engine/lib/curl/docs/examples/cookie_interface.c
Normal file
142
Engine/lib/curl/docs/examples/cookie_interface.c
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Import and export cookies with COOKIELIST.
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
static void
|
||||
print_cookies(CURL *curl)
|
||||
{
|
||||
CURLcode res;
|
||||
struct curl_slist *cookies;
|
||||
struct curl_slist *nc;
|
||||
int i;
|
||||
|
||||
printf("Cookies, curl knows:\n");
|
||||
res = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies);
|
||||
if(res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl curl_easy_getinfo failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
exit(1);
|
||||
}
|
||||
nc = cookies;
|
||||
i = 1;
|
||||
while(nc) {
|
||||
printf("[%d]: %s\n", i, nc->data);
|
||||
nc = nc->next;
|
||||
i++;
|
||||
}
|
||||
if(i == 1) {
|
||||
printf("(none)\n");
|
||||
}
|
||||
curl_slist_free_all(cookies);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
char nline[512];
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com/");
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_COOKIEFILE, ""); /* start cookie engine */
|
||||
res = curl_easy_perform(curl);
|
||||
if(res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl perform failed: %s\n", curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
print_cookies(curl);
|
||||
|
||||
printf("Erasing curl's knowledge of cookies!\n");
|
||||
curl_easy_setopt(curl, CURLOPT_COOKIELIST, "ALL");
|
||||
|
||||
print_cookies(curl);
|
||||
|
||||
printf("-----------------------------------------------\n"
|
||||
"Setting a cookie \"PREF\" via cookie interface:\n");
|
||||
#ifdef WIN32
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
/* Netscape format cookie */
|
||||
snprintf(nline, sizeof(nline), "%s\t%s\t%s\t%s\t%.0f\t%s\t%s",
|
||||
".example.com", "TRUE", "/", "FALSE",
|
||||
difftime(time(NULL) + 31337, (time_t)0),
|
||||
"PREF", "hello example, i like you very much!");
|
||||
res = curl_easy_setopt(curl, CURLOPT_COOKIELIST, nline);
|
||||
if(res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl curl_easy_setopt failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* HTTP-header style cookie. If you use the Set-Cookie format and do not
|
||||
specify a domain then the cookie is sent for any domain and will not be
|
||||
modified, likely not what you intended. Starting in 7.43.0 any-domain
|
||||
cookies will not be exported either. For more information refer to the
|
||||
CURLOPT_COOKIELIST documentation.
|
||||
*/
|
||||
snprintf(nline, sizeof(nline),
|
||||
"Set-Cookie: OLD_PREF=3d141414bf4209321; "
|
||||
"expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.example.com");
|
||||
res = curl_easy_setopt(curl, CURLOPT_COOKIELIST, nline);
|
||||
if(res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl curl_easy_setopt failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
print_cookies(curl);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
if(res != CURLE_OK) {
|
||||
fprintf(stderr, "Curl perform failed: %s\n", curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "Curl init failed!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
||||
228
Engine/lib/curl/docs/examples/crawler.c
Normal file
228
Engine/lib/curl/docs/examples/crawler.c
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2018 - 2022 Jeroen Ooms <jeroenooms@gmail.com>
|
||||
*
|
||||
* 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 https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
* To compile:
|
||||
* gcc crawler.c $(pkg-config --cflags --libs libxml-2.0 libcurl)
|
||||
*
|
||||
*/
|
||||
/* <DESC>
|
||||
* Web crawler based on curl and libxml2 to stress-test curl with
|
||||
* hundreds of concurrent connections to various servers.
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
/* Parameters */
|
||||
int max_con = 200;
|
||||
int max_total = 20000;
|
||||
int max_requests = 500;
|
||||
int max_link_per_page = 5;
|
||||
int follow_relative_links = 0;
|
||||
char *start_page = "https://www.reuters.com";
|
||||
|
||||
#include <libxml/HTMLparser.h>
|
||||
#include <libxml/xpath.h>
|
||||
#include <libxml/uri.h>
|
||||
#include <curl/curl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <signal.h>
|
||||
|
||||
int pending_interrupt = 0;
|
||||
void sighandler(int dummy)
|
||||
{
|
||||
pending_interrupt = 1;
|
||||
}
|
||||
|
||||
/* resizable buffer */
|
||||
typedef struct {
|
||||
char *buf;
|
||||
size_t size;
|
||||
} memory;
|
||||
|
||||
size_t grow_buffer(void *contents, size_t sz, size_t nmemb, void *ctx)
|
||||
{
|
||||
size_t realsize = sz * nmemb;
|
||||
memory *mem = (memory*) ctx;
|
||||
char *ptr = realloc(mem->buf, mem->size + realsize);
|
||||
if(!ptr) {
|
||||
/* out of memory */
|
||||
printf("not enough memory (realloc returned NULL)\n");
|
||||
return 0;
|
||||
}
|
||||
mem->buf = ptr;
|
||||
memcpy(&(mem->buf[mem->size]), contents, realsize);
|
||||
mem->size += realsize;
|
||||
return realsize;
|
||||
}
|
||||
|
||||
CURL *make_handle(char *url)
|
||||
{
|
||||
CURL *handle = curl_easy_init();
|
||||
|
||||
/* Important: use HTTP2 over HTTPS */
|
||||
curl_easy_setopt(handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS);
|
||||
curl_easy_setopt(handle, CURLOPT_URL, url);
|
||||
|
||||
/* buffer body */
|
||||
memory *mem = malloc(sizeof(memory));
|
||||
mem->size = 0;
|
||||
mem->buf = malloc(1);
|
||||
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, grow_buffer);
|
||||
curl_easy_setopt(handle, CURLOPT_WRITEDATA, mem);
|
||||
curl_easy_setopt(handle, CURLOPT_PRIVATE, mem);
|
||||
|
||||
/* For completeness */
|
||||
curl_easy_setopt(handle, CURLOPT_ACCEPT_ENCODING, "");
|
||||
curl_easy_setopt(handle, CURLOPT_TIMEOUT, 5L);
|
||||
curl_easy_setopt(handle, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(handle, CURLOPT_MAXREDIRS, 10L);
|
||||
curl_easy_setopt(handle, CURLOPT_CONNECTTIMEOUT, 2L);
|
||||
curl_easy_setopt(handle, CURLOPT_COOKIEFILE, "");
|
||||
curl_easy_setopt(handle, CURLOPT_FILETIME, 1L);
|
||||
curl_easy_setopt(handle, CURLOPT_USERAGENT, "mini crawler");
|
||||
curl_easy_setopt(handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
|
||||
curl_easy_setopt(handle, CURLOPT_UNRESTRICTED_AUTH, 1L);
|
||||
curl_easy_setopt(handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
|
||||
curl_easy_setopt(handle, CURLOPT_EXPECT_100_TIMEOUT_MS, 0L);
|
||||
return handle;
|
||||
}
|
||||
|
||||
/* HREF finder implemented in libxml2 but could be any HTML parser */
|
||||
size_t follow_links(CURLM *multi_handle, memory *mem, char *url)
|
||||
{
|
||||
int opts = HTML_PARSE_NOBLANKS | HTML_PARSE_NOERROR | \
|
||||
HTML_PARSE_NOWARNING | HTML_PARSE_NONET;
|
||||
htmlDocPtr doc = htmlReadMemory(mem->buf, mem->size, url, NULL, opts);
|
||||
if(!doc)
|
||||
return 0;
|
||||
xmlChar *xpath = (xmlChar*) "//a/@href";
|
||||
xmlXPathContextPtr context = xmlXPathNewContext(doc);
|
||||
xmlXPathObjectPtr result = xmlXPathEvalExpression(xpath, context);
|
||||
xmlXPathFreeContext(context);
|
||||
if(!result)
|
||||
return 0;
|
||||
xmlNodeSetPtr nodeset = result->nodesetval;
|
||||
if(xmlXPathNodeSetIsEmpty(nodeset)) {
|
||||
xmlXPathFreeObject(result);
|
||||
return 0;
|
||||
}
|
||||
size_t count = 0;
|
||||
int i;
|
||||
for(i = 0; i < nodeset->nodeNr; i++) {
|
||||
double r = rand();
|
||||
int x = r * nodeset->nodeNr / RAND_MAX;
|
||||
const xmlNode *node = nodeset->nodeTab[x]->xmlChildrenNode;
|
||||
xmlChar *href = xmlNodeListGetString(doc, node, 1);
|
||||
if(follow_relative_links) {
|
||||
xmlChar *orig = href;
|
||||
href = xmlBuildURI(href, (xmlChar *) url);
|
||||
xmlFree(orig);
|
||||
}
|
||||
char *link = (char *) href;
|
||||
if(!link || strlen(link) < 20)
|
||||
continue;
|
||||
if(!strncmp(link, "http://", 7) || !strncmp(link, "https://", 8)) {
|
||||
curl_multi_add_handle(multi_handle, make_handle(link));
|
||||
if(count++ == max_link_per_page)
|
||||
break;
|
||||
}
|
||||
xmlFree(link);
|
||||
}
|
||||
xmlXPathFreeObject(result);
|
||||
return count;
|
||||
}
|
||||
|
||||
int is_html(char *ctype)
|
||||
{
|
||||
return ctype != NULL && strlen(ctype) > 10 && strstr(ctype, "text/html");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
signal(SIGINT, sighandler);
|
||||
LIBXML_TEST_VERSION;
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
CURLM *multi_handle = curl_multi_init();
|
||||
curl_multi_setopt(multi_handle, CURLMOPT_MAX_TOTAL_CONNECTIONS, max_con);
|
||||
curl_multi_setopt(multi_handle, CURLMOPT_MAX_HOST_CONNECTIONS, 6L);
|
||||
|
||||
/* enables http/2 if available */
|
||||
#ifdef CURLPIPE_MULTIPLEX
|
||||
curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
|
||||
#endif
|
||||
|
||||
/* sets html start page */
|
||||
curl_multi_add_handle(multi_handle, make_handle(start_page));
|
||||
|
||||
int msgs_left;
|
||||
int pending = 0;
|
||||
int complete = 0;
|
||||
int still_running = 1;
|
||||
while(still_running && !pending_interrupt) {
|
||||
int numfds;
|
||||
curl_multi_wait(multi_handle, NULL, 0, 1000, &numfds);
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
/* See how the transfers went */
|
||||
CURLMsg *m = NULL;
|
||||
while((m = curl_multi_info_read(multi_handle, &msgs_left))) {
|
||||
if(m->msg == CURLMSG_DONE) {
|
||||
CURL *handle = m->easy_handle;
|
||||
char *url;
|
||||
memory *mem;
|
||||
curl_easy_getinfo(handle, CURLINFO_PRIVATE, &mem);
|
||||
curl_easy_getinfo(handle, CURLINFO_EFFECTIVE_URL, &url);
|
||||
if(m->data.result == CURLE_OK) {
|
||||
long res_status;
|
||||
curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &res_status);
|
||||
if(res_status == 200) {
|
||||
char *ctype;
|
||||
curl_easy_getinfo(handle, CURLINFO_CONTENT_TYPE, &ctype);
|
||||
printf("[%d] HTTP 200 (%s): %s\n", complete, ctype, url);
|
||||
if(is_html(ctype) && mem->size > 100) {
|
||||
if(pending < max_requests && (complete + pending) < max_total) {
|
||||
pending += follow_links(multi_handle, mem, url);
|
||||
still_running = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("[%d] HTTP %d: %s\n", complete, (int) res_status, url);
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("[%d] Connection failure: %s\n", complete, url);
|
||||
}
|
||||
curl_multi_remove_handle(multi_handle, handle);
|
||||
curl_easy_cleanup(handle);
|
||||
free(mem->buf);
|
||||
free(mem);
|
||||
complete++;
|
||||
pending--;
|
||||
}
|
||||
}
|
||||
}
|
||||
curl_multi_cleanup(multi_handle);
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
||||
119
Engine/lib/curl/docs/examples/curlgtk.c
Normal file
119
Engine/lib/curl/docs/examples/curlgtk.c
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (c) 2000 - 2022 David Odin (aka DindinX) for MandrakeSoft
|
||||
*
|
||||
* 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 https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* use the libcurl in a gtk-threaded application
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
GtkWidget *Bar;
|
||||
|
||||
static size_t my_write_func(void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
{
|
||||
return fwrite(ptr, size, nmemb, stream);
|
||||
}
|
||||
|
||||
static size_t my_read_func(char *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
{
|
||||
return fread(ptr, size, nmemb, stream);
|
||||
}
|
||||
|
||||
static int my_progress_func(GtkWidget *bar,
|
||||
double t, /* dltotal */
|
||||
double d, /* dlnow */
|
||||
double ultotal,
|
||||
double ulnow)
|
||||
{
|
||||
/* printf("%d / %d (%g %%)\n", d, t, d*100.0/t);*/
|
||||
gdk_threads_enter();
|
||||
gtk_progress_set_value(GTK_PROGRESS(bar), d*100.0/t);
|
||||
gdk_threads_leave();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *my_thread(void *ptr)
|
||||
{
|
||||
CURL *curl;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
gchar *url = ptr;
|
||||
const char *filename = "test.curl";
|
||||
FILE *outfile = fopen(filename, "wb");
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_write_func);
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, my_read_func);
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, my_progress_func);
|
||||
curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, Bar);
|
||||
|
||||
curl_easy_perform(curl);
|
||||
|
||||
fclose(outfile);
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GtkWidget *Window, *Frame, *Frame2;
|
||||
GtkAdjustment *adj;
|
||||
|
||||
/* Must initialize libcurl before any threads are started */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* Init thread */
|
||||
g_thread_init(NULL);
|
||||
|
||||
gtk_init(&argc, &argv);
|
||||
Window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
Frame = gtk_frame_new(NULL);
|
||||
gtk_frame_set_shadow_type(GTK_FRAME(Frame), GTK_SHADOW_OUT);
|
||||
gtk_container_add(GTK_CONTAINER(Window), Frame);
|
||||
Frame2 = gtk_frame_new(NULL);
|
||||
gtk_frame_set_shadow_type(GTK_FRAME(Frame2), GTK_SHADOW_IN);
|
||||
gtk_container_add(GTK_CONTAINER(Frame), Frame2);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(Frame2), 5);
|
||||
adj = (GtkAdjustment*)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
|
||||
Bar = gtk_progress_bar_new_with_adjustment(adj);
|
||||
gtk_container_add(GTK_CONTAINER(Frame2), Bar);
|
||||
gtk_widget_show_all(Window);
|
||||
|
||||
if(!g_thread_create(&my_thread, argv[1], FALSE, NULL) != 0)
|
||||
g_warning("cannot create the thread");
|
||||
|
||||
gdk_threads_enter();
|
||||
gtk_main();
|
||||
gdk_threads_leave();
|
||||
return 0;
|
||||
}
|
||||
156
Engine/lib/curl/docs/examples/debug.c
Normal file
156
Engine/lib/curl/docs/examples/debug.c
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Show how CURLOPT_DEBUGFUNCTION can be used.
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.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, %10.10lu bytes (0x%8.8lx)\n",
|
||||
text, (unsigned long)size, (unsigned long)size);
|
||||
|
||||
for(i = 0; i<size; i += width) {
|
||||
|
||||
fprintf(stream, "%4.4lx: ", (unsigned long)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", data);
|
||||
/* FALLTHROUGH */
|
||||
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;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct data config;
|
||||
|
||||
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);
|
||||
|
||||
/* example.com is redirected, so we tell libcurl to follow redirection */
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
547
Engine/lib/curl/docs/examples/ephiperfifo.c
Normal file
547
Engine/lib/curl/docs/examples/ephiperfifo.c
Normal file
|
|
@ -0,0 +1,547 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* multi socket API usage with epoll and timerfd
|
||||
* </DESC>
|
||||
*/
|
||||
/* Example application source code using the multi socket interface to
|
||||
* download many files at once.
|
||||
*
|
||||
* This example features the same basic functionality as hiperfifo.c does,
|
||||
* but this uses epoll and timerfd instead of libevent.
|
||||
*
|
||||
* Written by Jeff Pohlmeyer, converted to use epoll by Josh Bialkowski
|
||||
|
||||
Requires a linux system with epoll
|
||||
|
||||
When running, the program creates the named pipe "hiper.fifo"
|
||||
|
||||
Whenever there is input into the fifo, the program reads the input as a list
|
||||
of URL's and creates some new easy handles to fetch each URL via the
|
||||
curl_multi "hiper" API.
|
||||
|
||||
|
||||
Thus, you can try a single URL:
|
||||
% echo http://www.yahoo.com > hiper.fifo
|
||||
|
||||
Or a whole bunch of them:
|
||||
% cat my-url-list > hiper.fifo
|
||||
|
||||
The fifo buffer is handled almost instantly, so you can even add more URL's
|
||||
while the previous requests are still being downloaded.
|
||||
|
||||
Note:
|
||||
For the sake of simplicity, URL length is limited to 1023 char's !
|
||||
|
||||
This is purely a demo app, all retrieved data is simply discarded by the write
|
||||
callback.
|
||||
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/timerfd.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */
|
||||
|
||||
|
||||
/* Global information, common to all connections */
|
||||
typedef struct _GlobalInfo
|
||||
{
|
||||
int epfd; /* epoll filedescriptor */
|
||||
int tfd; /* timer filedescriptor */
|
||||
int fifofd; /* fifo filedescriptor */
|
||||
CURLM *multi;
|
||||
int still_running;
|
||||
FILE *input;
|
||||
} GlobalInfo;
|
||||
|
||||
|
||||
/* Information associated with a specific easy handle */
|
||||
typedef struct _ConnInfo
|
||||
{
|
||||
CURL *easy;
|
||||
char *url;
|
||||
GlobalInfo *global;
|
||||
char error[CURL_ERROR_SIZE];
|
||||
} ConnInfo;
|
||||
|
||||
|
||||
/* Information associated with a specific socket */
|
||||
typedef struct _SockInfo
|
||||
{
|
||||
curl_socket_t sockfd;
|
||||
CURL *easy;
|
||||
int action;
|
||||
long timeout;
|
||||
GlobalInfo *global;
|
||||
} SockInfo;
|
||||
|
||||
#define mycase(code) \
|
||||
case code: s = __STRING(code)
|
||||
|
||||
/* Die if we get a bad CURLMcode somewhere */
|
||||
static void mcode_or_die(const char *where, CURLMcode code)
|
||||
{
|
||||
if(CURLM_OK != code) {
|
||||
const char *s;
|
||||
switch(code) {
|
||||
mycase(CURLM_BAD_HANDLE); break;
|
||||
mycase(CURLM_BAD_EASY_HANDLE); break;
|
||||
mycase(CURLM_OUT_OF_MEMORY); break;
|
||||
mycase(CURLM_INTERNAL_ERROR); break;
|
||||
mycase(CURLM_UNKNOWN_OPTION); break;
|
||||
mycase(CURLM_LAST); break;
|
||||
default: s = "CURLM_unknown"; break;
|
||||
mycase(CURLM_BAD_SOCKET);
|
||||
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
|
||||
/* ignore this error */
|
||||
return;
|
||||
}
|
||||
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
|
||||
exit(code);
|
||||
}
|
||||
}
|
||||
|
||||
static void timer_cb(GlobalInfo* g, int revents);
|
||||
|
||||
/* Update the timer after curl_multi library does it's thing. Curl will
|
||||
* inform us through this callback what it wants the new timeout to be,
|
||||
* after it does some work. */
|
||||
static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
|
||||
{
|
||||
struct itimerspec its;
|
||||
|
||||
fprintf(MSG_OUT, "multi_timer_cb: Setting timeout to %ld ms\n", timeout_ms);
|
||||
|
||||
if(timeout_ms > 0) {
|
||||
its.it_interval.tv_sec = 0;
|
||||
its.it_interval.tv_nsec = 0;
|
||||
its.it_value.tv_sec = timeout_ms / 1000;
|
||||
its.it_value.tv_nsec = (timeout_ms % 1000) * 1000 * 1000;
|
||||
}
|
||||
else if(timeout_ms == 0) {
|
||||
/* libcurl wants us to timeout now, however setting both fields of
|
||||
* new_value.it_value to zero disarms the timer. The closest we can
|
||||
* do is to schedule the timer to fire in 1 ns. */
|
||||
its.it_interval.tv_sec = 0;
|
||||
its.it_interval.tv_nsec = 0;
|
||||
its.it_value.tv_sec = 0;
|
||||
its.it_value.tv_nsec = 1;
|
||||
}
|
||||
else {
|
||||
memset(&its, 0, sizeof(struct itimerspec));
|
||||
}
|
||||
|
||||
timerfd_settime(g->tfd, /*flags=*/0, &its, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Check for completed transfers, and remove their easy handles */
|
||||
static void check_multi_info(GlobalInfo *g)
|
||||
{
|
||||
char *eff_url;
|
||||
CURLMsg *msg;
|
||||
int msgs_left;
|
||||
ConnInfo *conn;
|
||||
CURL *easy;
|
||||
CURLcode res;
|
||||
|
||||
fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running);
|
||||
while((msg = curl_multi_info_read(g->multi, &msgs_left))) {
|
||||
if(msg->msg == CURLMSG_DONE) {
|
||||
easy = msg->easy_handle;
|
||||
res = msg->data.result;
|
||||
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
|
||||
curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
|
||||
fprintf(MSG_OUT, "DONE: %s => (%d) %s\n", eff_url, res, conn->error);
|
||||
curl_multi_remove_handle(g->multi, easy);
|
||||
free(conn->url);
|
||||
curl_easy_cleanup(easy);
|
||||
free(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Called by libevent when we get action on a multi socket filedescriptor*/
|
||||
static void event_cb(GlobalInfo *g, int fd, int revents)
|
||||
{
|
||||
CURLMcode rc;
|
||||
struct itimerspec its;
|
||||
|
||||
int action = ((revents & EPOLLIN) ? CURL_CSELECT_IN : 0) |
|
||||
((revents & EPOLLOUT) ? CURL_CSELECT_OUT : 0);
|
||||
|
||||
rc = curl_multi_socket_action(g->multi, fd, action, &g->still_running);
|
||||
mcode_or_die("event_cb: curl_multi_socket_action", rc);
|
||||
|
||||
check_multi_info(g);
|
||||
if(g->still_running <= 0) {
|
||||
fprintf(MSG_OUT, "last transfer done, kill timeout\n");
|
||||
memset(&its, 0, sizeof(struct itimerspec));
|
||||
timerfd_settime(g->tfd, 0, &its, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Called by main loop when our timeout expires */
|
||||
static void timer_cb(GlobalInfo* g, int revents)
|
||||
{
|
||||
CURLMcode rc;
|
||||
uint64_t count = 0;
|
||||
ssize_t err = 0;
|
||||
|
||||
err = read(g->tfd, &count, sizeof(uint64_t));
|
||||
if(err == -1) {
|
||||
/* Note that we may call the timer callback even if the timerfd is not
|
||||
* readable. It's possible that there are multiple events stored in the
|
||||
* epoll buffer (i.e. the timer may have fired multiple times). The
|
||||
* event count is cleared after the first call so future events in the
|
||||
* epoll buffer will fail to read from the timer. */
|
||||
if(errno == EAGAIN) {
|
||||
fprintf(MSG_OUT, "EAGAIN on tfd %d\n", g->tfd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if(err != sizeof(uint64_t)) {
|
||||
fprintf(stderr, "read(tfd) == %ld", err);
|
||||
perror("read(tfd)");
|
||||
}
|
||||
|
||||
rc = curl_multi_socket_action(g->multi,
|
||||
CURL_SOCKET_TIMEOUT, 0, &g->still_running);
|
||||
mcode_or_die("timer_cb: curl_multi_socket_action", rc);
|
||||
check_multi_info(g);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Clean up the SockInfo structure */
|
||||
static void remsock(SockInfo *f, GlobalInfo* g)
|
||||
{
|
||||
if(f) {
|
||||
if(f->sockfd) {
|
||||
if(epoll_ctl(g->epfd, EPOLL_CTL_DEL, f->sockfd, NULL))
|
||||
fprintf(stderr, "EPOLL_CTL_DEL failed for fd: %d : %s\n",
|
||||
f->sockfd, strerror(errno));
|
||||
}
|
||||
free(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Assign information to a SockInfo structure */
|
||||
static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act,
|
||||
GlobalInfo *g)
|
||||
{
|
||||
struct epoll_event ev;
|
||||
int kind = ((act & CURL_POLL_IN) ? EPOLLIN : 0) |
|
||||
((act & CURL_POLL_OUT) ? EPOLLOUT : 0);
|
||||
|
||||
if(f->sockfd) {
|
||||
if(epoll_ctl(g->epfd, EPOLL_CTL_DEL, f->sockfd, NULL))
|
||||
fprintf(stderr, "EPOLL_CTL_DEL failed for fd: %d : %s\n",
|
||||
f->sockfd, strerror(errno));
|
||||
}
|
||||
|
||||
f->sockfd = s;
|
||||
f->action = act;
|
||||
f->easy = e;
|
||||
|
||||
ev.events = kind;
|
||||
ev.data.fd = s;
|
||||
if(epoll_ctl(g->epfd, EPOLL_CTL_ADD, s, &ev))
|
||||
fprintf(stderr, "EPOLL_CTL_ADD failed for fd: %d : %s\n",
|
||||
s, strerror(errno));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Initialize a new SockInfo structure */
|
||||
static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g)
|
||||
{
|
||||
SockInfo *fdp = (SockInfo*)calloc(1, sizeof(SockInfo));
|
||||
|
||||
fdp->global = g;
|
||||
setsock(fdp, s, easy, action, g);
|
||||
curl_multi_assign(g->multi, s, fdp);
|
||||
}
|
||||
|
||||
/* CURLMOPT_SOCKETFUNCTION */
|
||||
static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo*) cbp;
|
||||
SockInfo *fdp = (SockInfo*) sockp;
|
||||
const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" };
|
||||
|
||||
fprintf(MSG_OUT,
|
||||
"socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
|
||||
if(what == CURL_POLL_REMOVE) {
|
||||
fprintf(MSG_OUT, "\n");
|
||||
remsock(fdp, g);
|
||||
}
|
||||
else {
|
||||
if(!fdp) {
|
||||
fprintf(MSG_OUT, "Adding data: %s\n", whatstr[what]);
|
||||
addsock(s, e, what, g);
|
||||
}
|
||||
else {
|
||||
fprintf(MSG_OUT,
|
||||
"Changing action from %s to %s\n",
|
||||
whatstr[fdp->action], whatstr[what]);
|
||||
setsock(fdp, s, e, what, g);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* CURLOPT_WRITEFUNCTION */
|
||||
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
(void)ptr;
|
||||
(void)data;
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
|
||||
/* CURLOPT_PROGRESSFUNCTION */
|
||||
static int prog_cb(void *p, double dltotal, double dlnow, double ult,
|
||||
double uln)
|
||||
{
|
||||
ConnInfo *conn = (ConnInfo *)p;
|
||||
(void)ult;
|
||||
(void)uln;
|
||||
|
||||
fprintf(MSG_OUT, "Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Create a new easy handle, and add it to the global curl_multi */
|
||||
static void new_conn(char *url, GlobalInfo *g)
|
||||
{
|
||||
ConnInfo *conn;
|
||||
CURLMcode rc;
|
||||
|
||||
conn = (ConnInfo*)calloc(1, sizeof(ConnInfo));
|
||||
conn->error[0]='\0';
|
||||
|
||||
conn->easy = curl_easy_init();
|
||||
if(!conn->easy) {
|
||||
fprintf(MSG_OUT, "curl_easy_init() failed, exiting!\n");
|
||||
exit(2);
|
||||
}
|
||||
conn->global = g;
|
||||
conn->url = strdup(url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 3L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 10L);
|
||||
fprintf(MSG_OUT,
|
||||
"Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
|
||||
rc = curl_multi_add_handle(g->multi, conn->easy);
|
||||
mcode_or_die("new_conn: curl_multi_add_handle", rc);
|
||||
|
||||
/* note that the add_handle() will set a time-out to trigger very soon so
|
||||
that the necessary socket_action() call will be called by this app */
|
||||
}
|
||||
|
||||
/* This gets called whenever data is received from the fifo */
|
||||
static void fifo_cb(GlobalInfo* g, int revents)
|
||||
{
|
||||
char s[1024];
|
||||
long int rv = 0;
|
||||
int n = 0;
|
||||
|
||||
do {
|
||||
s[0]='\0';
|
||||
rv = fscanf(g->input, "%1023s%n", s, &n);
|
||||
s[n]='\0';
|
||||
if(n && s[0]) {
|
||||
new_conn(s, g); /* if we read a URL, go get it! */
|
||||
}
|
||||
else
|
||||
break;
|
||||
} while(rv != EOF);
|
||||
}
|
||||
|
||||
/* Create a named pipe and tell libevent to monitor it */
|
||||
static const char *fifo = "hiper.fifo";
|
||||
static int init_fifo(GlobalInfo *g)
|
||||
{
|
||||
struct stat st;
|
||||
curl_socket_t sockfd;
|
||||
struct epoll_event epev;
|
||||
|
||||
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
|
||||
if(lstat (fifo, &st) == 0) {
|
||||
if((st.st_mode & S_IFMT) == S_IFREG) {
|
||||
errno = EEXIST;
|
||||
perror("lstat");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
unlink(fifo);
|
||||
if(mkfifo (fifo, 0600) == -1) {
|
||||
perror("mkfifo");
|
||||
exit(1);
|
||||
}
|
||||
sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
|
||||
if(sockfd == -1) {
|
||||
perror("open");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
g->fifofd = sockfd;
|
||||
g->input = fdopen(sockfd, "r");
|
||||
|
||||
epev.events = EPOLLIN;
|
||||
epev.data.fd = sockfd;
|
||||
epoll_ctl(g->epfd, EPOLL_CTL_ADD, sockfd, &epev);
|
||||
|
||||
fprintf(MSG_OUT, "Now, pipe some URL's into > %s\n", fifo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void clean_fifo(GlobalInfo *g)
|
||||
{
|
||||
epoll_ctl(g->epfd, EPOLL_CTL_DEL, g->fifofd, NULL);
|
||||
fclose(g->input);
|
||||
unlink(fifo);
|
||||
}
|
||||
|
||||
|
||||
int g_should_exit_ = 0;
|
||||
|
||||
void sigint_handler(int signo)
|
||||
{
|
||||
g_should_exit_ = 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GlobalInfo g;
|
||||
struct itimerspec its;
|
||||
struct epoll_event ev;
|
||||
struct epoll_event events[10];
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
g_should_exit_ = 0;
|
||||
signal(SIGINT, sigint_handler);
|
||||
|
||||
memset(&g, 0, sizeof(GlobalInfo));
|
||||
g.epfd = epoll_create1(EPOLL_CLOEXEC);
|
||||
if(g.epfd == -1) {
|
||||
perror("epoll_create1 failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
g.tfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
|
||||
if(g.tfd == -1) {
|
||||
perror("timerfd_create failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&its, 0, sizeof(struct itimerspec));
|
||||
its.it_interval.tv_sec = 0;
|
||||
its.it_value.tv_sec = 1;
|
||||
timerfd_settime(g.tfd, 0, &its, NULL);
|
||||
|
||||
ev.events = EPOLLIN;
|
||||
ev.data.fd = g.tfd;
|
||||
epoll_ctl(g.epfd, EPOLL_CTL_ADD, g.tfd, &ev);
|
||||
|
||||
init_fifo(&g);
|
||||
g.multi = curl_multi_init();
|
||||
|
||||
/* setup the generic multi interface options we want */
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g);
|
||||
|
||||
/* we do not call any curl_multi_socket*() function yet as we have no handles
|
||||
added! */
|
||||
|
||||
fprintf(MSG_OUT, "Entering wait loop\n");
|
||||
fflush(MSG_OUT);
|
||||
while(!g_should_exit_) {
|
||||
int idx;
|
||||
int err = epoll_wait(g.epfd, events,
|
||||
sizeof(events)/sizeof(struct epoll_event), 10000);
|
||||
if(err == -1) {
|
||||
if(errno == EINTR) {
|
||||
fprintf(MSG_OUT, "note: wait interrupted\n");
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
perror("epoll_wait");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
for(idx = 0; idx < err; ++idx) {
|
||||
if(events[idx].data.fd == g.fifofd) {
|
||||
fifo_cb(&g, events[idx].events);
|
||||
}
|
||||
else if(events[idx].data.fd == g.tfd) {
|
||||
timer_cb(&g, events[idx].events);
|
||||
}
|
||||
else {
|
||||
event_cb(&g, events[idx].data.fd, events[idx].events);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(MSG_OUT, "Exiting normally.\n");
|
||||
fflush(MSG_OUT);
|
||||
|
||||
curl_multi_cleanup(g.multi);
|
||||
clean_fifo(&g);
|
||||
return 0;
|
||||
}
|
||||
450
Engine/lib/curl/docs/examples/evhiperfifo.c
Normal file
450
Engine/lib/curl/docs/examples/evhiperfifo.c
Normal file
|
|
@ -0,0 +1,450 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* multi socket interface together with libev
|
||||
* </DESC>
|
||||
*/
|
||||
/* Example application source code using the multi socket interface to
|
||||
* download many files at once.
|
||||
*
|
||||
* This example features the same basic functionality as hiperfifo.c does,
|
||||
* but this uses libev instead of libevent.
|
||||
*
|
||||
* Written by Jeff Pohlmeyer, converted to use libev by Markus Koetter
|
||||
|
||||
Requires libev and a (POSIX?) system that has mkfifo().
|
||||
|
||||
This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c"
|
||||
sample programs.
|
||||
|
||||
When running, the program creates the named pipe "hiper.fifo"
|
||||
|
||||
Whenever there is input into the fifo, the program reads the input as a list
|
||||
of URL's and creates some new easy handles to fetch each URL via the
|
||||
curl_multi "hiper" API.
|
||||
|
||||
|
||||
Thus, you can try a single URL:
|
||||
% echo http://www.yahoo.com > hiper.fifo
|
||||
|
||||
Or a whole bunch of them:
|
||||
% cat my-url-list > hiper.fifo
|
||||
|
||||
The fifo buffer is handled almost instantly, so you can even add more URL's
|
||||
while the previous requests are still being downloaded.
|
||||
|
||||
Note:
|
||||
For the sake of simplicity, URL length is limited to 1023 char's !
|
||||
|
||||
This is purely a demo app, all retrieved data is simply discarded by the write
|
||||
callback.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/poll.h>
|
||||
#include <curl/curl.h>
|
||||
#include <ev.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define DPRINT(x...) printf(x)
|
||||
|
||||
#define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */
|
||||
|
||||
|
||||
/* Global information, common to all connections */
|
||||
typedef struct _GlobalInfo
|
||||
{
|
||||
struct ev_loop *loop;
|
||||
struct ev_io fifo_event;
|
||||
struct ev_timer timer_event;
|
||||
CURLM *multi;
|
||||
int still_running;
|
||||
FILE *input;
|
||||
} GlobalInfo;
|
||||
|
||||
|
||||
/* Information associated with a specific easy handle */
|
||||
typedef struct _ConnInfo
|
||||
{
|
||||
CURL *easy;
|
||||
char *url;
|
||||
GlobalInfo *global;
|
||||
char error[CURL_ERROR_SIZE];
|
||||
} ConnInfo;
|
||||
|
||||
|
||||
/* Information associated with a specific socket */
|
||||
typedef struct _SockInfo
|
||||
{
|
||||
curl_socket_t sockfd;
|
||||
CURL *easy;
|
||||
int action;
|
||||
long timeout;
|
||||
struct ev_io ev;
|
||||
int evset;
|
||||
GlobalInfo *global;
|
||||
} SockInfo;
|
||||
|
||||
static void timer_cb(EV_P_ struct ev_timer *w, int revents);
|
||||
|
||||
/* Update the event timer after curl_multi library calls */
|
||||
static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
|
||||
{
|
||||
DPRINT("%s %li\n", __PRETTY_FUNCTION__, timeout_ms);
|
||||
ev_timer_stop(g->loop, &g->timer_event);
|
||||
if(timeout_ms >= 0) {
|
||||
/* -1 means delete, other values are timeout times in milliseconds */
|
||||
double t = timeout_ms / 1000;
|
||||
ev_timer_init(&g->timer_event, timer_cb, t, 0.);
|
||||
ev_timer_start(g->loop, &g->timer_event);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Die if we get a bad CURLMcode somewhere */
|
||||
static void mcode_or_die(const char *where, CURLMcode code)
|
||||
{
|
||||
if(CURLM_OK != code) {
|
||||
const char *s;
|
||||
switch(code) {
|
||||
case CURLM_BAD_HANDLE:
|
||||
s = "CURLM_BAD_HANDLE";
|
||||
break;
|
||||
case CURLM_BAD_EASY_HANDLE:
|
||||
s = "CURLM_BAD_EASY_HANDLE";
|
||||
break;
|
||||
case CURLM_OUT_OF_MEMORY:
|
||||
s = "CURLM_OUT_OF_MEMORY";
|
||||
break;
|
||||
case CURLM_INTERNAL_ERROR:
|
||||
s = "CURLM_INTERNAL_ERROR";
|
||||
break;
|
||||
case CURLM_UNKNOWN_OPTION:
|
||||
s = "CURLM_UNKNOWN_OPTION";
|
||||
break;
|
||||
case CURLM_LAST:
|
||||
s = "CURLM_LAST";
|
||||
break;
|
||||
default:
|
||||
s = "CURLM_unknown";
|
||||
break;
|
||||
case CURLM_BAD_SOCKET:
|
||||
s = "CURLM_BAD_SOCKET";
|
||||
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
|
||||
/* ignore this error */
|
||||
return;
|
||||
}
|
||||
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
|
||||
exit(code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Check for completed transfers, and remove their easy handles */
|
||||
static void check_multi_info(GlobalInfo *g)
|
||||
{
|
||||
char *eff_url;
|
||||
CURLMsg *msg;
|
||||
int msgs_left;
|
||||
ConnInfo *conn;
|
||||
CURL *easy;
|
||||
CURLcode res;
|
||||
|
||||
fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running);
|
||||
while((msg = curl_multi_info_read(g->multi, &msgs_left))) {
|
||||
if(msg->msg == CURLMSG_DONE) {
|
||||
easy = msg->easy_handle;
|
||||
res = msg->data.result;
|
||||
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
|
||||
curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
|
||||
fprintf(MSG_OUT, "DONE: %s => (%d) %s\n", eff_url, res, conn->error);
|
||||
curl_multi_remove_handle(g->multi, easy);
|
||||
free(conn->url);
|
||||
curl_easy_cleanup(easy);
|
||||
free(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Called by libevent when we get action on a multi socket */
|
||||
static void event_cb(EV_P_ struct ev_io *w, int revents)
|
||||
{
|
||||
DPRINT("%s w %p revents %i\n", __PRETTY_FUNCTION__, w, revents);
|
||||
GlobalInfo *g = (GlobalInfo*) w->data;
|
||||
CURLMcode rc;
|
||||
|
||||
int action = ((revents & EV_READ) ? CURL_POLL_IN : 0) |
|
||||
((revents & EV_WRITE) ? CURL_POLL_OUT : 0);
|
||||
rc = curl_multi_socket_action(g->multi, w->fd, action, &g->still_running);
|
||||
mcode_or_die("event_cb: curl_multi_socket_action", rc);
|
||||
check_multi_info(g);
|
||||
if(g->still_running <= 0) {
|
||||
fprintf(MSG_OUT, "last transfer done, kill timeout\n");
|
||||
ev_timer_stop(g->loop, &g->timer_event);
|
||||
}
|
||||
}
|
||||
|
||||
/* Called by libevent when our timeout expires */
|
||||
static void timer_cb(EV_P_ struct ev_timer *w, int revents)
|
||||
{
|
||||
DPRINT("%s w %p revents %i\n", __PRETTY_FUNCTION__, w, revents);
|
||||
|
||||
GlobalInfo *g = (GlobalInfo *)w->data;
|
||||
CURLMcode rc;
|
||||
|
||||
rc = curl_multi_socket_action(g->multi, CURL_SOCKET_TIMEOUT, 0,
|
||||
&g->still_running);
|
||||
mcode_or_die("timer_cb: curl_multi_socket_action", rc);
|
||||
check_multi_info(g);
|
||||
}
|
||||
|
||||
/* Clean up the SockInfo structure */
|
||||
static void remsock(SockInfo *f, GlobalInfo *g)
|
||||
{
|
||||
printf("%s \n", __PRETTY_FUNCTION__);
|
||||
if(f) {
|
||||
if(f->evset)
|
||||
ev_io_stop(g->loop, &f->ev);
|
||||
free(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Assign information to a SockInfo structure */
|
||||
static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act,
|
||||
GlobalInfo *g)
|
||||
{
|
||||
printf("%s \n", __PRETTY_FUNCTION__);
|
||||
|
||||
int kind = ((act & CURL_POLL_IN) ? EV_READ : 0) |
|
||||
((act & CURL_POLL_OUT) ? EV_WRITE : 0);
|
||||
|
||||
f->sockfd = s;
|
||||
f->action = act;
|
||||
f->easy = e;
|
||||
if(f->evset)
|
||||
ev_io_stop(g->loop, &f->ev);
|
||||
ev_io_init(&f->ev, event_cb, f->sockfd, kind);
|
||||
f->ev.data = g;
|
||||
f->evset = 1;
|
||||
ev_io_start(g->loop, &f->ev);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Initialize a new SockInfo structure */
|
||||
static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g)
|
||||
{
|
||||
SockInfo *fdp = calloc(1, sizeof(SockInfo));
|
||||
|
||||
fdp->global = g;
|
||||
setsock(fdp, s, easy, action, g);
|
||||
curl_multi_assign(g->multi, s, fdp);
|
||||
}
|
||||
|
||||
/* CURLMOPT_SOCKETFUNCTION */
|
||||
static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
|
||||
{
|
||||
DPRINT("%s e %p s %i what %i cbp %p sockp %p\n",
|
||||
__PRETTY_FUNCTION__, e, s, what, cbp, sockp);
|
||||
|
||||
GlobalInfo *g = (GlobalInfo*) cbp;
|
||||
SockInfo *fdp = (SockInfo*) sockp;
|
||||
const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE"};
|
||||
|
||||
fprintf(MSG_OUT,
|
||||
"socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
|
||||
if(what == CURL_POLL_REMOVE) {
|
||||
fprintf(MSG_OUT, "\n");
|
||||
remsock(fdp, g);
|
||||
}
|
||||
else {
|
||||
if(!fdp) {
|
||||
fprintf(MSG_OUT, "Adding data: %s\n", whatstr[what]);
|
||||
addsock(s, e, what, g);
|
||||
}
|
||||
else {
|
||||
fprintf(MSG_OUT,
|
||||
"Changing action from %s to %s\n",
|
||||
whatstr[fdp->action], whatstr[what]);
|
||||
setsock(fdp, s, e, what, g);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* CURLOPT_WRITEFUNCTION */
|
||||
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
ConnInfo *conn = (ConnInfo*) data;
|
||||
(void)ptr;
|
||||
(void)conn;
|
||||
return realsize;
|
||||
}
|
||||
|
||||
|
||||
/* CURLOPT_PROGRESSFUNCTION */
|
||||
static int prog_cb(void *p, double dltotal, double dlnow, double ult,
|
||||
double uln)
|
||||
{
|
||||
ConnInfo *conn = (ConnInfo *)p;
|
||||
(void)ult;
|
||||
(void)uln;
|
||||
|
||||
fprintf(MSG_OUT, "Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Create a new easy handle, and add it to the global curl_multi */
|
||||
static void new_conn(char *url, GlobalInfo *g)
|
||||
{
|
||||
ConnInfo *conn;
|
||||
CURLMcode rc;
|
||||
|
||||
conn = calloc(1, sizeof(ConnInfo));
|
||||
conn->error[0]='\0';
|
||||
|
||||
conn->easy = curl_easy_init();
|
||||
if(!conn->easy) {
|
||||
fprintf(MSG_OUT, "curl_easy_init() failed, exiting!\n");
|
||||
exit(2);
|
||||
}
|
||||
conn->global = g;
|
||||
conn->url = strdup(url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 3L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 10L);
|
||||
|
||||
fprintf(MSG_OUT,
|
||||
"Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
|
||||
rc = curl_multi_add_handle(g->multi, conn->easy);
|
||||
mcode_or_die("new_conn: curl_multi_add_handle", rc);
|
||||
|
||||
/* note that the add_handle() will set a time-out to trigger very soon so
|
||||
that the necessary socket_action() call will be called by this app */
|
||||
}
|
||||
|
||||
/* This gets called whenever data is received from the fifo */
|
||||
static void fifo_cb(EV_P_ struct ev_io *w, int revents)
|
||||
{
|
||||
char s[1024];
|
||||
long int rv = 0;
|
||||
int n = 0;
|
||||
GlobalInfo *g = (GlobalInfo *)w->data;
|
||||
|
||||
do {
|
||||
s[0]='\0';
|
||||
rv = fscanf(g->input, "%1023s%n", s, &n);
|
||||
s[n]='\0';
|
||||
if(n && s[0]) {
|
||||
new_conn(s, g); /* if we read a URL, go get it! */
|
||||
}
|
||||
else
|
||||
break;
|
||||
} while(rv != EOF);
|
||||
}
|
||||
|
||||
/* Create a named pipe and tell libevent to monitor it */
|
||||
static int init_fifo(GlobalInfo *g)
|
||||
{
|
||||
struct stat st;
|
||||
static const char *fifo = "hiper.fifo";
|
||||
curl_socket_t sockfd;
|
||||
|
||||
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
|
||||
if(lstat (fifo, &st) == 0) {
|
||||
if((st.st_mode & S_IFMT) == S_IFREG) {
|
||||
errno = EEXIST;
|
||||
perror("lstat");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
unlink(fifo);
|
||||
if(mkfifo (fifo, 0600) == -1) {
|
||||
perror("mkfifo");
|
||||
exit(1);
|
||||
}
|
||||
sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
|
||||
if(sockfd == -1) {
|
||||
perror("open");
|
||||
exit(1);
|
||||
}
|
||||
g->input = fdopen(sockfd, "r");
|
||||
|
||||
fprintf(MSG_OUT, "Now, pipe some URL's into > %s\n", fifo);
|
||||
ev_io_init(&g->fifo_event, fifo_cb, sockfd, EV_READ);
|
||||
ev_io_start(g->loop, &g->fifo_event);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GlobalInfo g;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
memset(&g, 0, sizeof(GlobalInfo));
|
||||
g.loop = ev_default_loop(0);
|
||||
|
||||
init_fifo(&g);
|
||||
g.multi = curl_multi_init();
|
||||
|
||||
ev_timer_init(&g.timer_event, timer_cb, 0., 0.);
|
||||
g.timer_event.data = &g;
|
||||
g.fifo_event.data = &g;
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g);
|
||||
|
||||
/* we do not call any curl_multi_socket*() function yet as we have no handles
|
||||
added! */
|
||||
|
||||
ev_loop(g.loop, 0);
|
||||
curl_multi_cleanup(g.multi);
|
||||
return 0;
|
||||
}
|
||||
176
Engine/lib/curl/docs/examples/externalsocket.c
Normal file
176
Engine/lib/curl/docs/examples/externalsocket.c
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* An example demonstrating how an application can pass in a custom
|
||||
* socket to libcurl to use. This example also handles the connect itself.
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#define close closesocket
|
||||
#else
|
||||
#include <sys/types.h> /* socket types */
|
||||
#include <sys/socket.h> /* socket definitions */
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h> /* inet (3) functions */
|
||||
#include <unistd.h> /* misc. Unix functions */
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/* The IP address and port number to connect to */
|
||||
#define IPADDR "127.0.0.1"
|
||||
#define PORTNUM 80
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE 0xffffffff
|
||||
#endif
|
||||
|
||||
static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
size_t written = fwrite(ptr, size, nmemb, (FILE *)stream);
|
||||
return written;
|
||||
}
|
||||
|
||||
static int closecb(void *clientp, curl_socket_t item)
|
||||
{
|
||||
(void)clientp;
|
||||
printf("libcurl wants to close %d now\n", (int)item);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static curl_socket_t opensocket(void *clientp,
|
||||
curlsocktype purpose,
|
||||
struct curl_sockaddr *address)
|
||||
{
|
||||
curl_socket_t sockfd;
|
||||
(void)purpose;
|
||||
(void)address;
|
||||
sockfd = *(curl_socket_t *)clientp;
|
||||
/* the actual externally set socket is passed in via the OPENSOCKETDATA
|
||||
option */
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
static int sockopt_callback(void *clientp, curl_socket_t curlfd,
|
||||
curlsocktype purpose)
|
||||
{
|
||||
(void)clientp;
|
||||
(void)curlfd;
|
||||
(void)purpose;
|
||||
/* This return code was added in libcurl 7.21.5 */
|
||||
return CURL_SOCKOPT_ALREADY_CONNECTED;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct sockaddr_in servaddr; /* socket address structure */
|
||||
curl_socket_t sockfd;
|
||||
|
||||
#ifdef WIN32
|
||||
WSADATA wsaData;
|
||||
int initwsa = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
if(initwsa) {
|
||||
printf("WSAStartup failed: %d\n", initwsa);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/*
|
||||
* Note that libcurl will internally think that you connect to the host
|
||||
* and port that you specify in the URL option.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://99.99.99.99:9999");
|
||||
|
||||
/* Create the socket "manually" */
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(sockfd == CURL_SOCKET_BAD) {
|
||||
printf("Error creating listening socket.\n");
|
||||
return 3;
|
||||
}
|
||||
|
||||
memset(&servaddr, 0, sizeof(servaddr));
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_port = htons(PORTNUM);
|
||||
|
||||
servaddr.sin_addr.s_addr = inet_addr(IPADDR);
|
||||
if(INADDR_NONE == servaddr.sin_addr.s_addr) {
|
||||
close(sockfd);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if(connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) ==
|
||||
-1) {
|
||||
close(sockfd);
|
||||
printf("client error: connect: %s\n", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* no progress meter please */
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
|
||||
|
||||
/* send all data to this function */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
|
||||
|
||||
/* call this function to get a socket */
|
||||
curl_easy_setopt(curl, CURLOPT_OPENSOCKETFUNCTION, opensocket);
|
||||
curl_easy_setopt(curl, CURLOPT_OPENSOCKETDATA, &sockfd);
|
||||
|
||||
/* call this function to close sockets */
|
||||
curl_easy_setopt(curl, CURLOPT_CLOSESOCKETFUNCTION, closecb);
|
||||
curl_easy_setopt(curl, CURLOPT_CLOSESOCKETDATA, &sockfd);
|
||||
|
||||
/* call this function to set options for the socket */
|
||||
curl_easy_setopt(curl, CURLOPT_SOCKOPTFUNCTION, sockopt_callback);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
close(sockfd);
|
||||
|
||||
if(res) {
|
||||
printf("libcurl error: %d\n", res);
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
89
Engine/lib/curl/docs/examples/fileupload.c
Normal file
89
Engine/lib/curl/docs/examples/fileupload.c
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Upload to a file:// URL
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct stat file_info;
|
||||
curl_off_t speed_upload, total_time;
|
||||
FILE *fd;
|
||||
|
||||
fd = fopen("debugit", "rb"); /* open file to upload */
|
||||
if(!fd)
|
||||
return 1; /* cannot continue */
|
||||
|
||||
/* to get the file size */
|
||||
if(fstat(fileno(fd), &file_info) != 0)
|
||||
return 1; /* cannot continue */
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* upload to this place */
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"file:///home/dast/src/curl/debug/new");
|
||||
|
||||
/* tell it to "upload" to the URL */
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
/* set where to read from (on Windows you need to use READFUNCTION too) */
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, fd);
|
||||
|
||||
/* and give the size of the upload (optional) */
|
||||
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
|
||||
(curl_off_t)file_info.st_size);
|
||||
|
||||
/* enable verbose for easier tracing */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK) {
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
}
|
||||
else {
|
||||
/* now extract transfer info */
|
||||
curl_easy_getinfo(curl, CURLINFO_SPEED_UPLOAD_T, &speed_upload);
|
||||
curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME_T, &total_time);
|
||||
|
||||
fprintf(stderr, "Speed: %lu bytes/sec during %lu.%06lu seconds\n",
|
||||
(unsigned long)speed_upload,
|
||||
(unsigned long)(total_time / 1000000),
|
||||
(unsigned long)(total_time % 1000000));
|
||||
}
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
fclose(fd);
|
||||
return 0;
|
||||
}
|
||||
152
Engine/lib/curl/docs/examples/ftp-wildcard.c
Normal file
152
Engine/lib/curl/docs/examples/ftp-wildcard.c
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* FTP wildcard pattern matching
|
||||
* </DESC>
|
||||
*/
|
||||
#include <curl/curl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct callback_data {
|
||||
FILE *output;
|
||||
};
|
||||
|
||||
static long file_is_coming(struct curl_fileinfo *finfo,
|
||||
struct callback_data *data,
|
||||
int remains);
|
||||
|
||||
static long file_is_downloaded(struct callback_data *data);
|
||||
|
||||
static size_t write_it(char *buff, size_t size, size_t nmemb,
|
||||
void *cb_data);
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* curl easy handle */
|
||||
CURL *handle;
|
||||
|
||||
/* help data */
|
||||
struct callback_data data = { 0 };
|
||||
|
||||
/* global initialization */
|
||||
int rc = curl_global_init(CURL_GLOBAL_ALL);
|
||||
if(rc)
|
||||
return rc;
|
||||
|
||||
/* initialization of easy handle */
|
||||
handle = curl_easy_init();
|
||||
if(!handle) {
|
||||
curl_global_cleanup();
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* turn on wildcard matching */
|
||||
curl_easy_setopt(handle, CURLOPT_WILDCARDMATCH, 1L);
|
||||
|
||||
/* callback is called before download of concrete file started */
|
||||
curl_easy_setopt(handle, CURLOPT_CHUNK_BGN_FUNCTION, file_is_coming);
|
||||
|
||||
/* callback is called after data from the file have been transferred */
|
||||
curl_easy_setopt(handle, CURLOPT_CHUNK_END_FUNCTION, file_is_downloaded);
|
||||
|
||||
/* this callback will write contents into files */
|
||||
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_it);
|
||||
|
||||
/* put transfer data into callbacks */
|
||||
curl_easy_setopt(handle, CURLOPT_CHUNK_DATA, &data);
|
||||
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &data);
|
||||
|
||||
/* curl_easy_setopt(handle, CURLOPT_VERBOSE, 1L); */
|
||||
|
||||
/* set an URL containing wildcard pattern (only in the last part) */
|
||||
if(argc == 2)
|
||||
curl_easy_setopt(handle, CURLOPT_URL, argv[1]);
|
||||
else
|
||||
curl_easy_setopt(handle, CURLOPT_URL, "ftp://example.com/test/*");
|
||||
|
||||
/* and start transfer! */
|
||||
rc = curl_easy_perform(handle);
|
||||
|
||||
curl_easy_cleanup(handle);
|
||||
curl_global_cleanup();
|
||||
return rc;
|
||||
}
|
||||
|
||||
static long file_is_coming(struct curl_fileinfo *finfo,
|
||||
struct callback_data *data,
|
||||
int remains)
|
||||
{
|
||||
printf("%3d %40s %10luB ", remains, finfo->filename,
|
||||
(unsigned long)finfo->size);
|
||||
|
||||
switch(finfo->filetype) {
|
||||
case CURLFILETYPE_DIRECTORY:
|
||||
printf(" DIR\n");
|
||||
break;
|
||||
case CURLFILETYPE_FILE:
|
||||
printf("FILE ");
|
||||
break;
|
||||
default:
|
||||
printf("OTHER\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if(finfo->filetype == CURLFILETYPE_FILE) {
|
||||
/* do not transfer files >= 50B */
|
||||
if(finfo->size > 50) {
|
||||
printf("SKIPPED\n");
|
||||
return CURL_CHUNK_BGN_FUNC_SKIP;
|
||||
}
|
||||
|
||||
data->output = fopen(finfo->filename, "wb");
|
||||
if(!data->output) {
|
||||
return CURL_CHUNK_BGN_FUNC_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
return CURL_CHUNK_BGN_FUNC_OK;
|
||||
}
|
||||
|
||||
static long file_is_downloaded(struct callback_data *data)
|
||||
{
|
||||
if(data->output) {
|
||||
printf("DOWNLOADED\n");
|
||||
fclose(data->output);
|
||||
data->output = 0x0;
|
||||
}
|
||||
return CURL_CHUNK_END_FUNC_OK;
|
||||
}
|
||||
|
||||
static size_t write_it(char *buff, size_t size, size_t nmemb,
|
||||
void *cb_data)
|
||||
{
|
||||
struct callback_data *data = cb_data;
|
||||
size_t written = 0;
|
||||
if(data->output)
|
||||
written = fwrite(buff, size, nmemb, data->output);
|
||||
else
|
||||
/* listing output */
|
||||
written = fwrite(buff, size, nmemb, stdout);
|
||||
return written;
|
||||
}
|
||||
94
Engine/lib/curl/docs/examples/ftpget.c
Normal file
94
Engine/lib/curl/docs/examples/ftpget.c
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* <DESC>
|
||||
* Get a single file from an FTP server.
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
struct FtpFile {
|
||||
const char *filename;
|
||||
FILE *stream;
|
||||
};
|
||||
|
||||
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
struct FtpFile *out = (struct FtpFile *)stream;
|
||||
if(!out->stream) {
|
||||
/* open file for writing */
|
||||
out->stream = fopen(out->filename, "wb");
|
||||
if(!out->stream)
|
||||
return -1; /* failure, cannot open file to write */
|
||||
}
|
||||
return fwrite(buffer, size, nmemb, out->stream);
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct FtpFile ftpfile = {
|
||||
"curl.tar.gz", /* name to store the file as if successful */
|
||||
NULL
|
||||
};
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/*
|
||||
* You better replace the URL with one that works!
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"ftp://ftp.example.com/curl/curl-7.9.2.tar.gz");
|
||||
/* Define our callback to get called when there's data to be written */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
|
||||
/* Set a pointer to our struct to pass to the callback */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
|
||||
|
||||
/* Switch on full protocol/debug output */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if(CURLE_OK != res) {
|
||||
/* we failed */
|
||||
fprintf(stderr, "curl told us %d\n", res);
|
||||
}
|
||||
}
|
||||
|
||||
if(ftpfile.stream)
|
||||
fclose(ftpfile.stream); /* close the local file */
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
92
Engine/lib/curl/docs/examples/ftpgetinfo.c
Normal file
92
Engine/lib/curl/docs/examples/ftpgetinfo.c
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* <DESC>
|
||||
* Checks a single file's size and mtime from an FTP server.
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
static size_t throw_away(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
(void)ptr;
|
||||
(void)data;
|
||||
/* we are not interested in the headers itself,
|
||||
so we only return the size we would have saved ... */
|
||||
return (size_t)(size * nmemb);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char ftpurl[] = "ftp://ftp.example.com/gnu/binutils/binutils-2.19.1.tar.bz2";
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
long filetime = -1;
|
||||
double filesize = 0.0;
|
||||
const char *filename = strrchr(ftpurl, '/') + 1;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, ftpurl);
|
||||
/* No download if the file */
|
||||
curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
|
||||
/* Ask for filetime */
|
||||
curl_easy_setopt(curl, CURLOPT_FILETIME, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, throw_away);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 0L);
|
||||
/* Switch on full protocol/debug output */
|
||||
/* curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); */
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
if(CURLE_OK == res) {
|
||||
/* https://curl.se/libcurl/c/curl_easy_getinfo.html */
|
||||
res = curl_easy_getinfo(curl, CURLINFO_FILETIME, &filetime);
|
||||
if((CURLE_OK == res) && (filetime >= 0)) {
|
||||
time_t file_time = (time_t)filetime;
|
||||
printf("filetime %s: %s", filename, ctime(&file_time));
|
||||
}
|
||||
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD,
|
||||
&filesize);
|
||||
if((CURLE_OK == res) && (filesize>0.0))
|
||||
printf("filesize %s: %0.0f bytes\n", filename, filesize);
|
||||
}
|
||||
else {
|
||||
/* we failed */
|
||||
fprintf(stderr, "curl told us %d\n", res);
|
||||
}
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
79
Engine/lib/curl/docs/examples/ftpgetresp.c
Normal file
79
Engine/lib/curl/docs/examples/ftpgetresp.c
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* <DESC>
|
||||
* Similar to ftpget.c but also stores the received response-lines
|
||||
* in a separate file using our own callback!
|
||||
* </DESC>
|
||||
*/
|
||||
static size_t
|
||||
write_response(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
FILE *writehere = (FILE *)data;
|
||||
return fwrite(ptr, size, nmemb, writehere);
|
||||
}
|
||||
|
||||
#define FTPBODY "ftp-list"
|
||||
#define FTPHEADERS "ftp-responses"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
FILE *ftpfile;
|
||||
FILE *respfile;
|
||||
|
||||
/* local file name to store the file as */
|
||||
ftpfile = fopen(FTPBODY, "wb"); /* b is binary, needed on win32 */
|
||||
|
||||
/* local file name to store the FTP server's response lines in */
|
||||
respfile = fopen(FTPHEADERS, "wb"); /* b is binary, needed on win32 */
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Get a file listing from sunet */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "ftp://ftp.example.com/");
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, ftpfile);
|
||||
/* If you intend to use this on windows with a libcurl DLL, you must use
|
||||
CURLOPT_WRITEFUNCTION as well */
|
||||
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, write_response);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADERDATA, respfile);
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
fclose(ftpfile); /* close the local file */
|
||||
fclose(respfile); /* close the response file */
|
||||
|
||||
return 0;
|
||||
}
|
||||
101
Engine/lib/curl/docs/examples/ftpsget.c
Normal file
101
Engine/lib/curl/docs/examples/ftpsget.c
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* <DESC>
|
||||
* Get a single file from an FTPS server.
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
struct FtpFile {
|
||||
const char *filename;
|
||||
FILE *stream;
|
||||
};
|
||||
|
||||
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb,
|
||||
void *stream)
|
||||
{
|
||||
struct FtpFile *out = (struct FtpFile *)stream;
|
||||
if(!out->stream) {
|
||||
/* open file for writing */
|
||||
out->stream = fopen(out->filename, "wb");
|
||||
if(!out->stream)
|
||||
return -1; /* failure, cannot open file to write */
|
||||
}
|
||||
return fwrite(buffer, size, nmemb, out->stream);
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct FtpFile ftpfile = {
|
||||
"yourfile.bin", /* name to store the file as if successful */
|
||||
NULL
|
||||
};
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/*
|
||||
* You better replace the URL with one that works! Note that we use an
|
||||
* FTP:// URL with standard explicit FTPS. You can also do FTPS:// URLs if
|
||||
* you want to do the rarer kind of transfers: implicit.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"ftp://user@server/home/user/file.txt");
|
||||
/* Define our callback to get called when there's data to be written */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
|
||||
/* Set a pointer to our struct to pass to the callback */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
|
||||
|
||||
/* We activate SSL and we require it for both control and data */
|
||||
curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
|
||||
|
||||
/* Switch on full protocol/debug output */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if(CURLE_OK != res) {
|
||||
/* we failed */
|
||||
fprintf(stderr, "curl told us %d\n", res);
|
||||
}
|
||||
}
|
||||
|
||||
if(ftpfile.stream)
|
||||
fclose(ftpfile.stream); /* close the local file */
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
142
Engine/lib/curl/docs/examples/ftpupload.c
Normal file
142
Engine/lib/curl/docs/examples/ftpupload.c
Normal file
|
|
@ -0,0 +1,142 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#ifdef WIN32
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* <DESC>
|
||||
* Performs an FTP upload and renames the file just after a successful
|
||||
* transfer.
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#define LOCAL_FILE "/tmp/uploadthis.txt"
|
||||
#define UPLOAD_FILE_AS "while-uploading.txt"
|
||||
#define REMOTE_URL "ftp://example.com/" UPLOAD_FILE_AS
|
||||
#define RENAME_FILE_TO "renamed-and-fine.txt"
|
||||
|
||||
/* NOTE: if you want this example 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. */
|
||||
static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
unsigned long nread;
|
||||
/* in real-world cases, this would probably get this data differently
|
||||
as this fread() stuff is exactly what the library already would do
|
||||
by default internally */
|
||||
size_t retcode = fread(ptr, size, nmemb, stream);
|
||||
|
||||
if(retcode > 0) {
|
||||
nread = (unsigned long)retcode;
|
||||
fprintf(stderr, "*** We read %lu bytes from file\n", nread);
|
||||
}
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
FILE *hd_src;
|
||||
struct stat file_info;
|
||||
unsigned long fsize;
|
||||
|
||||
struct curl_slist *headerlist = NULL;
|
||||
static const char buf_1 [] = "RNFR " UPLOAD_FILE_AS;
|
||||
static const char buf_2 [] = "RNTO " RENAME_FILE_TO;
|
||||
|
||||
/* get the file size of the local file */
|
||||
if(stat(LOCAL_FILE, &file_info)) {
|
||||
printf("Couldn't open '%s': %s\n", LOCAL_FILE, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
fsize = (unsigned long)file_info.st_size;
|
||||
|
||||
printf("Local file size: %lu bytes.\n", fsize);
|
||||
|
||||
/* get a FILE * of the same file */
|
||||
hd_src = fopen(LOCAL_FILE, "rb");
|
||||
|
||||
/* In windows, this will init the winsock stuff */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* get a curl handle */
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* build a list of commands to pass to libcurl */
|
||||
headerlist = curl_slist_append(headerlist, buf_1);
|
||||
headerlist = curl_slist_append(headerlist, buf_2);
|
||||
|
||||
/* we want to use our own read function */
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
|
||||
/* enable uploading */
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
/* specify target */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, REMOTE_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_READDATA, hd_src);
|
||||
|
||||
/* 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)fsize);
|
||||
|
||||
/* Now run off and do what you have been told! */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* clean up the FTP commands list */
|
||||
curl_slist_free_all(headerlist);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
fclose(hd_src); /* close the local file */
|
||||
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
||||
126
Engine/lib/curl/docs/examples/ftpuploadfrommem.c
Normal file
126
Engine/lib/curl/docs/examples/ftpuploadfrommem.c
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* FTP upload a file from memory
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
static const char data[]=
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
|
||||
"Nam rhoncus odio id venenatis volutpat. Vestibulum dapibus "
|
||||
"bibendum ullamcorper. Maecenas finibus elit augue, vel "
|
||||
"condimentum odio maximus nec. In hac habitasse platea dictumst. "
|
||||
"Vestibulum vel dolor et turpis rutrum finibus ac at nulla. "
|
||||
"Vivamus nec neque ac elit blandit pretium vitae maximus ipsum. "
|
||||
"Quisque sodales magna vel erat auctor, sed pellentesque nisi "
|
||||
"rhoncus. Donec vehicula maximus pretium. Aliquam eu tincidunt "
|
||||
"lorem.";
|
||||
|
||||
struct WriteThis {
|
||||
const char *readptr;
|
||||
size_t sizeleft;
|
||||
};
|
||||
|
||||
static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
struct WriteThis *upload = (struct WriteThis *)userp;
|
||||
size_t max = size*nmemb;
|
||||
|
||||
if(max < 1)
|
||||
return 0;
|
||||
|
||||
if(upload->sizeleft) {
|
||||
size_t copylen = max;
|
||||
if(copylen > upload->sizeleft)
|
||||
copylen = upload->sizeleft;
|
||||
memcpy(ptr, upload->readptr, copylen);
|
||||
upload->readptr += copylen;
|
||||
upload->sizeleft -= copylen;
|
||||
return copylen;
|
||||
}
|
||||
|
||||
return 0; /* no more data left to deliver */
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
struct WriteThis upload;
|
||||
|
||||
upload.readptr = data;
|
||||
upload.sizeleft = strlen(data);
|
||||
|
||||
/* In windows, this will init the winsock stuff */
|
||||
res = curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK) {
|
||||
fprintf(stderr, "curl_global_init() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* get a curl handle */
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* First set the URL, the target file */
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"ftp://example.com/path/to/upload/file");
|
||||
|
||||
/* User and password for the FTP login */
|
||||
curl_easy_setopt(curl, CURLOPT_USERPWD, "login:secret");
|
||||
|
||||
/* Now specify we want to UPLOAD data */
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 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_READDATA, &upload);
|
||||
|
||||
/* get verbose debug output please */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* Set the expected upload size. */
|
||||
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
|
||||
(curl_off_t)upload.sizeleft);
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
||||
163
Engine/lib/curl/docs/examples/ftpuploadresume.c
Normal file
163
Engine/lib/curl/docs/examples/ftpuploadresume.c
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Upload to FTP, resuming failed transfers.
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* parse headers for Content-Length */
|
||||
static size_t getcontentlengthfunc(void *ptr, size_t size, size_t nmemb,
|
||||
void *stream)
|
||||
{
|
||||
int r;
|
||||
long len = 0;
|
||||
|
||||
r = sscanf(ptr, "Content-Length: %ld\n", &len);
|
||||
if(r)
|
||||
*((long *) stream) = len;
|
||||
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
/* discard downloaded data */
|
||||
static size_t discardfunc(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
(void)ptr;
|
||||
(void)stream;
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
/* read data to upload */
|
||||
static size_t readfunc(char *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
FILE *f = stream;
|
||||
size_t n;
|
||||
|
||||
if(ferror(f))
|
||||
return CURL_READFUNC_ABORT;
|
||||
|
||||
n = fread(ptr, size, nmemb, f) * size;
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static int upload(CURL *curlhandle, const char *remotepath,
|
||||
const char *localpath, long timeout, long tries)
|
||||
{
|
||||
FILE *f;
|
||||
long uploaded_len = 0;
|
||||
CURLcode r = CURLE_GOT_NOTHING;
|
||||
int c;
|
||||
|
||||
f = fopen(localpath, "rb");
|
||||
if(!f) {
|
||||
perror(NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_URL, remotepath);
|
||||
|
||||
if(timeout)
|
||||
curl_easy_setopt(curlhandle, CURLOPT_SERVER_RESPONSE_TIMEOUT, timeout);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_HEADERFUNCTION, getcontentlengthfunc);
|
||||
curl_easy_setopt(curlhandle, CURLOPT_HEADERDATA, &uploaded_len);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_WRITEFUNCTION, discardfunc);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_READFUNCTION, readfunc);
|
||||
curl_easy_setopt(curlhandle, CURLOPT_READDATA, f);
|
||||
|
||||
/* disable passive mode */
|
||||
curl_easy_setopt(curlhandle, CURLOPT_FTPPORT, "-");
|
||||
curl_easy_setopt(curlhandle, CURLOPT_FTP_CREATE_MISSING_DIRS, 1L);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
for(c = 0; (r != CURLE_OK) && (c < tries); c++) {
|
||||
/* are we resuming? */
|
||||
if(c) { /* yes */
|
||||
/* determine the length of the file already written */
|
||||
|
||||
/*
|
||||
* With NOBODY and NOHEADER, libcurl will issue a SIZE
|
||||
* command, but the only way to retrieve the result is
|
||||
* to parse the returned Content-Length header. Thus,
|
||||
* getcontentlengthfunc(). We need discardfunc() above
|
||||
* because HEADER will dump the headers to stdout
|
||||
* without it.
|
||||
*/
|
||||
curl_easy_setopt(curlhandle, CURLOPT_NOBODY, 1L);
|
||||
curl_easy_setopt(curlhandle, CURLOPT_HEADER, 1L);
|
||||
|
||||
r = curl_easy_perform(curlhandle);
|
||||
if(r != CURLE_OK)
|
||||
continue;
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_NOBODY, 0L);
|
||||
curl_easy_setopt(curlhandle, CURLOPT_HEADER, 0L);
|
||||
|
||||
fseek(f, uploaded_len, SEEK_SET);
|
||||
|
||||
curl_easy_setopt(curlhandle, CURLOPT_APPEND, 1L);
|
||||
}
|
||||
else { /* no */
|
||||
curl_easy_setopt(curlhandle, CURLOPT_APPEND, 0L);
|
||||
}
|
||||
|
||||
r = curl_easy_perform(curlhandle);
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
if(r == CURLE_OK)
|
||||
return 1;
|
||||
else {
|
||||
fprintf(stderr, "%s\n", curl_easy_strerror(r));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curlhandle = NULL;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
curlhandle = curl_easy_init();
|
||||
|
||||
upload(curlhandle, "ftp://user:pass@example.com/path/file", "C:\\file",
|
||||
0, 3);
|
||||
|
||||
curl_easy_cleanup(curlhandle);
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
54
Engine/lib/curl/docs/examples/getinfo.c
Normal file
54
Engine/lib/curl/docs/examples/getinfo.c
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Use getinfo to get content-type after completed transfer.
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com/");
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
if(CURLE_OK == res) {
|
||||
char *ct;
|
||||
/* ask for the content-type */
|
||||
res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct);
|
||||
|
||||
if((CURLE_OK == res) && ct)
|
||||
printf("We received Content-Type: %s\n", ct);
|
||||
}
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
118
Engine/lib/curl/docs/examples/getinmemory.c
Normal file
118
Engine/lib/curl/docs/examples/getinmemory.c
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Shows how the write callback function can be used to download data into a
|
||||
* chunk of memory instead of storing it in a file.
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
struct MemoryStruct {
|
||||
char *memory;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static size_t
|
||||
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
|
||||
|
||||
char *ptr = realloc(mem->memory, mem->size + realsize + 1);
|
||||
if(!ptr) {
|
||||
/* out of memory! */
|
||||
printf("not enough memory (realloc returned NULL)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mem->memory = ptr;
|
||||
memcpy(&(mem->memory[mem->size]), contents, realsize);
|
||||
mem->size += realsize;
|
||||
mem->memory[mem->size] = 0;
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl_handle;
|
||||
CURLcode res;
|
||||
|
||||
struct MemoryStruct chunk;
|
||||
|
||||
chunk.memory = malloc(1); /* will be grown as needed by the realloc above */
|
||||
chunk.size = 0; /* no data at this point */
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* init the curl session */
|
||||
curl_handle = curl_easy_init();
|
||||
|
||||
/* specify URL to get */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_URL, "https://www.example.com/");
|
||||
|
||||
/* send all data to this function */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
|
||||
|
||||
/* we pass our 'chunk' struct to the callback function */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk);
|
||||
|
||||
/* some servers do not like requests that are made without a user-agent
|
||||
field, so we provide one */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
|
||||
|
||||
/* get it! */
|
||||
res = curl_easy_perform(curl_handle);
|
||||
|
||||
/* check for errors */
|
||||
if(res != CURLE_OK) {
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Now, our chunk.memory points to a memory block that is chunk.size
|
||||
* bytes big and contains the remote file.
|
||||
*
|
||||
* Do something nice with it!
|
||||
*/
|
||||
|
||||
printf("%lu bytes retrieved\n", (unsigned long)chunk.size);
|
||||
}
|
||||
|
||||
/* cleanup curl stuff */
|
||||
curl_easy_cleanup(curl_handle);
|
||||
|
||||
free(chunk.memory);
|
||||
|
||||
/* we are done with libcurl, so clean it up */
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
72
Engine/lib/curl/docs/examples/getredirect.c
Normal file
72
Engine/lib/curl/docs/examples/getredirect.c
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Show how to extract Location: header and URL to redirect to.
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
char *location;
|
||||
long response_code;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
|
||||
|
||||
/* example.com is redirected, figure out the redirection! */
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
else {
|
||||
res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
|
||||
if((res == CURLE_OK) &&
|
||||
((response_code / 100) != 3)) {
|
||||
/* a redirect implies a 3xx response code */
|
||||
fprintf(stderr, "Not a redirect.\n");
|
||||
}
|
||||
else {
|
||||
res = curl_easy_getinfo(curl, CURLINFO_REDIRECT_URL, &location);
|
||||
|
||||
if((res == CURLE_OK) && location) {
|
||||
/* This is the new absolute URL that you could redirect to, even if
|
||||
* the Location: response header may have been a relative URL. */
|
||||
printf("Redirected to: %s\n", location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
59
Engine/lib/curl/docs/examples/getreferrer.c
Normal file
59
Engine/lib/curl/docs/examples/getreferrer.c
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Show how to extract referrer header.
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
CURLcode res;
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
|
||||
curl_easy_setopt(curl, CURLOPT_REFERER, "https://example.org/referrer");
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
else {
|
||||
char *hdr;
|
||||
res = curl_easy_getinfo(curl, CURLINFO_REFERER, &hdr);
|
||||
if((res == CURLE_OK) && hdr)
|
||||
printf("Referrer header: %s\n", hdr);
|
||||
}
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
438
Engine/lib/curl/docs/examples/ghiper.c
Normal file
438
Engine/lib/curl/docs/examples/ghiper.c
Normal file
|
|
@ -0,0 +1,438 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* multi socket API usage together with with glib2
|
||||
* </DESC>
|
||||
*/
|
||||
/* Example application source code using the multi socket interface to
|
||||
* download many files at once.
|
||||
*
|
||||
* Written by Jeff Pohlmeyer
|
||||
|
||||
Requires glib-2.x and a (POSIX?) system that has mkfifo().
|
||||
|
||||
This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c"
|
||||
sample programs, adapted to use glib's g_io_channel in place of libevent.
|
||||
|
||||
When running, the program creates the named pipe "hiper.fifo"
|
||||
|
||||
Whenever there is input into the fifo, the program reads the input as a list
|
||||
of URL's and creates some new easy handles to fetch each URL via the
|
||||
curl_multi "hiper" API.
|
||||
|
||||
|
||||
Thus, you can try a single URL:
|
||||
% echo http://www.yahoo.com > hiper.fifo
|
||||
|
||||
Or a whole bunch of them:
|
||||
% cat my-url-list > hiper.fifo
|
||||
|
||||
The fifo buffer is handled almost instantly, so you can even add more URL's
|
||||
while the previous requests are still being downloaded.
|
||||
|
||||
This is purely a demo app, all retrieved data is simply discarded by the write
|
||||
callback.
|
||||
|
||||
*/
|
||||
|
||||
#include <glib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#define MSG_OUT g_print /* Change to "g_error" to write to stderr */
|
||||
#define SHOW_VERBOSE 0 /* Set to non-zero for libcurl messages */
|
||||
#define SHOW_PROGRESS 0 /* Set to non-zero to enable progress callback */
|
||||
|
||||
/* Global information, common to all connections */
|
||||
typedef struct _GlobalInfo {
|
||||
CURLM *multi;
|
||||
guint timer_event;
|
||||
int still_running;
|
||||
} GlobalInfo;
|
||||
|
||||
/* Information associated with a specific easy handle */
|
||||
typedef struct _ConnInfo {
|
||||
CURL *easy;
|
||||
char *url;
|
||||
GlobalInfo *global;
|
||||
char error[CURL_ERROR_SIZE];
|
||||
} ConnInfo;
|
||||
|
||||
/* Information associated with a specific socket */
|
||||
typedef struct _SockInfo {
|
||||
curl_socket_t sockfd;
|
||||
CURL *easy;
|
||||
int action;
|
||||
long timeout;
|
||||
GIOChannel *ch;
|
||||
guint ev;
|
||||
GlobalInfo *global;
|
||||
} SockInfo;
|
||||
|
||||
/* Die if we get a bad CURLMcode somewhere */
|
||||
static void mcode_or_die(const char *where, CURLMcode code)
|
||||
{
|
||||
if(CURLM_OK != code) {
|
||||
const char *s;
|
||||
switch(code) {
|
||||
case CURLM_BAD_HANDLE: s = "CURLM_BAD_HANDLE"; break;
|
||||
case CURLM_BAD_EASY_HANDLE: s = "CURLM_BAD_EASY_HANDLE"; break;
|
||||
case CURLM_OUT_OF_MEMORY: s = "CURLM_OUT_OF_MEMORY"; break;
|
||||
case CURLM_INTERNAL_ERROR: s = "CURLM_INTERNAL_ERROR"; break;
|
||||
case CURLM_BAD_SOCKET: s = "CURLM_BAD_SOCKET"; break;
|
||||
case CURLM_UNKNOWN_OPTION: s = "CURLM_UNKNOWN_OPTION"; break;
|
||||
case CURLM_LAST: s = "CURLM_LAST"; break;
|
||||
default: s = "CURLM_unknown";
|
||||
}
|
||||
MSG_OUT("ERROR: %s returns %s\n", where, s);
|
||||
exit(code);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for completed transfers, and remove their easy handles */
|
||||
static void check_multi_info(GlobalInfo *g)
|
||||
{
|
||||
char *eff_url;
|
||||
CURLMsg *msg;
|
||||
int msgs_left;
|
||||
ConnInfo *conn;
|
||||
CURL *easy;
|
||||
CURLcode res;
|
||||
|
||||
MSG_OUT("REMAINING: %d\n", g->still_running);
|
||||
while((msg = curl_multi_info_read(g->multi, &msgs_left))) {
|
||||
if(msg->msg == CURLMSG_DONE) {
|
||||
easy = msg->easy_handle;
|
||||
res = msg->data.result;
|
||||
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
|
||||
curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
|
||||
MSG_OUT("DONE: %s => (%d) %s\n", eff_url, res, conn->error);
|
||||
curl_multi_remove_handle(g->multi, easy);
|
||||
free(conn->url);
|
||||
curl_easy_cleanup(easy);
|
||||
free(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Called by glib when our timeout expires */
|
||||
static gboolean timer_cb(gpointer data)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo *)data;
|
||||
CURLMcode rc;
|
||||
|
||||
rc = curl_multi_socket_action(g->multi,
|
||||
CURL_SOCKET_TIMEOUT, 0, &g->still_running);
|
||||
mcode_or_die("timer_cb: curl_multi_socket_action", rc);
|
||||
check_multi_info(g);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Update the event timer after curl_multi library calls */
|
||||
static int update_timeout_cb(CURLM *multi, long timeout_ms, void *userp)
|
||||
{
|
||||
struct timeval timeout;
|
||||
GlobalInfo *g = (GlobalInfo *)userp;
|
||||
timeout.tv_sec = timeout_ms/1000;
|
||||
timeout.tv_usec = (timeout_ms%1000)*1000;
|
||||
|
||||
MSG_OUT("*** update_timeout_cb %ld => %ld:%ld ***\n",
|
||||
timeout_ms, timeout.tv_sec, timeout.tv_usec);
|
||||
|
||||
/*
|
||||
* if timeout_ms is -1, just delete the timer
|
||||
*
|
||||
* For other values of timeout_ms, this should set or *update* the timer to
|
||||
* the new value
|
||||
*/
|
||||
if(timeout_ms >= 0)
|
||||
g->timer_event = g_timeout_add(timeout_ms, timer_cb, g);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called by glib when we get action on a multi socket */
|
||||
static gboolean event_cb(GIOChannel *ch, GIOCondition condition, gpointer data)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo*) data;
|
||||
CURLMcode rc;
|
||||
int fd = g_io_channel_unix_get_fd(ch);
|
||||
|
||||
int action =
|
||||
((condition & G_IO_IN) ? CURL_CSELECT_IN : 0) |
|
||||
((condition & G_IO_OUT) ? CURL_CSELECT_OUT : 0);
|
||||
|
||||
rc = curl_multi_socket_action(g->multi, fd, action, &g->still_running);
|
||||
mcode_or_die("event_cb: curl_multi_socket_action", rc);
|
||||
|
||||
check_multi_info(g);
|
||||
if(g->still_running) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
MSG_OUT("last transfer done, kill timeout\n");
|
||||
if(g->timer_event) {
|
||||
g_source_remove(g->timer_event);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up the SockInfo structure */
|
||||
static void remsock(SockInfo *f)
|
||||
{
|
||||
if(!f) {
|
||||
return;
|
||||
}
|
||||
if(f->ev) {
|
||||
g_source_remove(f->ev);
|
||||
}
|
||||
g_free(f);
|
||||
}
|
||||
|
||||
/* Assign information to a SockInfo structure */
|
||||
static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act,
|
||||
GlobalInfo *g)
|
||||
{
|
||||
GIOCondition kind =
|
||||
((act & CURL_POLL_IN) ? G_IO_IN : 0) |
|
||||
((act & CURL_POLL_OUT) ? G_IO_OUT : 0);
|
||||
|
||||
f->sockfd = s;
|
||||
f->action = act;
|
||||
f->easy = e;
|
||||
if(f->ev) {
|
||||
g_source_remove(f->ev);
|
||||
}
|
||||
f->ev = g_io_add_watch(f->ch, kind, event_cb, g);
|
||||
}
|
||||
|
||||
/* Initialize a new SockInfo structure */
|
||||
static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g)
|
||||
{
|
||||
SockInfo *fdp = g_malloc0(sizeof(SockInfo));
|
||||
|
||||
fdp->global = g;
|
||||
fdp->ch = g_io_channel_unix_new(s);
|
||||
setsock(fdp, s, easy, action, g);
|
||||
curl_multi_assign(g->multi, s, fdp);
|
||||
}
|
||||
|
||||
/* CURLMOPT_SOCKETFUNCTION */
|
||||
static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo*) cbp;
|
||||
SockInfo *fdp = (SockInfo*) sockp;
|
||||
static const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" };
|
||||
|
||||
MSG_OUT("socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
|
||||
if(what == CURL_POLL_REMOVE) {
|
||||
MSG_OUT("\n");
|
||||
remsock(fdp);
|
||||
}
|
||||
else {
|
||||
if(!fdp) {
|
||||
MSG_OUT("Adding data: %s%s\n",
|
||||
(what & CURL_POLL_IN) ? "READ" : "",
|
||||
(what & CURL_POLL_OUT) ? "WRITE" : "");
|
||||
addsock(s, e, what, g);
|
||||
}
|
||||
else {
|
||||
MSG_OUT(
|
||||
"Changing action from %d to %d\n", fdp->action, what);
|
||||
setsock(fdp, s, e, what, g);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* CURLOPT_WRITEFUNCTION */
|
||||
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
ConnInfo *conn = (ConnInfo*) data;
|
||||
(void)ptr;
|
||||
(void)conn;
|
||||
return realsize;
|
||||
}
|
||||
|
||||
/* CURLOPT_PROGRESSFUNCTION */
|
||||
static int prog_cb(void *p, double dltotal, double dlnow, double ult,
|
||||
double uln)
|
||||
{
|
||||
ConnInfo *conn = (ConnInfo *)p;
|
||||
MSG_OUT("Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create a new easy handle, and add it to the global curl_multi */
|
||||
static void new_conn(char *url, GlobalInfo *g)
|
||||
{
|
||||
ConnInfo *conn;
|
||||
CURLMcode rc;
|
||||
|
||||
conn = g_malloc0(sizeof(ConnInfo));
|
||||
conn->error[0]='\0';
|
||||
conn->easy = curl_easy_init();
|
||||
if(!conn->easy) {
|
||||
MSG_OUT("curl_easy_init() failed, exiting!\n");
|
||||
exit(2);
|
||||
}
|
||||
conn->global = g;
|
||||
conn->url = g_strdup(url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, &conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, (long)SHOW_VERBOSE);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, SHOW_PROGRESS?0L:1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_CONNECTTIMEOUT, 30L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_LIMIT, 1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_LOW_SPEED_TIME, 30L);
|
||||
|
||||
MSG_OUT("Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
|
||||
rc = curl_multi_add_handle(g->multi, conn->easy);
|
||||
mcode_or_die("new_conn: curl_multi_add_handle", rc);
|
||||
|
||||
/* note that the add_handle() will set a time-out to trigger very soon so
|
||||
that the necessary socket_action() call will be called by this app */
|
||||
}
|
||||
|
||||
/* This gets called by glib whenever data is received from the fifo */
|
||||
static gboolean fifo_cb(GIOChannel *ch, GIOCondition condition, gpointer data)
|
||||
{
|
||||
#define BUF_SIZE 1024
|
||||
gsize len, tp;
|
||||
gchar *buf, *tmp, *all = NULL;
|
||||
GIOStatus rv;
|
||||
|
||||
do {
|
||||
GError *err = NULL;
|
||||
rv = g_io_channel_read_line(ch, &buf, &len, &tp, &err);
|
||||
if(buf) {
|
||||
if(tp) {
|
||||
buf[tp]='\0';
|
||||
}
|
||||
new_conn(buf, (GlobalInfo*)data);
|
||||
g_free(buf);
|
||||
}
|
||||
else {
|
||||
buf = g_malloc(BUF_SIZE + 1);
|
||||
while(TRUE) {
|
||||
buf[BUF_SIZE]='\0';
|
||||
g_io_channel_read_chars(ch, buf, BUF_SIZE, &len, &err);
|
||||
if(len) {
|
||||
buf[len]='\0';
|
||||
if(all) {
|
||||
tmp = all;
|
||||
all = g_strdup_printf("%s%s", tmp, buf);
|
||||
g_free(tmp);
|
||||
}
|
||||
else {
|
||||
all = g_strdup(buf);
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(all) {
|
||||
new_conn(all, (GlobalInfo*)data);
|
||||
g_free(all);
|
||||
}
|
||||
g_free(buf);
|
||||
}
|
||||
if(err) {
|
||||
g_error("fifo_cb: %s", err->message);
|
||||
g_free(err);
|
||||
break;
|
||||
}
|
||||
} while((len) && (rv == G_IO_STATUS_NORMAL));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int init_fifo(void)
|
||||
{
|
||||
struct stat st;
|
||||
const char *fifo = "hiper.fifo";
|
||||
int socket;
|
||||
|
||||
if(lstat (fifo, &st) == 0) {
|
||||
if((st.st_mode & S_IFMT) == S_IFREG) {
|
||||
errno = EEXIST;
|
||||
perror("lstat");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
unlink(fifo);
|
||||
if(mkfifo (fifo, 0600) == -1) {
|
||||
perror("mkfifo");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
socket = open(fifo, O_RDWR | O_NONBLOCK, 0);
|
||||
|
||||
if(socket == -1) {
|
||||
perror("open");
|
||||
exit(1);
|
||||
}
|
||||
MSG_OUT("Now, pipe some URL's into > %s\n", fifo);
|
||||
|
||||
return socket;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GlobalInfo *g;
|
||||
GMainLoop*gmain;
|
||||
int fd;
|
||||
GIOChannel* ch;
|
||||
g = g_malloc0(sizeof(GlobalInfo));
|
||||
|
||||
fd = init_fifo();
|
||||
ch = g_io_channel_unix_new(fd);
|
||||
g_io_add_watch(ch, G_IO_IN, fifo_cb, g);
|
||||
gmain = g_main_loop_new(NULL, FALSE);
|
||||
g->multi = curl_multi_init();
|
||||
curl_multi_setopt(g->multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
|
||||
curl_multi_setopt(g->multi, CURLMOPT_SOCKETDATA, g);
|
||||
curl_multi_setopt(g->multi, CURLMOPT_TIMERFUNCTION, update_timeout_cb);
|
||||
curl_multi_setopt(g->multi, CURLMOPT_TIMERDATA, g);
|
||||
|
||||
/* we do not call any curl_multi_socket*() function yet as we have no handles
|
||||
added! */
|
||||
|
||||
g_main_loop_run(gmain);
|
||||
curl_multi_cleanup(g->multi);
|
||||
return 0;
|
||||
}
|
||||
81
Engine/lib/curl/docs/examples/headerapi.c
Normal file
81
Engine/lib/curl/docs/examples/headerapi.c
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Extract headers post transfer with the header API
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
static size_t write_cb(char *data, size_t n, size_t l, void *userp)
|
||||
{
|
||||
/* take care of the data here, ignored in this example */
|
||||
(void)data;
|
||||
(void)userp;
|
||||
return n*l;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
CURLcode res;
|
||||
struct curl_header *header;
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
|
||||
/* example.com is redirected, so we tell libcurl to follow redirection */
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
|
||||
/* this example just ignores the content */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
if(CURLHE_OK == curl_easy_header(curl, "Content-Type", 0, CURLH_HEADER,
|
||||
-1, &header))
|
||||
printf("Got content-type: %s\n", header->value);
|
||||
|
||||
printf("All server headers:\n");
|
||||
{
|
||||
struct curl_header *h;
|
||||
struct curl_header *prev = NULL;
|
||||
do {
|
||||
h = curl_easy_nextheader(curl, CURLH_HEADER, -1, prev);
|
||||
if(h)
|
||||
printf(" %s: %s (%u)\n", h->name, h->value, (int)h->amount);
|
||||
prev = h;
|
||||
} while(h);
|
||||
|
||||
}
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
464
Engine/lib/curl/docs/examples/hiperfifo.c
Normal file
464
Engine/lib/curl/docs/examples/hiperfifo.c
Normal file
|
|
@ -0,0 +1,464 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* multi socket API usage with libevent 2
|
||||
* </DESC>
|
||||
*/
|
||||
/* Example application source code using the multi socket interface to
|
||||
download many files at once.
|
||||
|
||||
Written by Jeff Pohlmeyer
|
||||
|
||||
Requires libevent version 2 and a (POSIX?) system that has mkfifo().
|
||||
|
||||
This is an adaptation of libcurl's "hipev.c" and libevent's "event-test.c"
|
||||
sample programs.
|
||||
|
||||
When running, the program creates the named pipe "hiper.fifo"
|
||||
|
||||
Whenever there is input into the fifo, the program reads the input as a list
|
||||
of URL's and creates some new easy handles to fetch each URL via the
|
||||
curl_multi "hiper" API.
|
||||
|
||||
|
||||
Thus, you can try a single URL:
|
||||
% echo http://www.yahoo.com > hiper.fifo
|
||||
|
||||
Or a whole bunch of them:
|
||||
% cat my-url-list > hiper.fifo
|
||||
|
||||
The fifo buffer is handled almost instantly, so you can even add more URL's
|
||||
while the previous requests are still being downloaded.
|
||||
|
||||
Note:
|
||||
For the sake of simplicity, URL length is limited to 1023 char's !
|
||||
|
||||
This is purely a demo app, all retrieved data is simply discarded by the write
|
||||
callback.
|
||||
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/poll.h>
|
||||
#include <curl/curl.h>
|
||||
#include <event2/event.h>
|
||||
#include <event2/event_struct.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
#define MSG_OUT stdout /* Send info to stdout, change to stderr if you want */
|
||||
|
||||
|
||||
/* Global information, common to all connections */
|
||||
typedef struct _GlobalInfo
|
||||
{
|
||||
struct event_base *evbase;
|
||||
struct event fifo_event;
|
||||
struct event timer_event;
|
||||
CURLM *multi;
|
||||
int still_running;
|
||||
FILE *input;
|
||||
int stopped;
|
||||
} GlobalInfo;
|
||||
|
||||
|
||||
/* Information associated with a specific easy handle */
|
||||
typedef struct _ConnInfo
|
||||
{
|
||||
CURL *easy;
|
||||
char *url;
|
||||
GlobalInfo *global;
|
||||
char error[CURL_ERROR_SIZE];
|
||||
} ConnInfo;
|
||||
|
||||
|
||||
/* Information associated with a specific socket */
|
||||
typedef struct _SockInfo
|
||||
{
|
||||
curl_socket_t sockfd;
|
||||
CURL *easy;
|
||||
int action;
|
||||
long timeout;
|
||||
struct event ev;
|
||||
GlobalInfo *global;
|
||||
} SockInfo;
|
||||
|
||||
#define mycase(code) \
|
||||
case code: s = __STRING(code)
|
||||
|
||||
/* Die if we get a bad CURLMcode somewhere */
|
||||
static void mcode_or_die(const char *where, CURLMcode code)
|
||||
{
|
||||
if(CURLM_OK != code) {
|
||||
const char *s;
|
||||
switch(code) {
|
||||
mycase(CURLM_BAD_HANDLE); break;
|
||||
mycase(CURLM_BAD_EASY_HANDLE); break;
|
||||
mycase(CURLM_OUT_OF_MEMORY); break;
|
||||
mycase(CURLM_INTERNAL_ERROR); break;
|
||||
mycase(CURLM_UNKNOWN_OPTION); break;
|
||||
mycase(CURLM_LAST); break;
|
||||
default: s = "CURLM_unknown"; break;
|
||||
mycase(CURLM_BAD_SOCKET);
|
||||
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
|
||||
/* ignore this error */
|
||||
return;
|
||||
}
|
||||
fprintf(MSG_OUT, "ERROR: %s returns %s\n", where, s);
|
||||
exit(code);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Update the event timer after curl_multi library calls */
|
||||
static int multi_timer_cb(CURLM *multi, long timeout_ms, GlobalInfo *g)
|
||||
{
|
||||
struct timeval timeout;
|
||||
(void)multi;
|
||||
|
||||
timeout.tv_sec = timeout_ms/1000;
|
||||
timeout.tv_usec = (timeout_ms%1000)*1000;
|
||||
fprintf(MSG_OUT, "multi_timer_cb: Setting timeout to %ld ms\n", timeout_ms);
|
||||
|
||||
/*
|
||||
* if timeout_ms is -1, just delete the timer
|
||||
*
|
||||
* For all other values of timeout_ms, this should set or *update* the timer
|
||||
* to the new value
|
||||
*/
|
||||
if(timeout_ms == -1)
|
||||
evtimer_del(&g->timer_event);
|
||||
else /* includes timeout zero */
|
||||
evtimer_add(&g->timer_event, &timeout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Check for completed transfers, and remove their easy handles */
|
||||
static void check_multi_info(GlobalInfo *g)
|
||||
{
|
||||
char *eff_url;
|
||||
CURLMsg *msg;
|
||||
int msgs_left;
|
||||
ConnInfo *conn;
|
||||
CURL *easy;
|
||||
CURLcode res;
|
||||
|
||||
fprintf(MSG_OUT, "REMAINING: %d\n", g->still_running);
|
||||
while((msg = curl_multi_info_read(g->multi, &msgs_left))) {
|
||||
if(msg->msg == CURLMSG_DONE) {
|
||||
easy = msg->easy_handle;
|
||||
res = msg->data.result;
|
||||
curl_easy_getinfo(easy, CURLINFO_PRIVATE, &conn);
|
||||
curl_easy_getinfo(easy, CURLINFO_EFFECTIVE_URL, &eff_url);
|
||||
fprintf(MSG_OUT, "DONE: %s => (%d) %s\n", eff_url, res, conn->error);
|
||||
curl_multi_remove_handle(g->multi, easy);
|
||||
free(conn->url);
|
||||
curl_easy_cleanup(easy);
|
||||
free(conn);
|
||||
}
|
||||
}
|
||||
if(g->still_running == 0 && g->stopped)
|
||||
event_base_loopbreak(g->evbase);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Called by libevent when we get action on a multi socket */
|
||||
static void event_cb(int fd, short kind, void *userp)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo*) userp;
|
||||
CURLMcode rc;
|
||||
|
||||
int action =
|
||||
((kind & EV_READ) ? CURL_CSELECT_IN : 0) |
|
||||
((kind & EV_WRITE) ? CURL_CSELECT_OUT : 0);
|
||||
|
||||
rc = curl_multi_socket_action(g->multi, fd, action, &g->still_running);
|
||||
mcode_or_die("event_cb: curl_multi_socket_action", rc);
|
||||
|
||||
check_multi_info(g);
|
||||
if(g->still_running <= 0) {
|
||||
fprintf(MSG_OUT, "last transfer done, kill timeout\n");
|
||||
if(evtimer_pending(&g->timer_event, NULL)) {
|
||||
evtimer_del(&g->timer_event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Called by libevent when our timeout expires */
|
||||
static void timer_cb(int fd, short kind, void *userp)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo *)userp;
|
||||
CURLMcode rc;
|
||||
(void)fd;
|
||||
(void)kind;
|
||||
|
||||
rc = curl_multi_socket_action(g->multi,
|
||||
CURL_SOCKET_TIMEOUT, 0, &g->still_running);
|
||||
mcode_or_die("timer_cb: curl_multi_socket_action", rc);
|
||||
check_multi_info(g);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Clean up the SockInfo structure */
|
||||
static void remsock(SockInfo *f)
|
||||
{
|
||||
if(f) {
|
||||
if(event_initialized(&f->ev)) {
|
||||
event_del(&f->ev);
|
||||
}
|
||||
free(f);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Assign information to a SockInfo structure */
|
||||
static void setsock(SockInfo *f, curl_socket_t s, CURL *e, int act,
|
||||
GlobalInfo *g)
|
||||
{
|
||||
int kind =
|
||||
((act & CURL_POLL_IN) ? EV_READ : 0) |
|
||||
((act & CURL_POLL_OUT) ? EV_WRITE : 0) | EV_PERSIST;
|
||||
|
||||
f->sockfd = s;
|
||||
f->action = act;
|
||||
f->easy = e;
|
||||
if(event_initialized(&f->ev)) {
|
||||
event_del(&f->ev);
|
||||
}
|
||||
event_assign(&f->ev, g->evbase, f->sockfd, kind, event_cb, g);
|
||||
event_add(&f->ev, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Initialize a new SockInfo structure */
|
||||
static void addsock(curl_socket_t s, CURL *easy, int action, GlobalInfo *g)
|
||||
{
|
||||
SockInfo *fdp = calloc(1, sizeof(SockInfo));
|
||||
|
||||
fdp->global = g;
|
||||
setsock(fdp, s, easy, action, g);
|
||||
curl_multi_assign(g->multi, s, fdp);
|
||||
}
|
||||
|
||||
/* CURLMOPT_SOCKETFUNCTION */
|
||||
static int sock_cb(CURL *e, curl_socket_t s, int what, void *cbp, void *sockp)
|
||||
{
|
||||
GlobalInfo *g = (GlobalInfo*) cbp;
|
||||
SockInfo *fdp = (SockInfo*) sockp;
|
||||
const char *whatstr[]={ "none", "IN", "OUT", "INOUT", "REMOVE" };
|
||||
|
||||
fprintf(MSG_OUT,
|
||||
"socket callback: s=%d e=%p what=%s ", s, e, whatstr[what]);
|
||||
if(what == CURL_POLL_REMOVE) {
|
||||
fprintf(MSG_OUT, "\n");
|
||||
remsock(fdp);
|
||||
}
|
||||
else {
|
||||
if(!fdp) {
|
||||
fprintf(MSG_OUT, "Adding data: %s\n", whatstr[what]);
|
||||
addsock(s, e, what, g);
|
||||
}
|
||||
else {
|
||||
fprintf(MSG_OUT,
|
||||
"Changing action from %s to %s\n",
|
||||
whatstr[fdp->action], whatstr[what]);
|
||||
setsock(fdp, s, e, what, g);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* CURLOPT_WRITEFUNCTION */
|
||||
static size_t write_cb(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
(void)ptr;
|
||||
(void)data;
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
|
||||
/* CURLOPT_PROGRESSFUNCTION */
|
||||
static int prog_cb(void *p, double dltotal, double dlnow, double ult,
|
||||
double uln)
|
||||
{
|
||||
ConnInfo *conn = (ConnInfo *)p;
|
||||
(void)ult;
|
||||
(void)uln;
|
||||
|
||||
fprintf(MSG_OUT, "Progress: %s (%g/%g)\n", conn->url, dlnow, dltotal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Create a new easy handle, and add it to the global curl_multi */
|
||||
static void new_conn(char *url, GlobalInfo *g)
|
||||
{
|
||||
ConnInfo *conn;
|
||||
CURLMcode rc;
|
||||
|
||||
conn = calloc(1, sizeof(ConnInfo));
|
||||
conn->error[0]='\0';
|
||||
|
||||
conn->easy = curl_easy_init();
|
||||
if(!conn->easy) {
|
||||
fprintf(MSG_OUT, "curl_easy_init() failed, exiting!\n");
|
||||
exit(2);
|
||||
}
|
||||
conn->global = g;
|
||||
conn->url = strdup(url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_URL, conn->url);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_WRITEDATA, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_ERRORBUFFER, conn->error);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PRIVATE, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSFUNCTION, prog_cb);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_PROGRESSDATA, conn);
|
||||
curl_easy_setopt(conn->easy, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
fprintf(MSG_OUT,
|
||||
"Adding easy %p to multi %p (%s)\n", conn->easy, g->multi, url);
|
||||
rc = curl_multi_add_handle(g->multi, conn->easy);
|
||||
mcode_or_die("new_conn: curl_multi_add_handle", rc);
|
||||
|
||||
/* note that the add_handle() will set a time-out to trigger very soon so
|
||||
that the necessary socket_action() call will be called by this app */
|
||||
}
|
||||
|
||||
/* This gets called whenever data is received from the fifo */
|
||||
static void fifo_cb(int fd, short event, void *arg)
|
||||
{
|
||||
char s[1024];
|
||||
long int rv = 0;
|
||||
int n = 0;
|
||||
GlobalInfo *g = (GlobalInfo *)arg;
|
||||
(void)fd;
|
||||
(void)event;
|
||||
|
||||
do {
|
||||
s[0]='\0';
|
||||
rv = fscanf(g->input, "%1023s%n", s, &n);
|
||||
s[n]='\0';
|
||||
if(n && s[0]) {
|
||||
if(!strcmp(s, "stop")) {
|
||||
g->stopped = 1;
|
||||
if(g->still_running == 0)
|
||||
event_base_loopbreak(g->evbase);
|
||||
}
|
||||
else
|
||||
new_conn(s, arg); /* if we read a URL, go get it! */
|
||||
}
|
||||
else
|
||||
break;
|
||||
} while(rv != EOF);
|
||||
}
|
||||
|
||||
/* Create a named pipe and tell libevent to monitor it */
|
||||
static const char *fifo = "hiper.fifo";
|
||||
static int init_fifo(GlobalInfo *g)
|
||||
{
|
||||
struct stat st;
|
||||
curl_socket_t sockfd;
|
||||
|
||||
fprintf(MSG_OUT, "Creating named pipe \"%s\"\n", fifo);
|
||||
if(lstat (fifo, &st) == 0) {
|
||||
if((st.st_mode & S_IFMT) == S_IFREG) {
|
||||
errno = EEXIST;
|
||||
perror("lstat");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
unlink(fifo);
|
||||
if(mkfifo (fifo, 0600) == -1) {
|
||||
perror("mkfifo");
|
||||
exit(1);
|
||||
}
|
||||
sockfd = open(fifo, O_RDWR | O_NONBLOCK, 0);
|
||||
if(sockfd == -1) {
|
||||
perror("open");
|
||||
exit(1);
|
||||
}
|
||||
g->input = fdopen(sockfd, "r");
|
||||
|
||||
fprintf(MSG_OUT, "Now, pipe some URL's into > %s\n", fifo);
|
||||
event_assign(&g->fifo_event, g->evbase, sockfd, EV_READ|EV_PERSIST,
|
||||
fifo_cb, g);
|
||||
event_add(&g->fifo_event, NULL);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void clean_fifo(GlobalInfo *g)
|
||||
{
|
||||
event_del(&g->fifo_event);
|
||||
fclose(g->input);
|
||||
unlink(fifo);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
GlobalInfo g;
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
memset(&g, 0, sizeof(GlobalInfo));
|
||||
g.evbase = event_base_new();
|
||||
init_fifo(&g);
|
||||
g.multi = curl_multi_init();
|
||||
evtimer_assign(&g.timer_event, g.evbase, timer_cb, &g);
|
||||
|
||||
/* setup the generic multi interface options we want */
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETFUNCTION, sock_cb);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_SOCKETDATA, &g);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
|
||||
curl_multi_setopt(g.multi, CURLMOPT_TIMERDATA, &g);
|
||||
|
||||
/* we do not call any curl_multi_socket*() function yet as we have no handles
|
||||
added! */
|
||||
|
||||
event_base_dispatch(g.evbase);
|
||||
|
||||
/* this, of course, will not get called since only way to stop this program
|
||||
is via ctrl-C, but it is here to show how cleanup /would/ be done. */
|
||||
clean_fifo(&g);
|
||||
event_del(&g.timer_event);
|
||||
event_base_free(g.evbase);
|
||||
curl_multi_cleanup(g.multi);
|
||||
return 0;
|
||||
}
|
||||
88
Engine/lib/curl/docs/examples/href_extractor.c
Normal file
88
Engine/lib/curl/docs/examples/href_extractor.c
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 2012 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* Uses the "Streaming HTML parser" to extract the href pieces in a streaming
|
||||
* manner from a downloaded HTML.
|
||||
* </DESC>
|
||||
*/
|
||||
/*
|
||||
* The HTML parser is found at https://github.com/arjunc77/htmlstreamparser
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
#include <htmlstreamparser.h>
|
||||
|
||||
|
||||
static size_t write_callback(void *buffer, size_t size, size_t nmemb,
|
||||
void *hsp)
|
||||
{
|
||||
size_t realsize = size * nmemb, p;
|
||||
for(p = 0; p < realsize; p++) {
|
||||
html_parser_char_parse(hsp, ((char *)buffer)[p]);
|
||||
if(html_parser_cmp_tag(hsp, "a", 1))
|
||||
if(html_parser_cmp_attr(hsp, "href", 4))
|
||||
if(html_parser_is_in(hsp, HTML_VALUE_ENDED)) {
|
||||
html_parser_val(hsp)[html_parser_val_length(hsp)] = '\0';
|
||||
printf("%s\n", html_parser_val(hsp));
|
||||
}
|
||||
}
|
||||
return realsize;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char tag[1], attr[4], val[128];
|
||||
CURL *curl;
|
||||
HTMLSTREAMPARSER *hsp;
|
||||
|
||||
if(argc != 2) {
|
||||
printf("Usage: %s URL\n", argv[0]);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
curl = curl_easy_init();
|
||||
|
||||
hsp = html_parser_init();
|
||||
|
||||
html_parser_set_tag_to_lower(hsp, 1);
|
||||
html_parser_set_attr_to_lower(hsp, 1);
|
||||
html_parser_set_tag_buffer(hsp, tag, sizeof(tag));
|
||||
html_parser_set_attr_buffer(hsp, attr, sizeof(attr));
|
||||
html_parser_set_val_buffer(hsp, val, sizeof(val)-1);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, argv[1]);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, hsp);
|
||||
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
|
||||
curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
html_parser_cleanup(hsp);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
130
Engine/lib/curl/docs/examples/htmltidy.c
Normal file
130
Engine/lib/curl/docs/examples/htmltidy.c
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Download a document and use libtidy to parse the HTML.
|
||||
* </DESC>
|
||||
*/
|
||||
/*
|
||||
* LibTidy => https://www.html-tidy.org/
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <tidy/tidy.h>
|
||||
#include <tidy/tidybuffio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* curl write callback, to fill tidy's input buffer... */
|
||||
uint write_cb(char *in, uint size, uint nmemb, TidyBuffer *out)
|
||||
{
|
||||
uint r;
|
||||
r = size * nmemb;
|
||||
tidyBufAppend(out, in, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Traverse the document tree */
|
||||
void dumpNode(TidyDoc doc, TidyNode tnod, int indent)
|
||||
{
|
||||
TidyNode child;
|
||||
for(child = tidyGetChild(tnod); child; child = tidyGetNext(child) ) {
|
||||
ctmbstr name = tidyNodeGetName(child);
|
||||
if(name) {
|
||||
/* if it has a name, then it's an HTML tag ... */
|
||||
TidyAttr attr;
|
||||
printf("%*.*s%s ", indent, indent, "<", name);
|
||||
/* walk the attribute list */
|
||||
for(attr = tidyAttrFirst(child); attr; attr = tidyAttrNext(attr) ) {
|
||||
printf("%s", tidyAttrName(attr));
|
||||
tidyAttrValue(attr)?printf("=\"%s\" ",
|
||||
tidyAttrValue(attr)):printf(" ");
|
||||
}
|
||||
printf(">\n");
|
||||
}
|
||||
else {
|
||||
/* if it does not have a name, then it's probably text, cdata, etc... */
|
||||
TidyBuffer buf;
|
||||
tidyBufInit(&buf);
|
||||
tidyNodeGetText(doc, child, &buf);
|
||||
printf("%*.*s\n", indent, indent, buf.bp?(char *)buf.bp:"");
|
||||
tidyBufFree(&buf);
|
||||
}
|
||||
dumpNode(doc, child, indent + 4); /* recursive */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if(argc == 2) {
|
||||
CURL *curl;
|
||||
char curl_errbuf[CURL_ERROR_SIZE];
|
||||
TidyDoc tdoc;
|
||||
TidyBuffer docbuf = {0};
|
||||
TidyBuffer tidy_errbuf = {0};
|
||||
int err;
|
||||
|
||||
curl = curl_easy_init();
|
||||
curl_easy_setopt(curl, CURLOPT_URL, argv[1]);
|
||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errbuf);
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
|
||||
tdoc = tidyCreate();
|
||||
tidyOptSetBool(tdoc, TidyForceOutput, yes); /* try harder */
|
||||
tidyOptSetInt(tdoc, TidyWrapLen, 4096);
|
||||
tidySetErrorBuffer(tdoc, &tidy_errbuf);
|
||||
tidyBufInit(&docbuf);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &docbuf);
|
||||
err = curl_easy_perform(curl);
|
||||
if(!err) {
|
||||
err = tidyParseBuffer(tdoc, &docbuf); /* parse the input */
|
||||
if(err >= 0) {
|
||||
err = tidyCleanAndRepair(tdoc); /* fix any problems */
|
||||
if(err >= 0) {
|
||||
err = tidyRunDiagnostics(tdoc); /* load tidy error buffer */
|
||||
if(err >= 0) {
|
||||
dumpNode(tdoc, tidyGetRoot(tdoc), 0); /* walk the tree */
|
||||
fprintf(stderr, "%s\n", tidy_errbuf.bp); /* show errors */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
fprintf(stderr, "%s\n", curl_errbuf);
|
||||
|
||||
/* clean-up */
|
||||
curl_easy_cleanup(curl);
|
||||
tidyBufFree(&docbuf);
|
||||
tidyBufFree(&tidy_errbuf);
|
||||
tidyRelease(tdoc);
|
||||
return err;
|
||||
|
||||
}
|
||||
else
|
||||
printf("usage: %s <url>\n", argv[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
296
Engine/lib/curl/docs/examples/htmltitle.cpp
Normal file
296
Engine/lib/curl/docs/examples/htmltitle.cpp
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Get a web page, extract the title with libxml.
|
||||
* </DESC>
|
||||
|
||||
Written by Lars Nilsson
|
||||
|
||||
GNU C++ compile command line suggestion (edit paths accordingly):
|
||||
|
||||
g++ -Wall -I/opt/curl/include -I/opt/libxml/include/libxml2 htmltitle.cpp \
|
||||
-o htmltitle -L/opt/curl/lib -L/opt/libxml/lib -lcurl -lxml2
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <curl/curl.h>
|
||||
#include <libxml/HTMLparser.h>
|
||||
|
||||
//
|
||||
// Case-insensitive string comparison
|
||||
//
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define COMPARE(a, b) (!_stricmp((a), (b)))
|
||||
#else
|
||||
#define COMPARE(a, b) (!strcasecmp((a), (b)))
|
||||
#endif
|
||||
|
||||
//
|
||||
// libxml callback context structure
|
||||
//
|
||||
|
||||
struct Context
|
||||
{
|
||||
Context(): addTitle(false) { }
|
||||
|
||||
bool addTitle;
|
||||
std::string title;
|
||||
};
|
||||
|
||||
//
|
||||
// libcurl variables for error strings and returned data
|
||||
|
||||
static char errorBuffer[CURL_ERROR_SIZE];
|
||||
static std::string buffer;
|
||||
|
||||
//
|
||||
// libcurl write callback function
|
||||
//
|
||||
|
||||
static int writer(char *data, size_t size, size_t nmemb,
|
||||
std::string *writerData)
|
||||
{
|
||||
if(writerData == NULL)
|
||||
return 0;
|
||||
|
||||
writerData->append(data, size*nmemb);
|
||||
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
//
|
||||
// libcurl connection initialization
|
||||
//
|
||||
|
||||
static bool init(CURL *&conn, char *url)
|
||||
{
|
||||
CURLcode code;
|
||||
|
||||
conn = curl_easy_init();
|
||||
|
||||
if(conn == NULL) {
|
||||
fprintf(stderr, "Failed to create CURL connection\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
code = curl_easy_setopt(conn, CURLOPT_ERRORBUFFER, errorBuffer);
|
||||
if(code != CURLE_OK) {
|
||||
fprintf(stderr, "Failed to set error buffer [%d]\n", code);
|
||||
return false;
|
||||
}
|
||||
|
||||
code = curl_easy_setopt(conn, CURLOPT_URL, url);
|
||||
if(code != CURLE_OK) {
|
||||
fprintf(stderr, "Failed to set URL [%s]\n", errorBuffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
code = curl_easy_setopt(conn, CURLOPT_FOLLOWLOCATION, 1L);
|
||||
if(code != CURLE_OK) {
|
||||
fprintf(stderr, "Failed to set redirect option [%s]\n", errorBuffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
code = curl_easy_setopt(conn, CURLOPT_WRITEFUNCTION, writer);
|
||||
if(code != CURLE_OK) {
|
||||
fprintf(stderr, "Failed to set writer [%s]\n", errorBuffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
code = curl_easy_setopt(conn, CURLOPT_WRITEDATA, &buffer);
|
||||
if(code != CURLE_OK) {
|
||||
fprintf(stderr, "Failed to set write data [%s]\n", errorBuffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//
|
||||
// libxml start element callback function
|
||||
//
|
||||
|
||||
static void StartElement(void *voidContext,
|
||||
const xmlChar *name,
|
||||
const xmlChar **attributes)
|
||||
{
|
||||
Context *context = static_cast<Context *>(voidContext);
|
||||
|
||||
if(COMPARE(reinterpret_cast<char *>(name), "TITLE")) {
|
||||
context->title = "";
|
||||
context->addTitle = true;
|
||||
}
|
||||
(void) attributes;
|
||||
}
|
||||
|
||||
//
|
||||
// libxml end element callback function
|
||||
//
|
||||
|
||||
static void EndElement(void *voidContext,
|
||||
const xmlChar *name)
|
||||
{
|
||||
Context *context = static_cast<Context *>(voidContext);
|
||||
|
||||
if(COMPARE(reinterpret_cast<char *>(name), "TITLE"))
|
||||
context->addTitle = false;
|
||||
}
|
||||
|
||||
//
|
||||
// Text handling helper function
|
||||
//
|
||||
|
||||
static void handleCharacters(Context *context,
|
||||
const xmlChar *chars,
|
||||
int length)
|
||||
{
|
||||
if(context->addTitle)
|
||||
context->title.append(reinterpret_cast<char *>(chars), length);
|
||||
}
|
||||
|
||||
//
|
||||
// libxml PCDATA callback function
|
||||
//
|
||||
|
||||
static void Characters(void *voidContext,
|
||||
const xmlChar *chars,
|
||||
int length)
|
||||
{
|
||||
Context *context = static_cast<Context *>(voidContext);
|
||||
|
||||
handleCharacters(context, chars, length);
|
||||
}
|
||||
|
||||
//
|
||||
// libxml CDATA callback function
|
||||
//
|
||||
|
||||
static void cdata(void *voidContext,
|
||||
const xmlChar *chars,
|
||||
int length)
|
||||
{
|
||||
Context *context = static_cast<Context *>(voidContext);
|
||||
|
||||
handleCharacters(context, chars, length);
|
||||
}
|
||||
|
||||
//
|
||||
// libxml SAX callback structure
|
||||
//
|
||||
|
||||
static htmlSAXHandler saxHandler =
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
StartElement,
|
||||
EndElement,
|
||||
NULL,
|
||||
Characters,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
cdata,
|
||||
NULL
|
||||
};
|
||||
|
||||
//
|
||||
// Parse given (assumed to be) HTML text and return the title
|
||||
//
|
||||
|
||||
static void parseHtml(const std::string &html,
|
||||
std::string &title)
|
||||
{
|
||||
htmlParserCtxtPtr ctxt;
|
||||
Context context;
|
||||
|
||||
ctxt = htmlCreatePushParserCtxt(&saxHandler, &context, "", 0, "",
|
||||
XML_CHAR_ENCODING_NONE);
|
||||
|
||||
htmlParseChunk(ctxt, html.c_str(), html.size(), 0);
|
||||
htmlParseChunk(ctxt, "", 0, 1);
|
||||
|
||||
htmlFreeParserCtxt(ctxt);
|
||||
|
||||
title = context.title;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
CURL *conn = NULL;
|
||||
CURLcode code;
|
||||
std::string title;
|
||||
|
||||
// Ensure one argument is given
|
||||
|
||||
if(argc != 2) {
|
||||
fprintf(stderr, "Usage: %s <url>\n", argv[0]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
// Initialize CURL connection
|
||||
|
||||
if(!init(conn, argv[1])) {
|
||||
fprintf(stderr, "Connection initializion failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Retrieve content for the URL
|
||||
|
||||
code = curl_easy_perform(conn);
|
||||
curl_easy_cleanup(conn);
|
||||
|
||||
if(code != CURLE_OK) {
|
||||
fprintf(stderr, "Failed to get '%s' [%s]\n", argv[1], errorBuffer);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// Parse the (assumed) HTML code
|
||||
parseHtml(buffer, title);
|
||||
|
||||
// Display the extracted title
|
||||
printf("Title: %s\n", title.c_str());
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
61
Engine/lib/curl/docs/examples/http-post.c
Normal file
61
Engine/lib/curl/docs/examples/http-post.c
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* simple HTTP POST using the easy interface
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
/* In windows, this will init the winsock stuff */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* get a curl handle */
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* First set the URL that is about to receive our POST. This URL can
|
||||
just as well be a https:// URL if that is what should receive the
|
||||
data. */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "http://postit.example.com/moo.cgi");
|
||||
/* Now specify the POST data */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "name=daniel&project=curl");
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
||||
236
Engine/lib/curl/docs/examples/http2-download.c
Normal file
236
Engine/lib/curl/docs/examples/http2-download.c
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Multiplexed HTTP/2 downloads over a single connection
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* curl stuff */
|
||||
#include <curl/curl.h>
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#ifndef CURLPIPE_MULTIPLEX
|
||||
/* This little trick will just make sure that we do not enable pipelining for
|
||||
libcurls old enough to not have this symbol. It is _not_ defined to zero in
|
||||
a recent libcurl header. */
|
||||
#define CURLPIPE_MULTIPLEX 0
|
||||
#endif
|
||||
|
||||
struct transfer {
|
||||
CURL *easy;
|
||||
unsigned int num;
|
||||
FILE *out;
|
||||
};
|
||||
|
||||
#define NUM_HANDLES 1000
|
||||
|
||||
static
|
||||
void dump(const char *text, int num, 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(stderr, "%d %s, %lu bytes (0x%lx)\n",
|
||||
num, text, (unsigned long)size, (unsigned long)size);
|
||||
|
||||
for(i = 0; i<size; i += width) {
|
||||
|
||||
fprintf(stderr, "%4.4lx: ", (unsigned long)i);
|
||||
|
||||
if(!nohex) {
|
||||
/* hex not disabled, show it */
|
||||
for(c = 0; c < width; c++)
|
||||
if(i + c < size)
|
||||
fprintf(stderr, "%02x ", ptr[i + c]);
|
||||
else
|
||||
fputs(" ", stderr);
|
||||
}
|
||||
|
||||
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(stderr, "%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', stderr); /* newline */
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
int my_trace(CURL *handle, curl_infotype type,
|
||||
char *data, size_t size,
|
||||
void *userp)
|
||||
{
|
||||
const char *text;
|
||||
struct transfer *t = (struct transfer *)userp;
|
||||
unsigned int num = t->num;
|
||||
(void)handle; /* prevent compiler warning */
|
||||
|
||||
switch(type) {
|
||||
case CURLINFO_TEXT:
|
||||
fprintf(stderr, "== %u Info: %s", num, data);
|
||||
/* FALLTHROUGH */
|
||||
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, num, (unsigned char *)data, size, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void setup(struct transfer *t, int num)
|
||||
{
|
||||
char filename[128];
|
||||
CURL *hnd;
|
||||
|
||||
hnd = t->easy = curl_easy_init();
|
||||
|
||||
curl_msnprintf(filename, 128, "dl-%d", num);
|
||||
|
||||
t->out = fopen(filename, "wb");
|
||||
if(!t->out) {
|
||||
fprintf(stderr, "error: could not open file %s for writing: %s\n",
|
||||
filename, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* write to this file */
|
||||
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, t->out);
|
||||
|
||||
/* set the same URL */
|
||||
curl_easy_setopt(hnd, CURLOPT_URL, "https://localhost:8443/index.html");
|
||||
|
||||
/* please be verbose */
|
||||
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_DEBUGFUNCTION, my_trace);
|
||||
curl_easy_setopt(hnd, CURLOPT_DEBUGDATA, t);
|
||||
|
||||
/* HTTP/2 please */
|
||||
curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
|
||||
|
||||
/* we use a self-signed test server, skip verification during debugging */
|
||||
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
|
||||
#if (CURLPIPE_MULTIPLEX > 0)
|
||||
/* wait for pipe connection to confirm */
|
||||
curl_easy_setopt(hnd, CURLOPT_PIPEWAIT, 1L);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Download many transfers over HTTP/2, using the same connection!
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct transfer trans[NUM_HANDLES];
|
||||
CURLM *multi_handle;
|
||||
int i;
|
||||
int still_running = 0; /* keep number of running handles */
|
||||
int num_transfers;
|
||||
if(argc > 1) {
|
||||
/* if given a number, do that many transfers */
|
||||
num_transfers = atoi(argv[1]);
|
||||
if((num_transfers < 1) || (num_transfers > NUM_HANDLES))
|
||||
num_transfers = 3; /* a suitable low default */
|
||||
}
|
||||
else
|
||||
num_transfers = 3; /* suitable default */
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
for(i = 0; i < num_transfers; i++) {
|
||||
setup(&trans[i], i);
|
||||
|
||||
/* add the individual transfer */
|
||||
curl_multi_add_handle(multi_handle, trans[i].easy);
|
||||
}
|
||||
|
||||
curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
|
||||
|
||||
do {
|
||||
CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
if(still_running)
|
||||
/* wait for activity, timeout or "nothing" */
|
||||
mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
|
||||
|
||||
if(mc)
|
||||
break;
|
||||
} while(still_running);
|
||||
|
||||
for(i = 0; i < num_transfers; i++) {
|
||||
curl_multi_remove_handle(multi_handle, trans[i].easy);
|
||||
curl_easy_cleanup(trans[i].easy);
|
||||
}
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
190
Engine/lib/curl/docs/examples/http2-pushinmemory.c
Normal file
190
Engine/lib/curl/docs/examples/http2-pushinmemory.c
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* HTTP/2 server push. Receive all data in memory.
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* curl stuff */
|
||||
#include <curl/curl.h>
|
||||
|
||||
struct Memory {
|
||||
char *memory;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static size_t
|
||||
write_cb(void *contents, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
struct Memory *mem = (struct Memory *)userp;
|
||||
char *ptr = realloc(mem->memory, mem->size + realsize + 1);
|
||||
if(!ptr) {
|
||||
/* out of memory! */
|
||||
printf("not enough memory (realloc returned NULL)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mem->memory = ptr;
|
||||
memcpy(&(mem->memory[mem->size]), contents, realsize);
|
||||
mem->size += realsize;
|
||||
mem->memory[mem->size] = 0;
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
||||
#define MAX_FILES 10
|
||||
static struct Memory files[MAX_FILES];
|
||||
static int pushindex = 1;
|
||||
|
||||
static void init_memory(struct Memory *chunk)
|
||||
{
|
||||
chunk->memory = malloc(1); /* grown as needed with realloc */
|
||||
chunk->size = 0; /* no data at this point */
|
||||
}
|
||||
|
||||
static void setup(CURL *hnd)
|
||||
{
|
||||
/* set the same URL */
|
||||
curl_easy_setopt(hnd, CURLOPT_URL, "https://localhost:8443/index.html");
|
||||
|
||||
/* HTTP/2 please */
|
||||
curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
|
||||
|
||||
/* we use a self-signed test server, skip verification during debugging */
|
||||
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
|
||||
/* write data to a struct */
|
||||
curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, write_cb);
|
||||
init_memory(&files[0]);
|
||||
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, &files[0]);
|
||||
|
||||
/* wait for pipe connection to confirm */
|
||||
curl_easy_setopt(hnd, CURLOPT_PIPEWAIT, 1L);
|
||||
}
|
||||
|
||||
/* called when there's an incoming push */
|
||||
static int server_push_callback(CURL *parent,
|
||||
CURL *easy,
|
||||
size_t num_headers,
|
||||
struct curl_pushheaders *headers,
|
||||
void *userp)
|
||||
{
|
||||
char *headp;
|
||||
int *transfers = (int *)userp;
|
||||
(void)parent; /* we have no use for this */
|
||||
(void)num_headers; /* unused */
|
||||
|
||||
if(pushindex == MAX_FILES)
|
||||
/* cannot fit anymore */
|
||||
return CURL_PUSH_DENY;
|
||||
|
||||
/* write to this buffer */
|
||||
init_memory(&files[pushindex]);
|
||||
curl_easy_setopt(easy, CURLOPT_WRITEDATA, &files[pushindex]);
|
||||
pushindex++;
|
||||
|
||||
headp = curl_pushheader_byname(headers, ":path");
|
||||
if(headp)
|
||||
fprintf(stderr, "* Pushed :path '%s'\n", headp /* skip :path + colon */);
|
||||
|
||||
(*transfers)++; /* one more */
|
||||
return CURL_PUSH_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Download a file over HTTP/2, take care of server push.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
CURL *easy;
|
||||
CURLM *multi;
|
||||
int still_running; /* keep number of running handles */
|
||||
int transfers = 1; /* we start with one */
|
||||
int i;
|
||||
struct CURLMsg *m;
|
||||
|
||||
/* init a multi stack */
|
||||
multi = curl_multi_init();
|
||||
|
||||
easy = curl_easy_init();
|
||||
|
||||
/* set options */
|
||||
setup(easy);
|
||||
|
||||
/* add the easy transfer */
|
||||
curl_multi_add_handle(multi, easy);
|
||||
|
||||
curl_multi_setopt(multi, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
|
||||
curl_multi_setopt(multi, CURLMOPT_PUSHFUNCTION, server_push_callback);
|
||||
curl_multi_setopt(multi, CURLMOPT_PUSHDATA, &transfers);
|
||||
|
||||
while(transfers) {
|
||||
int rc;
|
||||
CURLMcode mcode = curl_multi_perform(multi, &still_running);
|
||||
if(mcode)
|
||||
break;
|
||||
|
||||
mcode = curl_multi_wait(multi, NULL, 0, 1000, &rc);
|
||||
if(mcode)
|
||||
break;
|
||||
|
||||
|
||||
/*
|
||||
* When doing server push, libcurl itself created and added one or more
|
||||
* easy handles but *we* need to clean them up when they are done.
|
||||
*/
|
||||
do {
|
||||
int msgq = 0;
|
||||
m = curl_multi_info_read(multi, &msgq);
|
||||
if(m && (m->msg == CURLMSG_DONE)) {
|
||||
CURL *e = m->easy_handle;
|
||||
transfers--;
|
||||
curl_multi_remove_handle(multi, e);
|
||||
curl_easy_cleanup(e);
|
||||
}
|
||||
} while(m);
|
||||
|
||||
}
|
||||
|
||||
|
||||
curl_multi_cleanup(multi);
|
||||
|
||||
/* 'pushindex' is now the number of received transfers */
|
||||
for(i = 0; i < pushindex; i++) {
|
||||
/* do something fun with the data, and then free it when done */
|
||||
free(files[i].memory);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
273
Engine/lib/curl/docs/examples/http2-serverpush.c
Normal file
273
Engine/lib/curl/docs/examples/http2-serverpush.c
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* HTTP/2 server push
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* curl stuff */
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifndef CURLPIPE_MULTIPLEX
|
||||
#error "too old libcurl, cannot do HTTP/2 server push!"
|
||||
#endif
|
||||
|
||||
static
|
||||
void dump(const char *text, 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(stderr, "%s, %lu bytes (0x%lx)\n",
|
||||
text, (unsigned long)size, (unsigned long)size);
|
||||
|
||||
for(i = 0; i<size; i += width) {
|
||||
|
||||
fprintf(stderr, "%4.4lx: ", (unsigned long)i);
|
||||
|
||||
if(!nohex) {
|
||||
/* hex not disabled, show it */
|
||||
for(c = 0; c < width; c++)
|
||||
if(i + c < size)
|
||||
fprintf(stderr, "%02x ", ptr[i + c]);
|
||||
else
|
||||
fputs(" ", stderr);
|
||||
}
|
||||
|
||||
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(stderr, "%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', stderr); /* newline */
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
int my_trace(CURL *handle, curl_infotype type,
|
||||
char *data, size_t size,
|
||||
void *userp)
|
||||
{
|
||||
const char *text;
|
||||
(void)handle; /* prevent compiler warning */
|
||||
(void)userp;
|
||||
switch(type) {
|
||||
case CURLINFO_TEXT:
|
||||
fprintf(stderr, "== Info: %s", data);
|
||||
/* FALLTHROUGH */
|
||||
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, (unsigned char *)data, size, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define OUTPUTFILE "dl"
|
||||
|
||||
static int setup(CURL *hnd)
|
||||
{
|
||||
FILE *out = fopen(OUTPUTFILE, "wb");
|
||||
if(!out)
|
||||
/* failed */
|
||||
return 1;
|
||||
|
||||
/* write to this file */
|
||||
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, out);
|
||||
|
||||
/* set the same URL */
|
||||
curl_easy_setopt(hnd, CURLOPT_URL, "https://localhost:8443/index.html");
|
||||
|
||||
/* please be verbose */
|
||||
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_DEBUGFUNCTION, my_trace);
|
||||
|
||||
/* HTTP/2 please */
|
||||
curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
|
||||
|
||||
/* we use a self-signed test server, skip verification during debugging */
|
||||
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
|
||||
#if (CURLPIPE_MULTIPLEX > 0)
|
||||
/* wait for pipe connection to confirm */
|
||||
curl_easy_setopt(hnd, CURLOPT_PIPEWAIT, 1L);
|
||||
#endif
|
||||
return 0; /* all is good */
|
||||
}
|
||||
|
||||
/* called when there's an incoming push */
|
||||
static int server_push_callback(CURL *parent,
|
||||
CURL *easy,
|
||||
size_t num_headers,
|
||||
struct curl_pushheaders *headers,
|
||||
void *userp)
|
||||
{
|
||||
char *headp;
|
||||
size_t i;
|
||||
int *transfers = (int *)userp;
|
||||
char filename[128];
|
||||
FILE *out;
|
||||
static unsigned int count = 0;
|
||||
|
||||
(void)parent; /* we have no use for this */
|
||||
|
||||
snprintf(filename, 128, "push%u", count++);
|
||||
|
||||
/* here's a new stream, save it in a new file for each new push */
|
||||
out = fopen(filename, "wb");
|
||||
if(!out) {
|
||||
/* if we cannot save it, deny it */
|
||||
fprintf(stderr, "Failed to create output file for push\n");
|
||||
return CURL_PUSH_DENY;
|
||||
}
|
||||
|
||||
/* write to this file */
|
||||
curl_easy_setopt(easy, CURLOPT_WRITEDATA, out);
|
||||
|
||||
fprintf(stderr, "**** push callback approves stream %u, got %lu headers!\n",
|
||||
count, (unsigned long)num_headers);
|
||||
|
||||
for(i = 0; i<num_headers; i++) {
|
||||
headp = curl_pushheader_bynum(headers, i);
|
||||
fprintf(stderr, "**** header %lu: %s\n", (unsigned long)i, headp);
|
||||
}
|
||||
|
||||
headp = curl_pushheader_byname(headers, ":path");
|
||||
if(headp) {
|
||||
fprintf(stderr, "**** The PATH is %s\n", headp /* skip :path + colon */);
|
||||
}
|
||||
|
||||
(*transfers)++; /* one more */
|
||||
return CURL_PUSH_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Download a file over HTTP/2, take care of server push.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
CURL *easy;
|
||||
CURLM *multi_handle;
|
||||
int transfers = 1; /* we start with one */
|
||||
struct CURLMsg *m;
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
easy = curl_easy_init();
|
||||
|
||||
/* set options */
|
||||
if(setup(easy)) {
|
||||
fprintf(stderr, "failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* add the easy transfer */
|
||||
curl_multi_add_handle(multi_handle, easy);
|
||||
|
||||
curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
|
||||
curl_multi_setopt(multi_handle, CURLMOPT_PUSHFUNCTION, server_push_callback);
|
||||
curl_multi_setopt(multi_handle, CURLMOPT_PUSHDATA, &transfers);
|
||||
|
||||
do {
|
||||
int still_running; /* keep number of running handles */
|
||||
CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
if(still_running)
|
||||
/* wait for activity, timeout or "nothing" */
|
||||
mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
|
||||
|
||||
if(mc)
|
||||
break;
|
||||
|
||||
/*
|
||||
* A little caution when doing server push is that libcurl itself has
|
||||
* created and added one or more easy handles but we need to clean them up
|
||||
* when we are done.
|
||||
*/
|
||||
|
||||
do {
|
||||
int msgq = 0;
|
||||
m = curl_multi_info_read(multi_handle, &msgq);
|
||||
if(m && (m->msg == CURLMSG_DONE)) {
|
||||
CURL *e = m->easy_handle;
|
||||
transfers--;
|
||||
curl_multi_remove_handle(multi_handle, e);
|
||||
curl_easy_cleanup(e);
|
||||
}
|
||||
} while(m);
|
||||
|
||||
} while(transfers); /* as long as we have transfers going */
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
304
Engine/lib/curl/docs/examples/http2-upload.c
Normal file
304
Engine/lib/curl/docs/examples/http2-upload.c
Normal file
|
|
@ -0,0 +1,304 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Multiplexed HTTP/2 uploads over a single connection
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* curl stuff */
|
||||
#include <curl/curl.h>
|
||||
#include <curl/mprintf.h>
|
||||
|
||||
#ifndef CURLPIPE_MULTIPLEX
|
||||
/* This little trick will just make sure that we do not enable pipelining for
|
||||
libcurls old enough to not have this symbol. It is _not_ defined to zero in
|
||||
a recent libcurl header. */
|
||||
#define CURLPIPE_MULTIPLEX 0
|
||||
#endif
|
||||
|
||||
#define NUM_HANDLES 1000
|
||||
|
||||
struct input {
|
||||
FILE *in;
|
||||
size_t bytes_read; /* count up */
|
||||
CURL *hnd;
|
||||
int num;
|
||||
};
|
||||
|
||||
static
|
||||
void dump(const char *text, int num, 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(stderr, "%d %s, %lu bytes (0x%lx)\n",
|
||||
num, text, (unsigned long)size, (unsigned long)size);
|
||||
|
||||
for(i = 0; i<size; i += width) {
|
||||
|
||||
fprintf(stderr, "%4.4lx: ", (unsigned long)i);
|
||||
|
||||
if(!nohex) {
|
||||
/* hex not disabled, show it */
|
||||
for(c = 0; c < width; c++)
|
||||
if(i + c < size)
|
||||
fprintf(stderr, "%02x ", ptr[i + c]);
|
||||
else
|
||||
fputs(" ", stderr);
|
||||
}
|
||||
|
||||
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(stderr, "%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', stderr); /* newline */
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
int my_trace(CURL *handle, curl_infotype type,
|
||||
char *data, size_t size,
|
||||
void *userp)
|
||||
{
|
||||
char timebuf[60];
|
||||
const char *text;
|
||||
struct input *i = (struct input *)userp;
|
||||
int num = i->num;
|
||||
static time_t epoch_offset;
|
||||
static int known_offset;
|
||||
struct timeval tv;
|
||||
time_t secs;
|
||||
struct tm *now;
|
||||
(void)handle; /* prevent compiler warning */
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
if(!known_offset) {
|
||||
epoch_offset = time(NULL) - tv.tv_sec;
|
||||
known_offset = 1;
|
||||
}
|
||||
secs = epoch_offset + tv.tv_sec;
|
||||
now = localtime(&secs); /* not thread safe but we do not care */
|
||||
curl_msnprintf(timebuf, sizeof(timebuf), "%02d:%02d:%02d.%06ld",
|
||||
now->tm_hour, now->tm_min, now->tm_sec, (long)tv.tv_usec);
|
||||
|
||||
switch(type) {
|
||||
case CURLINFO_TEXT:
|
||||
fprintf(stderr, "%s [%d] Info: %s", timebuf, num, data);
|
||||
/* FALLTHROUGH */
|
||||
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, num, (unsigned char *)data, size, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
struct input *i = userp;
|
||||
size_t retcode = fread(ptr, size, nmemb, i->in);
|
||||
i->bytes_read += retcode;
|
||||
return retcode;
|
||||
}
|
||||
|
||||
static void setup(struct input *i, int num, const char *upload)
|
||||
{
|
||||
FILE *out;
|
||||
char url[256];
|
||||
char filename[128];
|
||||
struct stat file_info;
|
||||
curl_off_t uploadsize;
|
||||
CURL *hnd;
|
||||
|
||||
hnd = i->hnd = curl_easy_init();
|
||||
i->num = num;
|
||||
curl_msnprintf(filename, 128, "dl-%d", num);
|
||||
out = fopen(filename, "wb");
|
||||
if(!out) {
|
||||
fprintf(stderr, "error: could not open file %s for writing: %s\n", upload,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
curl_msnprintf(url, 256, "https://localhost:8443/upload-%d", num);
|
||||
|
||||
/* get the file size of the local file */
|
||||
if(stat(upload, &file_info)) {
|
||||
fprintf(stderr, "error: could not stat file %s: %s\n", upload,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
uploadsize = file_info.st_size;
|
||||
|
||||
i->in = fopen(upload, "rb");
|
||||
if(!i->in) {
|
||||
fprintf(stderr, "error: could not open file %s for reading: %s\n", upload,
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* write to this file */
|
||||
curl_easy_setopt(hnd, CURLOPT_WRITEDATA, out);
|
||||
|
||||
/* we want to use our own read function */
|
||||
curl_easy_setopt(hnd, CURLOPT_READFUNCTION, read_callback);
|
||||
/* read from this file */
|
||||
curl_easy_setopt(hnd, CURLOPT_READDATA, i);
|
||||
/* provide the size of the upload */
|
||||
curl_easy_setopt(hnd, CURLOPT_INFILESIZE_LARGE, uploadsize);
|
||||
|
||||
/* send in the URL to store the upload as */
|
||||
curl_easy_setopt(hnd, CURLOPT_URL, url);
|
||||
|
||||
/* upload please */
|
||||
curl_easy_setopt(hnd, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
/* please be verbose */
|
||||
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_DEBUGFUNCTION, my_trace);
|
||||
curl_easy_setopt(hnd, CURLOPT_DEBUGDATA, i);
|
||||
|
||||
/* HTTP/2 please */
|
||||
curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
|
||||
|
||||
/* we use a self-signed test server, skip verification during debugging */
|
||||
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
|
||||
#if (CURLPIPE_MULTIPLEX > 0)
|
||||
/* wait for pipe connection to confirm */
|
||||
curl_easy_setopt(hnd, CURLOPT_PIPEWAIT, 1L);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Upload all files over HTTP/2, using the same physical connection!
|
||||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct input trans[NUM_HANDLES];
|
||||
CURLM *multi_handle;
|
||||
int i;
|
||||
int still_running = 0; /* keep number of running handles */
|
||||
const char *filename = "index.html";
|
||||
int num_transfers;
|
||||
|
||||
if(argc > 1) {
|
||||
/* if given a number, do that many transfers */
|
||||
num_transfers = atoi(argv[1]);
|
||||
|
||||
if(!num_transfers || (num_transfers > NUM_HANDLES))
|
||||
num_transfers = 3; /* a suitable low default */
|
||||
|
||||
if(argc > 2)
|
||||
/* if given a file name, upload this! */
|
||||
filename = argv[2];
|
||||
}
|
||||
else
|
||||
num_transfers = 3;
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
for(i = 0; i<num_transfers; i++) {
|
||||
setup(&trans[i], i, filename);
|
||||
|
||||
/* add the individual transfer */
|
||||
curl_multi_add_handle(multi_handle, trans[i].hnd);
|
||||
}
|
||||
|
||||
curl_multi_setopt(multi_handle, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
|
||||
|
||||
/* We do HTTP/2 so let's stick to one connection per host */
|
||||
curl_multi_setopt(multi_handle, CURLMOPT_MAX_HOST_CONNECTIONS, 1L);
|
||||
|
||||
do {
|
||||
CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
if(still_running)
|
||||
/* wait for activity, timeout or "nothing" */
|
||||
mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
|
||||
|
||||
if(mc)
|
||||
break;
|
||||
|
||||
} while(still_running);
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
for(i = 0; i<num_transfers; i++) {
|
||||
curl_multi_remove_handle(multi_handle, trans[i].hnd);
|
||||
curl_easy_cleanup(trans[i].hnd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
49
Engine/lib/curl/docs/examples/http3-present.c
Normal file
49
Engine/lib/curl/docs/examples/http3-present.c
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Checks if HTTP/3 support is present in libcurl.
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
curl_version_info_data *ver;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
ver = curl_version_info(CURLVERSION_NOW);
|
||||
if(ver->features & CURL_VERSION_HTTP2)
|
||||
printf("HTTP/2 support is present\n");
|
||||
|
||||
if(ver->features & CURL_VERSION_HTTP3)
|
||||
printf("HTTP/3 support is present\n");
|
||||
|
||||
if(ver->features & CURL_VERSION_ALTSVC)
|
||||
printf("Alt-svc support is present\n");
|
||||
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
||||
56
Engine/lib/curl/docs/examples/http3.c
Normal file
56
Engine/lib/curl/docs/examples/http3.c
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Very simple HTTP/3 GET
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
|
||||
|
||||
/* Forcing HTTP/3 will make the connection fail if the server is not
|
||||
accessible over QUIC + HTTP/3 on the given host and port.
|
||||
Consider using CURLOPT_ALTSVC instead! */
|
||||
curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_3);
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
72
Engine/lib/curl/docs/examples/httpcustomheader.c
Normal file
72
Engine/lib/curl/docs/examples/httpcustomheader.c
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* HTTP request with custom modified, removed and added headers
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
struct curl_slist *chunk = NULL;
|
||||
|
||||
/* Remove a header curl would otherwise add by itself */
|
||||
chunk = curl_slist_append(chunk, "Accept:");
|
||||
|
||||
/* Add a custom header */
|
||||
chunk = curl_slist_append(chunk, "Another: yes");
|
||||
|
||||
/* Modify a header curl otherwise adds differently */
|
||||
chunk = curl_slist_append(chunk, "Host: example.com");
|
||||
|
||||
/* Add a header with "blank" contents to the right of the colon. Note that
|
||||
we are then using a semicolon in the string we pass to curl! */
|
||||
chunk = curl_slist_append(chunk, "X-silly-header;");
|
||||
|
||||
/* set our custom set of headers */
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "localhost");
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
/* free the custom headers */
|
||||
curl_slist_free_all(chunk);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
103
Engine/lib/curl/docs/examples/httpput-postfields.c
Normal file
103
Engine/lib/curl/docs/examples/httpput-postfields.c
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* HTTP PUT using CURLOPT_POSTFIELDS
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
static const char olivertwist[]=
|
||||
"Among other public buildings in a certain town, which for many reasons "
|
||||
"it will be prudent to refrain from mentioning, and to which I will assign "
|
||||
"no fictitious name, there is one anciently common to most towns, great or "
|
||||
"small: to wit, a workhouse; and in this workhouse was born; on a day and "
|
||||
"date which I need not trouble myself to repeat, inasmuch as it can be of "
|
||||
"no possible consequence to the reader, in this stage of the business at "
|
||||
"all events; the item of mortality whose name is prefixed to the head of "
|
||||
"this chapter.";
|
||||
|
||||
/*
|
||||
* This example shows a HTTP PUT operation that sends a fixed buffer with
|
||||
* CURLOPT_POSTFIELDS to the URL given as an argument.
|
||||
*/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
char *url;
|
||||
|
||||
if(argc < 2)
|
||||
return 1;
|
||||
|
||||
url = argv[1];
|
||||
|
||||
/* In windows, this will init the winsock stuff */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* get a curl handle */
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
struct curl_slist *headers = NULL;
|
||||
|
||||
/* default type with postfields is application/x-www-form-urlencoded,
|
||||
change it if you want */
|
||||
headers = curl_slist_append(headers, "Content-Type: literature/classic");
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
||||
|
||||
/* pass on content in request body. When CURLOPT_POSTFIELDSIZE is not used,
|
||||
curl does strlen to get the size. */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, olivertwist);
|
||||
|
||||
/* override the POST implied by CURLOPT_POSTFIELDS
|
||||
*
|
||||
* Warning: CURLOPT_CUSTOMREQUEST is problematic, especially if you want
|
||||
* to follow redirects. Be aware.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
|
||||
|
||||
/* specify target URL, and note that this URL should include a file
|
||||
name, not only a directory */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
|
||||
/* Now run off and do what you have been told! */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
/* free headers */
|
||||
curl_slist_free_all(headers);
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
||||
123
Engine/lib/curl/docs/examples/httpput.c
Normal file
123
Engine/lib/curl/docs/examples/httpput.c
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* HTTP PUT with easy interface and read callback
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/*
|
||||
* This example shows a HTTP PUT operation. PUTs a file given as a command
|
||||
* line argument to the URL also given on the command line.
|
||||
*
|
||||
* This example also uses its own read callback.
|
||||
*
|
||||
* Here's an article on how to setup a PUT handler for Apache:
|
||||
* http://www.apacheweek.com/features/put
|
||||
*/
|
||||
|
||||
static size_t read_callback(char *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
size_t retcode;
|
||||
unsigned long nread;
|
||||
|
||||
/* in real-world cases, this would probably get this data differently
|
||||
as this fread() stuff is exactly what the library already would do
|
||||
by default internally */
|
||||
retcode = fread(ptr, size, nmemb, stream);
|
||||
|
||||
if(retcode > 0) {
|
||||
nread = (unsigned long)retcode;
|
||||
fprintf(stderr, "*** We read %lu bytes from file\n", nread);
|
||||
}
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
FILE * hd_src;
|
||||
struct stat file_info;
|
||||
|
||||
char *file;
|
||||
char *url;
|
||||
|
||||
if(argc < 3)
|
||||
return 1;
|
||||
|
||||
file = argv[1];
|
||||
url = argv[2];
|
||||
|
||||
/* get the file size of the local file */
|
||||
stat(file, &file_info);
|
||||
|
||||
/* 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(file, "rb");
|
||||
|
||||
/* In windows, this will init the winsock stuff */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* get a curl handle */
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* we want to use our own read function */
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
|
||||
|
||||
/* enable uploading (implies PUT over HTTP) */
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
/* specify target URL, and note that this URL should include a file
|
||||
name, not only a directory */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
|
||||
/* now specify which file to upload */
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, hd_src);
|
||||
|
||||
/* provide the size of the upload, we specicially typecast the value
|
||||
to curl_off_t since we must be sure to use the correct data size */
|
||||
curl_easy_setopt(curl, CURLOPT_INFILESIZE_LARGE,
|
||||
(curl_off_t)file_info.st_size);
|
||||
|
||||
/* Now run off and do what you have been told! */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
fclose(hd_src); /* close the local file */
|
||||
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
||||
80
Engine/lib/curl/docs/examples/https.c
Normal file
80
Engine/lib/curl/docs/examples/https.c
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Simple HTTPS GET
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
|
||||
|
||||
#ifdef SKIP_PEER_VERIFICATION
|
||||
/*
|
||||
* If you want to connect to a site who is not using a certificate that is
|
||||
* signed by one of the certs in the CA bundle you have, you can skip the
|
||||
* verification of the server's certificate. This makes the connection
|
||||
* A LOT LESS SECURE.
|
||||
*
|
||||
* If you have a CA cert for the server stored someplace else than in the
|
||||
* default bundle, then the CURLOPT_CAPATH option might come handy for
|
||||
* you.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
#endif
|
||||
|
||||
#ifdef SKIP_HOSTNAME_VERIFICATION
|
||||
/*
|
||||
* If the site you are connecting to uses a different host name that what
|
||||
* they have mentioned in their server certificate's commonName (or
|
||||
* subjectAltName) fields, libcurl will refuse to connect. You can skip
|
||||
* this check, but this will make the connection less secure.
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
#endif
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
132
Engine/lib/curl/docs/examples/imap-append.c
Normal file
132
Engine/lib/curl/docs/examples/imap-append.c
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example showing how to send emails
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to send mail using libcurl's IMAP
|
||||
* capabilities.
|
||||
*
|
||||
* Note that this example requires libcurl 7.30.0 or above.
|
||||
*/
|
||||
|
||||
#define FROM "<sender@example.org>"
|
||||
#define TO "<addressee@example.net>"
|
||||
#define CC "<info@example.org>"
|
||||
|
||||
static const char *payload_text =
|
||||
"Date: Mon, 29 Nov 2010 21:54:29 +1100\r\n"
|
||||
"To: " TO "\r\n"
|
||||
"From: " FROM "(Example User)\r\n"
|
||||
"Cc: " CC "(Another example User)\r\n"
|
||||
"Message-ID: "
|
||||
"<dcd7cb36-11db-487a-9f3a-e652a9458efd@rfcpedant.example.org>\r\n"
|
||||
"Subject: IMAP example message\r\n"
|
||||
"\r\n" /* empty line to divide headers from body, see RFC5322 */
|
||||
"The body of the message starts here.\r\n"
|
||||
"\r\n"
|
||||
"It could be a lot of lines, could be MIME encoded, whatever.\r\n"
|
||||
"Check RFC5322.\r\n";
|
||||
|
||||
struct upload_status {
|
||||
size_t bytes_read;
|
||||
};
|
||||
|
||||
static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
struct upload_status *upload_ctx = (struct upload_status *)userp;
|
||||
const char *data;
|
||||
size_t room = size * nmemb;
|
||||
|
||||
if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
data = &payload_text[upload_ctx->bytes_read];
|
||||
|
||||
if(*data) {
|
||||
size_t len = strlen(data);
|
||||
if(room < len)
|
||||
len = room;
|
||||
memcpy(ptr, data, len);
|
||||
upload_ctx->bytes_read += len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
size_t filesize;
|
||||
long infilesize = LONG_MAX;
|
||||
struct upload_status upload_ctx = { 0 };
|
||||
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This will create a new message 100. Note that you should perform an
|
||||
* EXAMINE command to obtain the UID of the next message to create and a
|
||||
* SELECT to ensure you are creating the message in the OUTBOX. */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/100");
|
||||
|
||||
/* In this case, we are using a callback function to specify the data. You
|
||||
* could just use the CURLOPT_READDATA option to specify a FILE pointer to
|
||||
* read from. */
|
||||
curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
|
||||
curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
|
||||
curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
|
||||
|
||||
filesize = strlen(payload_text);
|
||||
if(filesize <= LONG_MAX)
|
||||
infilesize = (long)filesize;
|
||||
curl_easy_setopt(curl, CURLOPT_INFILESIZE, infilesize);
|
||||
|
||||
/* Perform the append */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
73
Engine/lib/curl/docs/examples/imap-authzid.c
Normal file
73
Engine/lib/curl/docs/examples/imap-authzid.c
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example showing how to retreieve emails from a shared mailed box
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to fetch mail using libcurl's IMAP
|
||||
* capabilities.
|
||||
*
|
||||
* Note that this example requires libcurl 7.66.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set the username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* Set the authorization identity (identity to act as) */
|
||||
curl_easy_setopt(curl, CURLOPT_SASL_AUTHZID, "shared-mailbox");
|
||||
|
||||
/* Force PLAIN authentication */
|
||||
curl_easy_setopt(curl, CURLOPT_LOGIN_OPTIONS, "AUTH=PLAIN");
|
||||
|
||||
/* This will fetch message 1 from the user's inbox */
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"imap://imap.example.com/INBOX/;UID=1");
|
||||
|
||||
/* Perform the fetch */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
73
Engine/lib/curl/docs/examples/imap-copy.c
Normal file
73
Engine/lib/curl/docs/examples/imap-copy.c
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example showing how to copy an email from one folder to another
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to copy a mail from one mailbox folder
|
||||
* to another using libcurl's IMAP capabilities.
|
||||
*
|
||||
* Note that this example requires libcurl 7.30.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This is source mailbox folder to select */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/INBOX");
|
||||
|
||||
/* Set the COPY command specifying the message ID and destination folder */
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "COPY 1 FOLDER");
|
||||
|
||||
/* Note that to perform a move operation you will need to perform the copy,
|
||||
* then mark the original mail as Deleted and EXPUNGE or CLOSE. Please see
|
||||
* imap-store.c for more information on deleting messages. */
|
||||
|
||||
/* Perform the custom request */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
69
Engine/lib/curl/docs/examples/imap-create.c
Normal file
69
Engine/lib/curl/docs/examples/imap-create.c
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example showing how to create a new folder
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to create a new mailbox folder using
|
||||
* libcurl's IMAP capabilities.
|
||||
*
|
||||
* Note that this example requires libcurl 7.30.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This is just the server URL */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com");
|
||||
|
||||
/* Set the CREATE command specifying the new folder name */
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "CREATE FOLDER");
|
||||
|
||||
/* Perform the custom request */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
69
Engine/lib/curl/docs/examples/imap-delete.c
Normal file
69
Engine/lib/curl/docs/examples/imap-delete.c
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example showing how to delete a folder
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to delete an existing mailbox folder
|
||||
* using libcurl's IMAP capabilities.
|
||||
*
|
||||
* Note that this example requires libcurl 7.30.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This is just the server URL */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com");
|
||||
|
||||
/* Set the DELETE command specifying the existing folder */
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELETE FOLDER");
|
||||
|
||||
/* Perform the custom request */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
69
Engine/lib/curl/docs/examples/imap-examine.c
Normal file
69
Engine/lib/curl/docs/examples/imap-examine.c
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example showing how to obtain information about a folder
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to obtain information about a mailbox
|
||||
* folder using libcurl's IMAP capabilities via the EXAMINE command.
|
||||
*
|
||||
* Note that this example requires libcurl 7.30.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This is just the server URL */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com");
|
||||
|
||||
/* Set the EXAMINE command specifying the mailbox folder */
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "EXAMINE OUTBOX");
|
||||
|
||||
/* Perform the custom request */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
67
Engine/lib/curl/docs/examples/imap-fetch.c
Normal file
67
Engine/lib/curl/docs/examples/imap-fetch.c
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example showing how to retreieve emails
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to fetch mail using libcurl's IMAP
|
||||
* capabilities.
|
||||
*
|
||||
* Note that this example requires libcurl 7.30.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This will fetch message 1 from the user's inbox */
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"imap://imap.example.com/INBOX/;UID=1");
|
||||
|
||||
/* Perform the fetch */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
68
Engine/lib/curl/docs/examples/imap-list.c
Normal file
68
Engine/lib/curl/docs/examples/imap-list.c
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example to list the folders within a mailbox
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to list the folders within an IMAP
|
||||
* mailbox.
|
||||
*
|
||||
* Note that this example requires libcurl 7.30.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This will list the folders within the user's mailbox. If you want to
|
||||
* list the folders within a specific folder, for example the inbox, then
|
||||
* specify the folder as a path in the URL such as /INBOX */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com");
|
||||
|
||||
/* Perform the list */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
70
Engine/lib/curl/docs/examples/imap-lsub.c
Normal file
70
Engine/lib/curl/docs/examples/imap-lsub.c
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example to list the subscribed folders
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to list the subscribed folders within
|
||||
* an IMAP mailbox.
|
||||
*
|
||||
* Note that this example requires libcurl 7.30.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This is just the server URL */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com");
|
||||
|
||||
/* Set the LSUB command. Note the syntax is very similar to that of a LIST
|
||||
command. */
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "LSUB \"\" *");
|
||||
|
||||
/* Perform the custom request */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
83
Engine/lib/curl/docs/examples/imap-multi.c
Normal file
83
Engine/lib/curl/docs/examples/imap-multi.c
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example using the multi interface
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to fetch mail using libcurl's IMAP
|
||||
* capabilities. It builds on the imap-fetch.c example to demonstrate how to
|
||||
* use libcurl's multi interface.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLM *mcurl;
|
||||
int still_running = 1;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(!curl)
|
||||
return 1;
|
||||
|
||||
mcurl = curl_multi_init();
|
||||
if(!mcurl)
|
||||
return 2;
|
||||
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This will fetch message 1 from the user's inbox */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/INBOX/;UID=1");
|
||||
|
||||
/* Tell the multi stack about our easy handle */
|
||||
curl_multi_add_handle(mcurl, curl);
|
||||
|
||||
do {
|
||||
CURLMcode mc = curl_multi_perform(mcurl, &still_running);
|
||||
|
||||
if(still_running)
|
||||
/* wait for activity, timeout or "nothing" */
|
||||
mc = curl_multi_poll(mcurl, NULL, 0, 1000, NULL);
|
||||
|
||||
if(mc)
|
||||
break;
|
||||
} while(still_running);
|
||||
|
||||
/* Always cleanup */
|
||||
curl_multi_remove_handle(mcurl, curl);
|
||||
curl_multi_cleanup(mcurl);
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
69
Engine/lib/curl/docs/examples/imap-noop.c
Normal file
69
Engine/lib/curl/docs/examples/imap-noop.c
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example showing how to perform a noop
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to perform a noop using libcurl's IMAP
|
||||
* capabilities.
|
||||
*
|
||||
* Note that this example requires libcurl 7.30.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This is just the server URL */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com");
|
||||
|
||||
/* Set the NOOP command */
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "NOOP");
|
||||
|
||||
/* Perform the custom request */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
73
Engine/lib/curl/docs/examples/imap-search.c
Normal file
73
Engine/lib/curl/docs/examples/imap-search.c
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example showing how to search for new emails
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to search for new messages using
|
||||
* libcurl's IMAP capabilities.
|
||||
*
|
||||
* Note that this example requires libcurl 7.30.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This is mailbox folder to select */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/INBOX");
|
||||
|
||||
/* Set the SEARCH command specifying what we want to search for. Note that
|
||||
* this can contain a message sequence set and a number of search criteria
|
||||
* keywords including flags such as ANSWERED, DELETED, DRAFT, FLAGGED, NEW,
|
||||
* RECENT and SEEN. For more information about the search criteria please
|
||||
* see RFC-3501 section 6.4.4. */
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "SEARCH NEW");
|
||||
|
||||
/* Perform the custom request */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
94
Engine/lib/curl/docs/examples/imap-ssl.c
Normal file
94
Engine/lib/curl/docs/examples/imap-ssl.c
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example using SSL
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to fetch mail using libcurl's IMAP
|
||||
* capabilities. It builds on the imap-fetch.c example adding transport
|
||||
* security to protect the authentication details from being snooped.
|
||||
*
|
||||
* Note that this example requires libcurl 7.30.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This will fetch message 1 from the user's inbox. Note the use of
|
||||
* imaps:// rather than imap:// to request a SSL based connection. */
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"imaps://imap.example.com/INBOX/;UID=1");
|
||||
|
||||
/* If you want to connect to a site who is not using a certificate that is
|
||||
* signed by one of the certs in the CA bundle you have, you can skip the
|
||||
* verification of the server's certificate. This makes the connection
|
||||
* A LOT LESS SECURE.
|
||||
*
|
||||
* If you have a CA cert for the server stored someplace else than in the
|
||||
* default bundle, then the CURLOPT_CAPATH option might come handy for
|
||||
* you. */
|
||||
#ifdef SKIP_PEER_VERIFICATION
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
#endif
|
||||
|
||||
/* If the site you are connecting to uses a different host name that what
|
||||
* they have mentioned in their server certificate's commonName (or
|
||||
* subjectAltName) fields, libcurl will refuse to connect. You can skip
|
||||
* this check, but this will make the connection less secure. */
|
||||
#ifdef SKIP_HOSTNAME_VERIFICATION
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
#endif
|
||||
|
||||
/* Since the traffic will be encrypted, it is very useful to turn on debug
|
||||
* information within libcurl to see what is happening during the
|
||||
* transfer */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* Perform the fetch */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
84
Engine/lib/curl/docs/examples/imap-store.c
Normal file
84
Engine/lib/curl/docs/examples/imap-store.c
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example showing how to modify the properties of an email
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to modify an existing mail using
|
||||
* libcurl's IMAP capabilities with the STORE command.
|
||||
*
|
||||
* Note that this example requires libcurl 7.30.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This is the mailbox folder to select */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "imap://imap.example.com/INBOX");
|
||||
|
||||
/* Set the STORE command with the Deleted flag for message 1. Note that
|
||||
* you can use the STORE command to set other flags such as Seen, Answered,
|
||||
* Flagged, Draft and Recent. */
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "STORE 1 +Flags \\Deleted");
|
||||
|
||||
/* Perform the custom request */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
else {
|
||||
/* Set the EXPUNGE command, although you can use the CLOSE command if you
|
||||
* do not want to know the result of the STORE */
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "EXPUNGE");
|
||||
|
||||
/* Perform the second custom request */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
}
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
94
Engine/lib/curl/docs/examples/imap-tls.c
Normal file
94
Engine/lib/curl/docs/examples/imap-tls.c
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* IMAP example using TLS
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to fetch mail using libcurl's IMAP
|
||||
* capabilities. It builds on the imap-fetch.c example adding transport
|
||||
* security to protect the authentication details from being snooped.
|
||||
*
|
||||
* Note that this example requires libcurl 7.30.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This will fetch message 1 from the user's inbox */
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"imap://imap.example.com/INBOX/;UID=1");
|
||||
|
||||
/* In this example, we will start with a plain text connection, and upgrade
|
||||
* to Transport Layer Security (TLS) using the STARTTLS command. Be careful
|
||||
* of using CURLUSESSL_TRY here, because if TLS upgrade fails, the transfer
|
||||
* will continue anyway - see the security discussion in the libcurl
|
||||
* tutorial for more details. */
|
||||
curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
|
||||
|
||||
/* If your server does not have a valid certificate, then you can disable
|
||||
* part of the Transport Layer Security protection by setting the
|
||||
* CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST options to 0 (false).
|
||||
* curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
* curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
*
|
||||
* That is, in general, a bad idea. It is still better than sending your
|
||||
* authentication details in plain text though. Instead, you should get
|
||||
* the issuer certificate (or the host certificate if the certificate is
|
||||
* self-signed) and add it to the set of certificates that are known to
|
||||
* libcurl using CURLOPT_CAINFO and/or CURLOPT_CAPATH. See docs/SSLCERTS
|
||||
* for more information. */
|
||||
curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/certificate.pem");
|
||||
|
||||
/* Since the traffic will be encrypted, it is very useful to turn on debug
|
||||
* information within libcurl to see what is happening during the
|
||||
* transfer */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* Perform the fetch */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
57
Engine/lib/curl/docs/examples/makefile.dj
Normal file
57
Engine/lib/curl/docs/examples/makefile.dj
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.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.
|
||||
#
|
||||
# SPDX-License-Identifier: curl
|
||||
#
|
||||
###########################################################################
|
||||
|
||||
TOPDIR = ../..
|
||||
|
||||
include $(TOPDIR)/packages/DOS/common.dj
|
||||
|
||||
CFLAGS += -DFALSE=0 -DTRUE=1
|
||||
|
||||
LIBS = $(TOPDIR)/lib/libcurl.a
|
||||
|
||||
ifeq ($(USE_SSL),1)
|
||||
LIBS += $(OPENSSL_ROOT)/lib/libssl.a $(OPENSSL_ROOT)/lib/libcrypt.a
|
||||
endif
|
||||
|
||||
ifeq ($(USE_IDNA),1)
|
||||
LIBS += $(LIBIDN_ROOT)/lib/dj_obj/libidn.a -liconv
|
||||
endif
|
||||
|
||||
LIBS += $(WATT32_ROOT)/lib/libwatt.a $(ZLIB_ROOT)/libz.a
|
||||
|
||||
include Makefile.inc
|
||||
|
||||
PROGRAMS = $(patsubst %,%.exe,$(check_PROGRAMS))
|
||||
|
||||
all: $(PROGRAMS)
|
||||
@echo Welcome to libcurl example program
|
||||
|
||||
%.exe: %.c
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
|
||||
@echo
|
||||
|
||||
clean vclean realclean:
|
||||
- rm -f $(PROGRAMS) depend.dj
|
||||
|
||||
-include depend.dj
|
||||
118
Engine/lib/curl/docs/examples/multi-app.c
Normal file
118
Engine/lib/curl/docs/examples/multi-app.c
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* A basic application source code using the multi interface doing two
|
||||
* transfers in parallel.
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* curl stuff */
|
||||
#include <curl/curl.h>
|
||||
|
||||
/*
|
||||
* Download a HTTP file and upload an FTP file simultaneously.
|
||||
*/
|
||||
|
||||
#define HANDLECOUNT 2 /* Number of simultaneous transfers */
|
||||
#define HTTP_HANDLE 0 /* Index for the HTTP transfer */
|
||||
#define FTP_HANDLE 1 /* Index for the FTP transfer */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *handles[HANDLECOUNT];
|
||||
CURLM *multi_handle;
|
||||
|
||||
int still_running = 1; /* keep number of running handles */
|
||||
int i;
|
||||
|
||||
CURLMsg *msg; /* for picking up messages with the transfer status */
|
||||
int msgs_left; /* how many messages are left */
|
||||
|
||||
/* Allocate one CURL handle per transfer */
|
||||
for(i = 0; i<HANDLECOUNT; i++)
|
||||
handles[i] = curl_easy_init();
|
||||
|
||||
/* set the options (I left out a few, you will get the point anyway) */
|
||||
curl_easy_setopt(handles[HTTP_HANDLE], CURLOPT_URL, "https://example.com");
|
||||
|
||||
curl_easy_setopt(handles[FTP_HANDLE], CURLOPT_URL, "ftp://example.com");
|
||||
curl_easy_setopt(handles[FTP_HANDLE], CURLOPT_UPLOAD, 1L);
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
/* add the individual transfers */
|
||||
for(i = 0; i<HANDLECOUNT; i++)
|
||||
curl_multi_add_handle(multi_handle, handles[i]);
|
||||
|
||||
while(still_running) {
|
||||
CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
if(still_running)
|
||||
/* wait for activity, timeout or "nothing" */
|
||||
mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
|
||||
|
||||
if(mc)
|
||||
break;
|
||||
}
|
||||
/* See how the transfers went */
|
||||
while((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
|
||||
if(msg->msg == CURLMSG_DONE) {
|
||||
int idx;
|
||||
|
||||
/* Find out which handle this message is about */
|
||||
for(idx = 0; idx<HANDLECOUNT; idx++) {
|
||||
int found = (msg->easy_handle == handles[idx]);
|
||||
if(found)
|
||||
break;
|
||||
}
|
||||
|
||||
switch(idx) {
|
||||
case HTTP_HANDLE:
|
||||
printf("HTTP transfer completed with status %d\n", msg->data.result);
|
||||
break;
|
||||
case FTP_HANDLE:
|
||||
printf("FTP transfer completed with status %d\n", msg->data.result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* remove the transfers and cleanup the handles */
|
||||
for(i = 0; i<HANDLECOUNT; i++) {
|
||||
curl_multi_remove_handle(multi_handle, handles[i]);
|
||||
curl_easy_cleanup(handles[i]);
|
||||
}
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
169
Engine/lib/curl/docs/examples/multi-debugcallback.c
Normal file
169
Engine/lib/curl/docs/examples/multi-debugcallback.c
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* multi interface and debug callback
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* curl stuff */
|
||||
#include <curl/curl.h>
|
||||
|
||||
typedef char bool;
|
||||
#define TRUE 1
|
||||
|
||||
static
|
||||
void dump(const char *text,
|
||||
FILE *stream, unsigned char *ptr, size_t size,
|
||||
bool 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, %10.10lu bytes (0x%8.8lx)\n",
|
||||
text, (unsigned long)size, (unsigned long)size);
|
||||
|
||||
for(i = 0; i<size; i += width) {
|
||||
|
||||
fprintf(stream, "%4.4lx: ", (unsigned long)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,
|
||||
unsigned char *data, size_t size,
|
||||
void *userp)
|
||||
{
|
||||
const char *text;
|
||||
|
||||
(void)userp;
|
||||
(void)handle; /* prevent compiler warning */
|
||||
|
||||
switch(type) {
|
||||
case CURLINFO_TEXT:
|
||||
fprintf(stderr, "== Info: %s", data);
|
||||
/* FALLTHROUGH */
|
||||
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_HEADER_IN:
|
||||
text = "<= Recv header";
|
||||
break;
|
||||
case CURLINFO_DATA_IN:
|
||||
text = "<= Recv data";
|
||||
break;
|
||||
}
|
||||
|
||||
dump(text, stderr, data, size, TRUE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Simply download a HTTP file.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
CURL *http_handle;
|
||||
CURLM *multi_handle;
|
||||
|
||||
int still_running = 0; /* keep number of running handles */
|
||||
|
||||
http_handle = curl_easy_init();
|
||||
|
||||
/* set the options (I left out a few, you will get the point anyway) */
|
||||
curl_easy_setopt(http_handle, CURLOPT_URL, "https://www.example.com/");
|
||||
|
||||
curl_easy_setopt(http_handle, CURLOPT_DEBUGFUNCTION, my_trace);
|
||||
curl_easy_setopt(http_handle, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
/* add the individual transfers */
|
||||
curl_multi_add_handle(multi_handle, http_handle);
|
||||
|
||||
do {
|
||||
CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
if(still_running)
|
||||
/* wait for activity, timeout or "nothing" */
|
||||
mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
|
||||
|
||||
if(mc)
|
||||
break;
|
||||
|
||||
} while(still_running);
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
curl_easy_cleanup(http_handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
97
Engine/lib/curl/docs/examples/multi-double.c
Normal file
97
Engine/lib/curl/docs/examples/multi-double.c
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* multi interface code doing two parallel HTTP transfers
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* curl stuff */
|
||||
#include <curl/curl.h>
|
||||
|
||||
/*
|
||||
* Simply download two HTTP files!
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
CURL *http_handle;
|
||||
CURL *http_handle2;
|
||||
CURLM *multi_handle;
|
||||
|
||||
int still_running = 1; /* keep number of running handles */
|
||||
|
||||
http_handle = curl_easy_init();
|
||||
http_handle2 = curl_easy_init();
|
||||
|
||||
/* set options */
|
||||
curl_easy_setopt(http_handle, CURLOPT_URL, "https://www.example.com/");
|
||||
|
||||
/* set options */
|
||||
curl_easy_setopt(http_handle2, CURLOPT_URL, "http://localhost/");
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
/* add the individual transfers */
|
||||
curl_multi_add_handle(multi_handle, http_handle);
|
||||
curl_multi_add_handle(multi_handle, http_handle2);
|
||||
|
||||
while(still_running) {
|
||||
CURLMsg *msg;
|
||||
int queued;
|
||||
CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
if(still_running)
|
||||
/* wait for activity, timeout or "nothing" */
|
||||
mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
|
||||
|
||||
if(mc)
|
||||
break;
|
||||
|
||||
do {
|
||||
msg = curl_multi_info_read(multi_handle, &queued);
|
||||
if(msg) {
|
||||
if(msg->msg == CURLMSG_DONE) {
|
||||
/* a transfer ended */
|
||||
fprintf(stderr, "Transfer completed\n");
|
||||
}
|
||||
}
|
||||
} while(msg);
|
||||
}
|
||||
|
||||
curl_multi_remove_handle(multi_handle, http_handle);
|
||||
curl_multi_remove_handle(multi_handle, http_handle2);
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
curl_easy_cleanup(http_handle);
|
||||
curl_easy_cleanup(http_handle2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
242
Engine/lib/curl/docs/examples/multi-event.c
Normal file
242
Engine/lib/curl/docs/examples/multi-event.c
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* multi_socket API using libevent
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <event2/event.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
struct event_base *base;
|
||||
CURLM *curl_handle;
|
||||
struct event *timeout;
|
||||
|
||||
typedef struct curl_context_s {
|
||||
struct event *event;
|
||||
curl_socket_t sockfd;
|
||||
} curl_context_t;
|
||||
|
||||
static void curl_perform(int fd, short event, void *arg);
|
||||
|
||||
static curl_context_t *create_curl_context(curl_socket_t sockfd)
|
||||
{
|
||||
curl_context_t *context;
|
||||
|
||||
context = (curl_context_t *) malloc(sizeof(*context));
|
||||
|
||||
context->sockfd = sockfd;
|
||||
|
||||
context->event = event_new(base, sockfd, 0, curl_perform, context);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
static void destroy_curl_context(curl_context_t *context)
|
||||
{
|
||||
event_del(context->event);
|
||||
event_free(context->event);
|
||||
free(context);
|
||||
}
|
||||
|
||||
static void add_download(const char *url, int num)
|
||||
{
|
||||
char filename[50];
|
||||
FILE *file;
|
||||
CURL *handle;
|
||||
|
||||
snprintf(filename, 50, "%d.download", num);
|
||||
|
||||
file = fopen(filename, "wb");
|
||||
if(!file) {
|
||||
fprintf(stderr, "Error opening %s\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
handle = curl_easy_init();
|
||||
curl_easy_setopt(handle, CURLOPT_WRITEDATA, file);
|
||||
curl_easy_setopt(handle, CURLOPT_PRIVATE, file);
|
||||
curl_easy_setopt(handle, CURLOPT_URL, url);
|
||||
curl_multi_add_handle(curl_handle, handle);
|
||||
fprintf(stderr, "Added download %s -> %s\n", url, filename);
|
||||
}
|
||||
|
||||
static void check_multi_info(void)
|
||||
{
|
||||
char *done_url;
|
||||
CURLMsg *message;
|
||||
int pending;
|
||||
CURL *easy_handle;
|
||||
FILE *file;
|
||||
|
||||
while((message = curl_multi_info_read(curl_handle, &pending))) {
|
||||
switch(message->msg) {
|
||||
case CURLMSG_DONE:
|
||||
/* Do not use message data after calling curl_multi_remove_handle() and
|
||||
curl_easy_cleanup(). As per curl_multi_info_read() docs:
|
||||
"WARNING: The data the returned pointer points to will not survive
|
||||
calling curl_multi_cleanup, curl_multi_remove_handle or
|
||||
curl_easy_cleanup." */
|
||||
easy_handle = message->easy_handle;
|
||||
|
||||
curl_easy_getinfo(easy_handle, CURLINFO_EFFECTIVE_URL, &done_url);
|
||||
curl_easy_getinfo(easy_handle, CURLINFO_PRIVATE, &file);
|
||||
printf("%s DONE\n", done_url);
|
||||
|
||||
curl_multi_remove_handle(curl_handle, easy_handle);
|
||||
curl_easy_cleanup(easy_handle);
|
||||
if(file) {
|
||||
fclose(file);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "CURLMSG default\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void curl_perform(int fd, short event, void *arg)
|
||||
{
|
||||
int running_handles;
|
||||
int flags = 0;
|
||||
curl_context_t *context;
|
||||
|
||||
if(event & EV_READ)
|
||||
flags |= CURL_CSELECT_IN;
|
||||
if(event & EV_WRITE)
|
||||
flags |= CURL_CSELECT_OUT;
|
||||
|
||||
context = (curl_context_t *) arg;
|
||||
|
||||
curl_multi_socket_action(curl_handle, context->sockfd, flags,
|
||||
&running_handles);
|
||||
|
||||
check_multi_info();
|
||||
}
|
||||
|
||||
static void on_timeout(evutil_socket_t fd, short events, void *arg)
|
||||
{
|
||||
int running_handles;
|
||||
curl_multi_socket_action(curl_handle, CURL_SOCKET_TIMEOUT, 0,
|
||||
&running_handles);
|
||||
check_multi_info();
|
||||
}
|
||||
|
||||
static int start_timeout(CURLM *multi, long timeout_ms, void *userp)
|
||||
{
|
||||
if(timeout_ms < 0) {
|
||||
evtimer_del(timeout);
|
||||
}
|
||||
else {
|
||||
if(timeout_ms == 0)
|
||||
timeout_ms = 1; /* 0 means directly call socket_action, but we will do it
|
||||
in a bit */
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeout_ms / 1000;
|
||||
tv.tv_usec = (timeout_ms % 1000) * 1000;
|
||||
evtimer_del(timeout);
|
||||
evtimer_add(timeout, &tv);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handle_socket(CURL *easy, curl_socket_t s, int action, void *userp,
|
||||
void *socketp)
|
||||
{
|
||||
curl_context_t *curl_context;
|
||||
int events = 0;
|
||||
|
||||
switch(action) {
|
||||
case CURL_POLL_IN:
|
||||
case CURL_POLL_OUT:
|
||||
case CURL_POLL_INOUT:
|
||||
curl_context = socketp ?
|
||||
(curl_context_t *) socketp : create_curl_context(s);
|
||||
|
||||
curl_multi_assign(curl_handle, s, (void *) curl_context);
|
||||
|
||||
if(action != CURL_POLL_IN)
|
||||
events |= EV_WRITE;
|
||||
if(action != CURL_POLL_OUT)
|
||||
events |= EV_READ;
|
||||
|
||||
events |= EV_PERSIST;
|
||||
|
||||
event_del(curl_context->event);
|
||||
event_assign(curl_context->event, base, curl_context->sockfd, events,
|
||||
curl_perform, curl_context);
|
||||
event_add(curl_context->event, NULL);
|
||||
|
||||
break;
|
||||
case CURL_POLL_REMOVE:
|
||||
if(socketp) {
|
||||
event_del(((curl_context_t*) socketp)->event);
|
||||
destroy_curl_context((curl_context_t*) socketp);
|
||||
curl_multi_assign(curl_handle, s, NULL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if(argc <= 1)
|
||||
return 0;
|
||||
|
||||
if(curl_global_init(CURL_GLOBAL_ALL)) {
|
||||
fprintf(stderr, "Could not init curl\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
base = event_base_new();
|
||||
timeout = evtimer_new(base, on_timeout, NULL);
|
||||
|
||||
curl_handle = curl_multi_init();
|
||||
curl_multi_setopt(curl_handle, CURLMOPT_SOCKETFUNCTION, handle_socket);
|
||||
curl_multi_setopt(curl_handle, CURLMOPT_TIMERFUNCTION, start_timeout);
|
||||
|
||||
while(argc-- > 1) {
|
||||
add_download(argv[argc], argc);
|
||||
}
|
||||
|
||||
event_base_dispatch(base);
|
||||
|
||||
curl_multi_cleanup(curl_handle);
|
||||
event_free(timeout);
|
||||
event_base_free(base);
|
||||
|
||||
libevent_global_shutdown();
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
110
Engine/lib/curl/docs/examples/multi-formadd.c
Normal file
110
Engine/lib/curl/docs/examples/multi-formadd.c
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* using the multi interface to do a multipart formpost without blocking
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
|
||||
CURLM *multi_handle;
|
||||
int still_running = 0;
|
||||
|
||||
struct curl_httppost *formpost = NULL;
|
||||
struct curl_httppost *lastptr = NULL;
|
||||
struct curl_slist *headerlist = NULL;
|
||||
static const char buf[] = "Expect:";
|
||||
|
||||
/* Fill in the file upload field. This makes libcurl load data from
|
||||
the given file name when curl_easy_perform() is called. */
|
||||
curl_formadd(&formpost,
|
||||
&lastptr,
|
||||
CURLFORM_COPYNAME, "sendfile",
|
||||
CURLFORM_FILE, "postit2.c",
|
||||
CURLFORM_END);
|
||||
|
||||
/* Fill in the filename field */
|
||||
curl_formadd(&formpost,
|
||||
&lastptr,
|
||||
CURLFORM_COPYNAME, "filename",
|
||||
CURLFORM_COPYCONTENTS, "postit2.c",
|
||||
CURLFORM_END);
|
||||
|
||||
/* Fill in the submit field too, even if this is rarely needed */
|
||||
curl_formadd(&formpost,
|
||||
&lastptr,
|
||||
CURLFORM_COPYNAME, "submit",
|
||||
CURLFORM_COPYCONTENTS, "send",
|
||||
CURLFORM_END);
|
||||
|
||||
curl = curl_easy_init();
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
/* initialize custom header list (stating that Expect: 100-continue is not
|
||||
wanted */
|
||||
headerlist = curl_slist_append(headerlist, buf);
|
||||
if(curl && multi_handle) {
|
||||
|
||||
/* what URL that receives this POST */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com/upload.cgi");
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
|
||||
|
||||
curl_multi_add_handle(multi_handle, curl);
|
||||
|
||||
do {
|
||||
CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
if(still_running)
|
||||
/* wait for activity, timeout or "nothing" */
|
||||
mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
|
||||
|
||||
if(mc)
|
||||
break;
|
||||
|
||||
} while(still_running);
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
/* then cleanup the formpost chain */
|
||||
curl_formfree(formpost);
|
||||
|
||||
/* free slist */
|
||||
curl_slist_free_all(headerlist);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
179
Engine/lib/curl/docs/examples/multi-legacy.c
Normal file
179
Engine/lib/curl/docs/examples/multi-legacy.c
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* A basic application source code using the multi interface doing two
|
||||
* transfers in parallel without curl_multi_wait/poll.
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* curl stuff */
|
||||
#include <curl/curl.h>
|
||||
|
||||
/*
|
||||
* Download a HTTP file and upload an FTP file simultaneously.
|
||||
*/
|
||||
|
||||
#define HANDLECOUNT 2 /* Number of simultaneous transfers */
|
||||
#define HTTP_HANDLE 0 /* Index for the HTTP transfer */
|
||||
#define FTP_HANDLE 1 /* Index for the FTP transfer */
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *handles[HANDLECOUNT];
|
||||
CURLM *multi_handle;
|
||||
|
||||
int still_running = 0; /* keep number of running handles */
|
||||
int i;
|
||||
|
||||
CURLMsg *msg; /* for picking up messages with the transfer status */
|
||||
int msgs_left; /* how many messages are left */
|
||||
|
||||
/* Allocate one CURL handle per transfer */
|
||||
for(i = 0; i<HANDLECOUNT; i++)
|
||||
handles[i] = curl_easy_init();
|
||||
|
||||
/* set the options (I left out a few, you will get the point anyway) */
|
||||
curl_easy_setopt(handles[HTTP_HANDLE], CURLOPT_URL, "https://example.com");
|
||||
|
||||
curl_easy_setopt(handles[FTP_HANDLE], CURLOPT_URL, "ftp://example.com");
|
||||
curl_easy_setopt(handles[FTP_HANDLE], CURLOPT_UPLOAD, 1L);
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
/* add the individual transfers */
|
||||
for(i = 0; i<HANDLECOUNT; i++)
|
||||
curl_multi_add_handle(multi_handle, handles[i]);
|
||||
|
||||
/* we start some action by calling perform right away */
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
while(still_running) {
|
||||
struct timeval timeout;
|
||||
int rc; /* select() return code */
|
||||
CURLMcode mc; /* curl_multi_fdset() return code */
|
||||
|
||||
fd_set fdread;
|
||||
fd_set fdwrite;
|
||||
fd_set fdexcep;
|
||||
int maxfd = -1;
|
||||
|
||||
long curl_timeo = -1;
|
||||
|
||||
FD_ZERO(&fdread);
|
||||
FD_ZERO(&fdwrite);
|
||||
FD_ZERO(&fdexcep);
|
||||
|
||||
/* set a suitable timeout to play around with */
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
curl_multi_timeout(multi_handle, &curl_timeo);
|
||||
if(curl_timeo >= 0) {
|
||||
timeout.tv_sec = curl_timeo / 1000;
|
||||
if(timeout.tv_sec > 1)
|
||||
timeout.tv_sec = 1;
|
||||
else
|
||||
timeout.tv_usec = (curl_timeo % 1000) * 1000;
|
||||
}
|
||||
|
||||
/* get file descriptors from the transfers */
|
||||
mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
|
||||
|
||||
if(mc != CURLM_OK) {
|
||||
fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
|
||||
break;
|
||||
}
|
||||
|
||||
/* On success the value of maxfd is guaranteed to be >= -1. We call
|
||||
select(maxfd + 1, ...); specially in case of (maxfd == -1) there are
|
||||
no fds ready yet so we call select(0, ...) --or Sleep() on Windows--
|
||||
to sleep 100ms, which is the minimum suggested value in the
|
||||
curl_multi_fdset() doc. */
|
||||
|
||||
if(maxfd == -1) {
|
||||
#ifdef _WIN32
|
||||
Sleep(100);
|
||||
rc = 0;
|
||||
#else
|
||||
/* Portable sleep for platforms other than Windows. */
|
||||
struct timeval wait = { 0, 100 * 1000 }; /* 100ms */
|
||||
rc = select(0, NULL, NULL, NULL, &wait);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
/* Note that on some platforms 'timeout' may be modified by select().
|
||||
If you need access to the original value save a copy beforehand. */
|
||||
rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
|
||||
}
|
||||
|
||||
switch(rc) {
|
||||
case -1:
|
||||
/* select error */
|
||||
break;
|
||||
case 0: /* timeout */
|
||||
default: /* action */
|
||||
curl_multi_perform(multi_handle, &still_running);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* See how the transfers went */
|
||||
while((msg = curl_multi_info_read(multi_handle, &msgs_left))) {
|
||||
if(msg->msg == CURLMSG_DONE) {
|
||||
int idx;
|
||||
|
||||
/* Find out which handle this message is about */
|
||||
for(idx = 0; idx<HANDLECOUNT; idx++) {
|
||||
int found = (msg->easy_handle == handles[idx]);
|
||||
if(found)
|
||||
break;
|
||||
}
|
||||
|
||||
switch(idx) {
|
||||
case HTTP_HANDLE:
|
||||
printf("HTTP transfer completed with status %d\n", msg->data.result);
|
||||
break;
|
||||
case FTP_HANDLE:
|
||||
printf("FTP transfer completed with status %d\n", msg->data.result);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
/* Free the CURL handles */
|
||||
for(i = 0; i<HANDLECOUNT; i++)
|
||||
curl_easy_cleanup(handles[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
105
Engine/lib/curl/docs/examples/multi-post.c
Normal file
105
Engine/lib/curl/docs/examples/multi-post.c
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* using the multi interface to do a multipart formpost without blocking
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
|
||||
CURLM *multi_handle;
|
||||
int still_running = 0;
|
||||
|
||||
curl_mime *form = NULL;
|
||||
curl_mimepart *field = NULL;
|
||||
struct curl_slist *headerlist = NULL;
|
||||
static const char buf[] = "Expect:";
|
||||
|
||||
curl = curl_easy_init();
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
if(curl && multi_handle) {
|
||||
/* Create the form */
|
||||
form = curl_mime_init(curl);
|
||||
|
||||
/* Fill in the file upload field */
|
||||
field = curl_mime_addpart(form);
|
||||
curl_mime_name(field, "sendfile");
|
||||
curl_mime_filedata(field, "multi-post.c");
|
||||
|
||||
/* Fill in the filename field */
|
||||
field = curl_mime_addpart(form);
|
||||
curl_mime_name(field, "filename");
|
||||
curl_mime_data(field, "multi-post.c", CURL_ZERO_TERMINATED);
|
||||
|
||||
/* Fill in the submit field too, even if this is rarely needed */
|
||||
field = curl_mime_addpart(form);
|
||||
curl_mime_name(field, "submit");
|
||||
curl_mime_data(field, "send", CURL_ZERO_TERMINATED);
|
||||
|
||||
/* initialize custom header list (stating that Expect: 100-continue is not
|
||||
wanted */
|
||||
headerlist = curl_slist_append(headerlist, buf);
|
||||
|
||||
/* what URL that receives this POST */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com/upload.cgi");
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
|
||||
curl_easy_setopt(curl, CURLOPT_MIMEPOST, form);
|
||||
|
||||
curl_multi_add_handle(multi_handle, curl);
|
||||
|
||||
do {
|
||||
CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
if(still_running)
|
||||
/* wait for activity, timeout or "nothing" */
|
||||
mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
|
||||
|
||||
if(mc)
|
||||
break;
|
||||
} while(still_running);
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
/* then cleanup the form */
|
||||
curl_mime_free(form);
|
||||
|
||||
/* free slist */
|
||||
curl_slist_free_all(headerlist);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
84
Engine/lib/curl/docs/examples/multi-single.c
Normal file
84
Engine/lib/curl/docs/examples/multi-single.c
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* using the multi interface to do a single download
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* somewhat unix-specific */
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* curl stuff */
|
||||
#include <curl/curl.h>
|
||||
|
||||
/*
|
||||
* Simply download a HTTP file.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
CURL *http_handle;
|
||||
CURLM *multi_handle;
|
||||
int still_running = 1; /* keep number of running handles */
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
http_handle = curl_easy_init();
|
||||
|
||||
/* set the options (I left out a few, you will get the point anyway) */
|
||||
curl_easy_setopt(http_handle, CURLOPT_URL, "https://www.example.com/");
|
||||
|
||||
/* init a multi stack */
|
||||
multi_handle = curl_multi_init();
|
||||
|
||||
/* add the individual transfers */
|
||||
curl_multi_add_handle(multi_handle, http_handle);
|
||||
|
||||
do {
|
||||
CURLMcode mc = curl_multi_perform(multi_handle, &still_running);
|
||||
|
||||
if(!mc)
|
||||
/* wait for activity, timeout or "nothing" */
|
||||
mc = curl_multi_poll(multi_handle, NULL, 0, 1000, NULL);
|
||||
|
||||
if(mc) {
|
||||
fprintf(stderr, "curl_multi_poll() failed, code %d.\n", (int)mc);
|
||||
break;
|
||||
}
|
||||
|
||||
} while(still_running);
|
||||
|
||||
curl_multi_remove_handle(multi_handle, http_handle);
|
||||
|
||||
curl_easy_cleanup(http_handle);
|
||||
|
||||
curl_multi_cleanup(multi_handle);
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
237
Engine/lib/curl/docs/examples/multi-uv.c
Normal file
237
Engine/lib/curl/docs/examples/multi-uv.c
Normal file
|
|
@ -0,0 +1,237 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* multi_socket API using libuv
|
||||
* </DESC>
|
||||
*/
|
||||
/* Example application using the multi socket interface to download multiple
|
||||
files in parallel, powered by libuv.
|
||||
|
||||
Requires libuv and (of course) libcurl.
|
||||
|
||||
See https://nikhilm.github.io/uvbook/ for more information on libuv.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <uv.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
uv_loop_t *loop;
|
||||
CURLM *curl_handle;
|
||||
uv_timer_t timeout;
|
||||
|
||||
typedef struct curl_context_s {
|
||||
uv_poll_t poll_handle;
|
||||
curl_socket_t sockfd;
|
||||
} curl_context_t;
|
||||
|
||||
static curl_context_t *create_curl_context(curl_socket_t sockfd)
|
||||
{
|
||||
curl_context_t *context;
|
||||
|
||||
context = (curl_context_t *) malloc(sizeof(*context));
|
||||
|
||||
context->sockfd = sockfd;
|
||||
|
||||
uv_poll_init_socket(loop, &context->poll_handle, sockfd);
|
||||
context->poll_handle.data = context;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
static void curl_close_cb(uv_handle_t *handle)
|
||||
{
|
||||
curl_context_t *context = (curl_context_t *) handle->data;
|
||||
free(context);
|
||||
}
|
||||
|
||||
static void destroy_curl_context(curl_context_t *context)
|
||||
{
|
||||
uv_close((uv_handle_t *) &context->poll_handle, curl_close_cb);
|
||||
}
|
||||
|
||||
static void add_download(const char *url, int num)
|
||||
{
|
||||
char filename[50];
|
||||
FILE *file;
|
||||
CURL *handle;
|
||||
|
||||
snprintf(filename, 50, "%d.download", num);
|
||||
|
||||
file = fopen(filename, "wb");
|
||||
if(!file) {
|
||||
fprintf(stderr, "Error opening %s\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
handle = curl_easy_init();
|
||||
curl_easy_setopt(handle, CURLOPT_WRITEDATA, file);
|
||||
curl_easy_setopt(handle, CURLOPT_PRIVATE, file);
|
||||
curl_easy_setopt(handle, CURLOPT_URL, url);
|
||||
curl_multi_add_handle(curl_handle, handle);
|
||||
fprintf(stderr, "Added download %s -> %s\n", url, filename);
|
||||
}
|
||||
|
||||
static void check_multi_info(void)
|
||||
{
|
||||
char *done_url;
|
||||
CURLMsg *message;
|
||||
int pending;
|
||||
CURL *easy_handle;
|
||||
FILE *file;
|
||||
|
||||
while((message = curl_multi_info_read(curl_handle, &pending))) {
|
||||
switch(message->msg) {
|
||||
case CURLMSG_DONE:
|
||||
/* Do not use message data after calling curl_multi_remove_handle() and
|
||||
curl_easy_cleanup(). As per curl_multi_info_read() docs:
|
||||
"WARNING: The data the returned pointer points to will not survive
|
||||
calling curl_multi_cleanup, curl_multi_remove_handle or
|
||||
curl_easy_cleanup." */
|
||||
easy_handle = message->easy_handle;
|
||||
|
||||
curl_easy_getinfo(easy_handle, CURLINFO_EFFECTIVE_URL, &done_url);
|
||||
curl_easy_getinfo(easy_handle, CURLINFO_PRIVATE, &file);
|
||||
printf("%s DONE\n", done_url);
|
||||
|
||||
curl_multi_remove_handle(curl_handle, easy_handle);
|
||||
curl_easy_cleanup(easy_handle);
|
||||
if(file) {
|
||||
fclose(file);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(stderr, "CURLMSG default\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void curl_perform(uv_poll_t *req, int status, int events)
|
||||
{
|
||||
int running_handles;
|
||||
int flags = 0;
|
||||
curl_context_t *context;
|
||||
|
||||
if(events & UV_READABLE)
|
||||
flags |= CURL_CSELECT_IN;
|
||||
if(events & UV_WRITABLE)
|
||||
flags |= CURL_CSELECT_OUT;
|
||||
|
||||
context = (curl_context_t *) req->data;
|
||||
|
||||
curl_multi_socket_action(curl_handle, context->sockfd, flags,
|
||||
&running_handles);
|
||||
|
||||
check_multi_info();
|
||||
}
|
||||
|
||||
static void on_timeout(uv_timer_t *req)
|
||||
{
|
||||
int running_handles;
|
||||
curl_multi_socket_action(curl_handle, CURL_SOCKET_TIMEOUT, 0,
|
||||
&running_handles);
|
||||
check_multi_info();
|
||||
}
|
||||
|
||||
static int start_timeout(CURLM *multi, long timeout_ms, void *userp)
|
||||
{
|
||||
if(timeout_ms < 0) {
|
||||
uv_timer_stop(&timeout);
|
||||
}
|
||||
else {
|
||||
if(timeout_ms == 0)
|
||||
timeout_ms = 1; /* 0 means directly call socket_action, but we will do it
|
||||
in a bit */
|
||||
uv_timer_start(&timeout, on_timeout, timeout_ms, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handle_socket(CURL *easy, curl_socket_t s, int action, void *userp,
|
||||
void *socketp)
|
||||
{
|
||||
curl_context_t *curl_context;
|
||||
int events = 0;
|
||||
|
||||
switch(action) {
|
||||
case CURL_POLL_IN:
|
||||
case CURL_POLL_OUT:
|
||||
case CURL_POLL_INOUT:
|
||||
curl_context = socketp ?
|
||||
(curl_context_t *) socketp : create_curl_context(s);
|
||||
|
||||
curl_multi_assign(curl_handle, s, (void *) curl_context);
|
||||
|
||||
if(action != CURL_POLL_IN)
|
||||
events |= UV_WRITABLE;
|
||||
if(action != CURL_POLL_OUT)
|
||||
events |= UV_READABLE;
|
||||
|
||||
uv_poll_start(&curl_context->poll_handle, events, curl_perform);
|
||||
break;
|
||||
case CURL_POLL_REMOVE:
|
||||
if(socketp) {
|
||||
uv_poll_stop(&((curl_context_t*)socketp)->poll_handle);
|
||||
destroy_curl_context((curl_context_t*) socketp);
|
||||
curl_multi_assign(curl_handle, s, NULL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
loop = uv_default_loop();
|
||||
|
||||
if(argc <= 1)
|
||||
return 0;
|
||||
|
||||
if(curl_global_init(CURL_GLOBAL_ALL)) {
|
||||
fprintf(stderr, "Could not init curl\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
uv_timer_init(loop, &timeout);
|
||||
|
||||
curl_handle = curl_multi_init();
|
||||
curl_multi_setopt(curl_handle, CURLMOPT_SOCKETFUNCTION, handle_socket);
|
||||
curl_multi_setopt(curl_handle, CURLMOPT_TIMERFUNCTION, start_timeout);
|
||||
|
||||
while(argc-- > 1) {
|
||||
add_download(argv[argc], argc);
|
||||
}
|
||||
|
||||
uv_run(loop, UV_RUN_DEFAULT);
|
||||
curl_multi_cleanup(curl_handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
96
Engine/lib/curl/docs/examples/multithread.c
Normal file
96
Engine/lib/curl/docs/examples/multithread.c
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* A multi-threaded example that uses pthreads to fetch several files at once
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#define NUMT 4
|
||||
|
||||
/*
|
||||
List of URLs to fetch.
|
||||
|
||||
If you intend to use a SSL-based protocol here you might need to setup TLS
|
||||
library mutex callbacks as described here:
|
||||
|
||||
https://curl.se/libcurl/c/threadsafe.html
|
||||
|
||||
*/
|
||||
const char * const urls[NUMT]= {
|
||||
"https://curl.se/",
|
||||
"ftp://example.com/",
|
||||
"https://example.net/",
|
||||
"www.example"
|
||||
};
|
||||
|
||||
static void *pull_one_url(void *url)
|
||||
{
|
||||
CURL *curl;
|
||||
|
||||
curl = curl_easy_init();
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_easy_perform(curl); /* ignores error */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
int pthread_create(pthread_t *new_thread_ID,
|
||||
const pthread_attr_t *attr,
|
||||
void * (*start_func)(void *), void *arg);
|
||||
*/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
pthread_t tid[NUMT];
|
||||
int i;
|
||||
|
||||
/* Must initialize libcurl before any threads are started */
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
for(i = 0; i< NUMT; i++) {
|
||||
int error = pthread_create(&tid[i],
|
||||
NULL, /* default attributes please */
|
||||
pull_one_url,
|
||||
(void *)urls[i]);
|
||||
if(0 != error)
|
||||
fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
|
||||
else
|
||||
fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]);
|
||||
}
|
||||
|
||||
/* now wait for all threads to terminate */
|
||||
for(i = 0; i< NUMT; i++) {
|
||||
pthread_join(tid[i], NULL);
|
||||
fprintf(stderr, "Thread %d terminated\n", i);
|
||||
}
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
||||
97
Engine/lib/curl/docs/examples/opensslthreadlock.c
Normal file
97
Engine/lib/curl/docs/examples/opensslthreadlock.c
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* one way to set the necessary OpenSSL locking callbacks if you want to do
|
||||
* multi-threaded transfers with HTTPS/FTPS with libcurl built to use OpenSSL.
|
||||
* </DESC>
|
||||
*/
|
||||
/*
|
||||
* This is not a complete stand-alone example.
|
||||
*
|
||||
* Author: Jeremy Brown
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <openssl/err.h>
|
||||
|
||||
#define MUTEX_TYPE pthread_mutex_t
|
||||
#define MUTEX_SETUP(x) pthread_mutex_init(&(x), NULL)
|
||||
#define MUTEX_CLEANUP(x) pthread_mutex_destroy(&(x))
|
||||
#define MUTEX_LOCK(x) pthread_mutex_lock(&(x))
|
||||
#define MUTEX_UNLOCK(x) pthread_mutex_unlock(&(x))
|
||||
#define THREAD_ID pthread_self()
|
||||
|
||||
|
||||
void handle_error(const char *file, int lineno, const char *msg)
|
||||
{
|
||||
fprintf(stderr, "** %s:%d %s\n", file, lineno, msg);
|
||||
ERR_print_errors_fp(stderr);
|
||||
/* exit(-1); */
|
||||
}
|
||||
|
||||
/* This array will store all of the mutexes available to OpenSSL. */
|
||||
static MUTEX_TYPE *mutex_buf = NULL;
|
||||
|
||||
static void locking_function(int mode, int n, const char *file, int line)
|
||||
{
|
||||
if(mode & CRYPTO_LOCK)
|
||||
MUTEX_LOCK(mutex_buf[n]);
|
||||
else
|
||||
MUTEX_UNLOCK(mutex_buf[n]);
|
||||
}
|
||||
|
||||
static unsigned long id_function(void)
|
||||
{
|
||||
return ((unsigned long)THREAD_ID);
|
||||
}
|
||||
|
||||
int thread_setup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
mutex_buf = malloc(CRYPTO_num_locks() * sizeof(MUTEX_TYPE));
|
||||
if(!mutex_buf)
|
||||
return 0;
|
||||
for(i = 0; i < CRYPTO_num_locks(); i++)
|
||||
MUTEX_SETUP(mutex_buf[i]);
|
||||
CRYPTO_set_id_callback(id_function);
|
||||
CRYPTO_set_locking_callback(locking_function);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int thread_cleanup(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if(!mutex_buf)
|
||||
return 0;
|
||||
CRYPTO_set_id_callback(NULL);
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
for(i = 0; i < CRYPTO_num_locks(); i++)
|
||||
MUTEX_CLEANUP(mutex_buf[i]);
|
||||
free(mutex_buf);
|
||||
mutex_buf = NULL;
|
||||
return 1;
|
||||
}
|
||||
80
Engine/lib/curl/docs/examples/parseurl.c
Normal file
80
Engine/lib/curl/docs/examples/parseurl.c
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Basic URL API use.
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#if !CURL_AT_LEAST_VERSION(7, 62, 0)
|
||||
#error "this example requires curl 7.62.0 or later"
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURLU *h;
|
||||
CURLUcode uc;
|
||||
char *host;
|
||||
char *path;
|
||||
|
||||
h = curl_url(); /* get a handle to work with */
|
||||
if(!h)
|
||||
return 1;
|
||||
|
||||
/* parse a full URL */
|
||||
uc = curl_url_set(h, CURLUPART_URL, "http://example.com/path/index.html", 0);
|
||||
if(uc)
|
||||
goto fail;
|
||||
|
||||
/* extract host name from the parsed URL */
|
||||
uc = curl_url_get(h, CURLUPART_HOST, &host, 0);
|
||||
if(!uc) {
|
||||
printf("Host name: %s\n", host);
|
||||
curl_free(host);
|
||||
}
|
||||
|
||||
/* extract the path from the parsed URL */
|
||||
uc = curl_url_get(h, CURLUPART_PATH, &path, 0);
|
||||
if(!uc) {
|
||||
printf("Path: %s\n", path);
|
||||
curl_free(path);
|
||||
}
|
||||
|
||||
/* redirect with a relative URL */
|
||||
uc = curl_url_set(h, CURLUPART_URL, "../another/second.html", 0);
|
||||
if(uc)
|
||||
goto fail;
|
||||
|
||||
/* extract the new, updated path */
|
||||
uc = curl_url_get(h, CURLUPART_PATH, &path, 0);
|
||||
if(!uc) {
|
||||
printf("Path: %s\n", path);
|
||||
curl_free(path);
|
||||
}
|
||||
|
||||
fail:
|
||||
curl_url_cleanup(h); /* free url handle */
|
||||
return 0;
|
||||
}
|
||||
70
Engine/lib/curl/docs/examples/persistent.c
Normal file
70
Engine/lib/curl/docs/examples/persistent.c
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* re-using handles to do HTTP persistent connections
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_HEADER, 1L);
|
||||
|
||||
/* get the first document */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* get another document from the same server using the same
|
||||
connection */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/docs/");
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
72
Engine/lib/curl/docs/examples/pop3-authzid.c
Normal file
72
Engine/lib/curl/docs/examples/pop3-authzid.c
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example showing how to retrieve emails from a shared mailbox
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to retrieve mail using libcurl's POP3
|
||||
* capabilities.
|
||||
*
|
||||
* Note that this example requires libcurl 7.66.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set the username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* Set the authorization identity (identity to act as) */
|
||||
curl_easy_setopt(curl, CURLOPT_SASL_AUTHZID, "shared-mailbox");
|
||||
|
||||
/* Force PLAIN authentication */
|
||||
curl_easy_setopt(curl, CURLOPT_LOGIN_OPTIONS, "AUTH=PLAIN");
|
||||
|
||||
/* This will retrieve message 1 from the user's mailbox */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "pop3://pop.example.com/1");
|
||||
|
||||
/* Perform the retr */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
72
Engine/lib/curl/docs/examples/pop3-dele.c
Normal file
72
Engine/lib/curl/docs/examples/pop3-dele.c
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example showing how to delete emails
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to delete an existing mail using
|
||||
* libcurl's POP3 capabilities.
|
||||
*
|
||||
* Note that this example requires libcurl 7.26.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* You can specify the message either in the URL or DELE command */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "pop3://pop.example.com/1");
|
||||
|
||||
/* Set the DELE command */
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "DELE");
|
||||
|
||||
/* Do not perform a transfer as DELE returns no data */
|
||||
curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
|
||||
|
||||
/* Perform the custom request */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
66
Engine/lib/curl/docs/examples/pop3-list.c
Normal file
66
Engine/lib/curl/docs/examples/pop3-list.c
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example to list the contents of a mailbox
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example using libcurl's POP3 capabilities to list the
|
||||
* contents of a mailbox.
|
||||
*
|
||||
* Note that this example requires libcurl 7.20.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This will list every message of the given mailbox */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "pop3://pop.example.com");
|
||||
|
||||
/* Perform the list */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
84
Engine/lib/curl/docs/examples/pop3-multi.c
Normal file
84
Engine/lib/curl/docs/examples/pop3-multi.c
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example using the multi interface
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to retrieve mail using libcurl's POP3
|
||||
* capabilities. It builds on the pop3-retr.c example to demonstrate how to use
|
||||
* libcurl's multi interface.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLM *mcurl;
|
||||
int still_running = 1;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(!curl)
|
||||
return 1;
|
||||
|
||||
mcurl = curl_multi_init();
|
||||
if(!mcurl)
|
||||
return 2;
|
||||
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This will retrieve message 1 from the user's mailbox */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "pop3://pop.example.com/1");
|
||||
|
||||
/* Tell the multi stack about our easy handle */
|
||||
curl_multi_add_handle(mcurl, curl);
|
||||
|
||||
do {
|
||||
CURLMcode mc = curl_multi_perform(mcurl, &still_running);
|
||||
|
||||
if(still_running)
|
||||
/* wait for activity, timeout or "nothing" */
|
||||
mc = curl_multi_poll(mcurl, NULL, 0, 1000, NULL);
|
||||
|
||||
if(mc)
|
||||
break;
|
||||
|
||||
} while(still_running);
|
||||
|
||||
/* Always cleanup */
|
||||
curl_multi_remove_handle(mcurl, curl);
|
||||
curl_multi_cleanup(mcurl);
|
||||
curl_easy_cleanup(curl);
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
72
Engine/lib/curl/docs/examples/pop3-noop.c
Normal file
72
Engine/lib/curl/docs/examples/pop3-noop.c
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example showing how to perform a noop
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to perform a noop using libcurl's POP3
|
||||
* capabilities.
|
||||
*
|
||||
* Note that this example requires libcurl 7.26.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This is just the server URL */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "pop3://pop.example.com");
|
||||
|
||||
/* Set the NOOP command */
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "NOOP");
|
||||
|
||||
/* Do not perform a transfer as NOOP returns no data */
|
||||
curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
|
||||
|
||||
/* Perform the custom request */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
66
Engine/lib/curl/docs/examples/pop3-retr.c
Normal file
66
Engine/lib/curl/docs/examples/pop3-retr.c
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example showing how to retrieve emails
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to retrieve mail using libcurl's POP3
|
||||
* capabilities.
|
||||
*
|
||||
* Note that this example requires libcurl 7.20.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This will retrieve message 1 from the user's mailbox */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "pop3://pop.example.com/1");
|
||||
|
||||
/* Perform the retr */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
93
Engine/lib/curl/docs/examples/pop3-ssl.c
Normal file
93
Engine/lib/curl/docs/examples/pop3-ssl.c
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example using SSL
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to retrieve mail using libcurl's POP3
|
||||
* capabilities. It builds on the pop3-retr.c example adding transport
|
||||
* security to protect the authentication details from being snooped.
|
||||
*
|
||||
* Note that this example requires libcurl 7.20.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This will retrieve message 1 from the user's mailbox. Note the use of
|
||||
* pop3s:// rather than pop3:// to request a SSL based connection. */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "pop3s://pop.example.com/1");
|
||||
|
||||
/* If you want to connect to a site who is not using a certificate that is
|
||||
* signed by one of the certs in the CA bundle you have, you can skip the
|
||||
* verification of the server's certificate. This makes the connection
|
||||
* A LOT LESS SECURE.
|
||||
*
|
||||
* If you have a CA cert for the server stored someplace else than in the
|
||||
* default bundle, then the CURLOPT_CAPATH option might come handy for
|
||||
* you. */
|
||||
#ifdef SKIP_PEER_VERIFICATION
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
#endif
|
||||
|
||||
/* If the site you are connecting to uses a different host name that what
|
||||
* they have mentioned in their server certificate's commonName (or
|
||||
* subjectAltName) fields, libcurl will refuse to connect. You can skip
|
||||
* this check, but this will make the connection less secure. */
|
||||
#ifdef SKIP_HOSTNAME_VERIFICATION
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
#endif
|
||||
|
||||
/* Since the traffic will be encrypted, it is very useful to turn on debug
|
||||
* information within libcurl to see what is happening during the
|
||||
* transfer */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* Perform the retr */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
72
Engine/lib/curl/docs/examples/pop3-stat.c
Normal file
72
Engine/lib/curl/docs/examples/pop3-stat.c
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example showing how to obtain message statistics
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to obtain message statistics using
|
||||
* libcurl's POP3 capabilities.
|
||||
*
|
||||
* Note that this example requires libcurl 7.26.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This is just the server URL */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "pop3://pop.example.com");
|
||||
|
||||
/* Set the STAT command */
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "STAT");
|
||||
|
||||
/* Do not perform a transfer as the data is in the response */
|
||||
curl_easy_setopt(curl, CURLOPT_NOBODY, 1L);
|
||||
|
||||
/* Perform the custom request */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
93
Engine/lib/curl/docs/examples/pop3-tls.c
Normal file
93
Engine/lib/curl/docs/examples/pop3-tls.c
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example using TLS
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to retrieve mail using libcurl's POP3
|
||||
* capabilities. It builds on the pop3-retr.c example adding transport
|
||||
* security to protect the authentication details from being snooped.
|
||||
*
|
||||
* Note that this example requires libcurl 7.20.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This will retrieve message 1 from the user's mailbox */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "pop3://pop.example.com/1");
|
||||
|
||||
/* In this example, we will start with a plain text connection, and upgrade
|
||||
* to Transport Layer Security (TLS) using the STLS command. Be careful of
|
||||
* using CURLUSESSL_TRY here, because if TLS upgrade fails, the transfer
|
||||
* will continue anyway - see the security discussion in the libcurl
|
||||
* tutorial for more details. */
|
||||
curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
|
||||
|
||||
/* If your server does not have a valid certificate, then you can disable
|
||||
* part of the Transport Layer Security protection by setting the
|
||||
* CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST options to 0 (false).
|
||||
* curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
* curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
*
|
||||
* That is, in general, a bad idea. It is still better than sending your
|
||||
* authentication details in plain text though. Instead, you should get
|
||||
* the issuer certificate (or the host certificate if the certificate is
|
||||
* self-signed) and add it to the set of certificates that are known to
|
||||
* libcurl using CURLOPT_CAINFO and/or CURLOPT_CAPATH. See docs/SSLCERTS
|
||||
* for more information. */
|
||||
curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/certificate.pem");
|
||||
|
||||
/* Since the traffic will be encrypted, it is very useful to turn on debug
|
||||
* information within libcurl to see what is happening during the
|
||||
* transfer */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/* Perform the retr */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
69
Engine/lib/curl/docs/examples/pop3-top.c
Normal file
69
Engine/lib/curl/docs/examples/pop3-top.c
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example showing how to retrieve only the headers of an email
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example showing how to retrieve only the headers of a mail
|
||||
* using libcurl's POP3 capabilities.
|
||||
*
|
||||
* Note that this example requires libcurl 7.26.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This is just the server URL */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "pop3://pop.example.com");
|
||||
|
||||
/* Set the TOP command for message 1 to only include the headers */
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "TOP 1 0");
|
||||
|
||||
/* Perform the custom request */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
69
Engine/lib/curl/docs/examples/pop3-uidl.c
Normal file
69
Engine/lib/curl/docs/examples/pop3-uidl.c
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
/* <DESC>
|
||||
* POP3 example to list the contents of a mailbox by unique ID
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* This is a simple example using libcurl's POP3 capabilities to list the
|
||||
* contents of a mailbox by unique ID.
|
||||
*
|
||||
* Note that this example requires libcurl 7.26.0 or above.
|
||||
*/
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Set username and password */
|
||||
curl_easy_setopt(curl, CURLOPT_USERNAME, "user");
|
||||
curl_easy_setopt(curl, CURLOPT_PASSWORD, "secret");
|
||||
|
||||
/* This is just the server URL */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "pop3://pop.example.com");
|
||||
|
||||
/* Set the UIDL command */
|
||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "UIDL");
|
||||
|
||||
/* Perform the custom request */
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* Always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
156
Engine/lib/curl/docs/examples/post-callback.c
Normal file
156
Engine/lib/curl/docs/examples/post-callback.c
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Issue an HTTP POST and provide the data through the read callback.
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* silly test data to POST */
|
||||
static const char data[]="Lorem ipsum dolor sit amet, consectetur adipiscing "
|
||||
"elit. Sed vel urna neque. Ut quis leo metus. Quisque eleifend, ex at "
|
||||
"laoreet rhoncus, odio ipsum semper metus, at tempus ante urna in mauris. "
|
||||
"Suspendisse ornare tempor venenatis. Ut dui neque, pellentesque a varius "
|
||||
"eget, mattis vitae ligula. Fusce ut pharetra est. Ut ullamcorper mi ac "
|
||||
"sollicitudin semper. Praesent sit amet tellus varius, posuere nulla non, "
|
||||
"rhoncus ipsum.";
|
||||
|
||||
struct WriteThis {
|
||||
const char *readptr;
|
||||
size_t sizeleft;
|
||||
};
|
||||
|
||||
static size_t read_callback(char *dest, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
struct WriteThis *wt = (struct WriteThis *)userp;
|
||||
size_t buffer_size = size*nmemb;
|
||||
|
||||
if(wt->sizeleft) {
|
||||
/* copy as much as possible from the source to the destination */
|
||||
size_t copy_this_much = wt->sizeleft;
|
||||
if(copy_this_much > buffer_size)
|
||||
copy_this_much = buffer_size;
|
||||
memcpy(dest, wt->readptr, copy_this_much);
|
||||
|
||||
wt->readptr += copy_this_much;
|
||||
wt->sizeleft -= copy_this_much;
|
||||
return copy_this_much; /* we copied this many bytes */
|
||||
}
|
||||
|
||||
return 0; /* no more data left to deliver */
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
struct WriteThis wt;
|
||||
|
||||
wt.readptr = data;
|
||||
wt.sizeleft = strlen(data);
|
||||
|
||||
/* In windows, this will init the winsock stuff */
|
||||
res = curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK) {
|
||||
fprintf(stderr, "curl_global_init() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* get a curl handle */
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* First set the URL that is about to receive our POST. */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/index.cgi");
|
||||
|
||||
/* 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_READDATA, &wt);
|
||||
|
||||
/* get verbose debug output please */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
/*
|
||||
If you use POST to a HTTP 1.1 server, you can send data without knowing
|
||||
the size before starting the POST if you use chunked encoding. You
|
||||
enable this by adding a header like "Transfer-Encoding: chunked" with
|
||||
CURLOPT_HTTPHEADER. With HTTP 1.0 or without chunked transfer, you must
|
||||
specify the size in the request.
|
||||
*/
|
||||
#ifdef USE_CHUNKED
|
||||
{
|
||||
struct curl_slist *chunk = NULL;
|
||||
|
||||
chunk = curl_slist_append(chunk, "Transfer-Encoding: chunked");
|
||||
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||
/* use curl_slist_free_all() after the *perform() call to free this
|
||||
list again */
|
||||
}
|
||||
#else
|
||||
/* Set the expected POST size. If you want to POST large amounts of data,
|
||||
consider CURLOPT_POSTFIELDSIZE_LARGE */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)wt.sizeleft);
|
||||
#endif
|
||||
|
||||
#ifdef DISABLE_EXPECT
|
||||
/*
|
||||
Using POST with HTTP 1.1 implies the use of a "Expect: 100-continue"
|
||||
header. You can disable this header with CURLOPT_HTTPHEADER as usual.
|
||||
NOTE: if you want chunked transfer too, you need to combine these two
|
||||
since you can only set one list of headers with CURLOPT_HTTPHEADER. */
|
||||
|
||||
/* A less good option would be to enforce HTTP 1.0, but that might also
|
||||
have other implications. */
|
||||
{
|
||||
struct curl_slist *chunk = NULL;
|
||||
|
||||
chunk = curl_slist_append(chunk, "Expect:");
|
||||
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
|
||||
/* use curl_slist_free_all() after the *perform() call to free this
|
||||
list again */
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
||||
114
Engine/lib/curl/docs/examples/postinmemory.c
Normal file
114
Engine/lib/curl/docs/examples/postinmemory.c
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Make a HTTP POST with data from memory and receive response in memory.
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
struct MemoryStruct {
|
||||
char *memory;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
static size_t
|
||||
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
size_t realsize = size * nmemb;
|
||||
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
|
||||
|
||||
char *ptr = realloc(mem->memory, mem->size + realsize + 1);
|
||||
if(!ptr) {
|
||||
/* out of memory! */
|
||||
printf("not enough memory (realloc returned NULL)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mem->memory = ptr;
|
||||
memcpy(&(mem->memory[mem->size]), contents, realsize);
|
||||
mem->size += realsize;
|
||||
mem->memory[mem->size] = 0;
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct MemoryStruct chunk;
|
||||
static const char *postthis = "Field=1&Field=2&Field=3";
|
||||
|
||||
chunk.memory = malloc(1); /* will be grown as needed by realloc above */
|
||||
chunk.size = 0; /* no data at this point */
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.org/");
|
||||
|
||||
/* send all data to this function */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
|
||||
|
||||
/* we pass our 'chunk' struct to the callback function */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
|
||||
|
||||
/* some servers do not like requests that are made without a user-agent
|
||||
field, so we provide one */
|
||||
curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postthis);
|
||||
|
||||
/* if we do not provide POSTFIELDSIZE, libcurl will strlen() by
|
||||
itself */
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (long)strlen(postthis));
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK) {
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* Now, our chunk.memory points to a memory block that is chunk.size
|
||||
* bytes big and contains the remote file.
|
||||
*
|
||||
* Do something nice with it!
|
||||
*/
|
||||
printf("%s\n",chunk.memory);
|
||||
}
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
free(chunk.memory);
|
||||
curl_global_cleanup();
|
||||
return 0;
|
||||
}
|
||||
108
Engine/lib/curl/docs/examples/postit2-formadd.c
Normal file
108
Engine/lib/curl/docs/examples/postit2-formadd.c
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* HTTP Multipart formpost with file upload and two additional parts.
|
||||
* </DESC>
|
||||
*/
|
||||
/* Example code that uploads a file name 'foo' to a remote script that accepts
|
||||
* "HTML form based" (as described in RFC1738) uploads using HTTP POST.
|
||||
*
|
||||
* The imaginary form we will fill in looks like:
|
||||
*
|
||||
* <form method="post" enctype="multipart/form-data" action="examplepost.cgi">
|
||||
* Enter file: <input type="file" name="sendfile" size="40">
|
||||
* Enter file name: <input type="text" name="filename" size="30">
|
||||
* <input type="submit" value="send" name="submit">
|
||||
* </form>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
struct curl_httppost *formpost = NULL;
|
||||
struct curl_httppost *lastptr = NULL;
|
||||
struct curl_slist *headerlist = NULL;
|
||||
static const char buf[] = "Expect:";
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* Fill in the file upload field */
|
||||
curl_formadd(&formpost,
|
||||
&lastptr,
|
||||
CURLFORM_COPYNAME, "sendfile",
|
||||
CURLFORM_FILE, "postit2.c",
|
||||
CURLFORM_END);
|
||||
|
||||
/* Fill in the filename field */
|
||||
curl_formadd(&formpost,
|
||||
&lastptr,
|
||||
CURLFORM_COPYNAME, "filename",
|
||||
CURLFORM_COPYCONTENTS, "postit2.c",
|
||||
CURLFORM_END);
|
||||
|
||||
|
||||
/* Fill in the submit field too, even if this is rarely needed */
|
||||
curl_formadd(&formpost,
|
||||
&lastptr,
|
||||
CURLFORM_COPYNAME, "submit",
|
||||
CURLFORM_COPYCONTENTS, "send",
|
||||
CURLFORM_END);
|
||||
|
||||
curl = curl_easy_init();
|
||||
/* initialize custom header list (stating that Expect: 100-continue is not
|
||||
wanted */
|
||||
headerlist = curl_slist_append(headerlist, buf);
|
||||
if(curl) {
|
||||
/* what URL that receives this POST */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/examplepost.cgi");
|
||||
if((argc == 2) && (!strcmp(argv[1], "noexpectheader")))
|
||||
/* only disable 100-continue header if explicitly requested */
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
/* then cleanup the formpost chain */
|
||||
curl_formfree(formpost);
|
||||
/* free slist */
|
||||
curl_slist_free_all(headerlist);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
104
Engine/lib/curl/docs/examples/postit2.c
Normal file
104
Engine/lib/curl/docs/examples/postit2.c
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* HTTP Multipart formpost with file upload and two additional parts.
|
||||
* </DESC>
|
||||
*/
|
||||
/* Example code that uploads a file name 'foo' to a remote script that accepts
|
||||
* "HTML form based" (as described in RFC1738) uploads using HTTP POST.
|
||||
*
|
||||
* The imaginary form we will fill in looks like:
|
||||
*
|
||||
* <form method="post" enctype="multipart/form-data" action="examplepost.cgi">
|
||||
* Enter file: <input type="file" name="sendfile" size="40">
|
||||
* Enter file name: <input type="text" name="filename" size="30">
|
||||
* <input type="submit" value="send" name="submit">
|
||||
* </form>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
|
||||
curl_mime *form = NULL;
|
||||
curl_mimepart *field = NULL;
|
||||
struct curl_slist *headerlist = NULL;
|
||||
static const char buf[] = "Expect:";
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/* Create the form */
|
||||
form = curl_mime_init(curl);
|
||||
|
||||
/* Fill in the file upload field */
|
||||
field = curl_mime_addpart(form);
|
||||
curl_mime_name(field, "sendfile");
|
||||
curl_mime_filedata(field, "postit2.c");
|
||||
|
||||
/* Fill in the filename field */
|
||||
field = curl_mime_addpart(form);
|
||||
curl_mime_name(field, "filename");
|
||||
curl_mime_data(field, "postit2.c", CURL_ZERO_TERMINATED);
|
||||
|
||||
/* Fill in the submit field too, even if this is rarely needed */
|
||||
field = curl_mime_addpart(form);
|
||||
curl_mime_name(field, "submit");
|
||||
curl_mime_data(field, "send", CURL_ZERO_TERMINATED);
|
||||
|
||||
/* initialize custom header list (stating that Expect: 100-continue is not
|
||||
wanted */
|
||||
headerlist = curl_slist_append(headerlist, buf);
|
||||
/* what URL that receives this POST */
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/examplepost.cgi");
|
||||
if((argc == 2) && (!strcmp(argv[1], "noexpectheader")))
|
||||
/* only disable 100-continue header if explicitly requested */
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
|
||||
curl_easy_setopt(curl, CURLOPT_MIMEPOST, form);
|
||||
|
||||
/* Perform the request, res will get the return code */
|
||||
res = curl_easy_perform(curl);
|
||||
/* Check for errors */
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "curl_easy_perform() failed: %s\n",
|
||||
curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
/* then cleanup the form */
|
||||
curl_mime_free(form);
|
||||
/* free slist */
|
||||
curl_slist_free_all(headerlist);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
97
Engine/lib/curl/docs/examples/progressfunc.c
Normal file
97
Engine/lib/curl/docs/examples/progressfunc.c
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Use the progress callbacks, old and/or new one depending on available
|
||||
* libcurl version.
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
#define MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL 3000000
|
||||
#define STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES 6000
|
||||
|
||||
struct myprogress {
|
||||
curl_off_t lastruntime; /* type depends on version, see above */
|
||||
CURL *curl;
|
||||
};
|
||||
|
||||
/* this is how the CURLOPT_XFERINFOFUNCTION callback works */
|
||||
static int xferinfo(void *p,
|
||||
curl_off_t dltotal, curl_off_t dlnow,
|
||||
curl_off_t ultotal, curl_off_t ulnow)
|
||||
{
|
||||
struct myprogress *myp = (struct myprogress *)p;
|
||||
CURL *curl = myp->curl;
|
||||
curl_off_t curtime = 0;
|
||||
|
||||
curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME_T, &curtime);
|
||||
|
||||
/* under certain circumstances it may be desirable for certain functionality
|
||||
to only run every N seconds, in order to do this the transaction time can
|
||||
be used */
|
||||
if((curtime - myp->lastruntime) >= MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL) {
|
||||
myp->lastruntime = curtime;
|
||||
fprintf(stderr, "TOTAL TIME: %lu.%06lu\r\n",
|
||||
(unsigned long)(curtime / 1000000),
|
||||
(unsigned long)(curtime % 1000000));
|
||||
}
|
||||
|
||||
fprintf(stderr, "UP: %lu of %lu DOWN: %lu of %lu\r\n",
|
||||
(unsigned long)ulnow, (unsigned long)ultotal,
|
||||
(unsigned long)dlnow, (unsigned long)dltotal);
|
||||
|
||||
if(dlnow > STOP_DOWNLOAD_AFTER_THIS_MANY_BYTES)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
struct myprogress prog;
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
prog.lastruntime = 0;
|
||||
prog.curl = curl;
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, xferinfo);
|
||||
/* pass the struct pointer into the xferinfo function */
|
||||
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &prog);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
if(res != CURLE_OK)
|
||||
fprintf(stderr, "%s\n", curl_easy_strerror(res));
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return (int)res;
|
||||
}
|
||||
58
Engine/lib/curl/docs/examples/resolve.c
Normal file
58
Engine/lib/curl/docs/examples/resolve.c
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Use CURLOPT_RESOLVE to feed custom IP addresses for given host name + port
|
||||
* number combinations.
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res = CURLE_OK;
|
||||
|
||||
/* Each single name resolve string should be written using the format
|
||||
HOST:PORT:ADDRESS where HOST is the name libcurl will try to resolve,
|
||||
PORT is the port number of the service where libcurl wants to connect to
|
||||
the HOST and ADDRESS is the numerical IP address
|
||||
*/
|
||||
struct curl_slist *host = curl_slist_append(NULL,
|
||||
"example.com:443:127.0.0.1");
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_RESOLVE, host);
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
curl_slist_free_all(host);
|
||||
|
||||
return (int)res;
|
||||
}
|
||||
162
Engine/lib/curl/docs/examples/sendrecv.c
Normal file
162
Engine/lib/curl/docs/examples/sendrecv.c
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* An example of curl_easy_send() and curl_easy_recv() usage.
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* Auxiliary function that waits on the socket. */
|
||||
static int wait_on_socket(curl_socket_t sockfd, int for_recv, long timeout_ms)
|
||||
{
|
||||
struct timeval tv;
|
||||
fd_set infd, outfd, errfd;
|
||||
int res;
|
||||
|
||||
tv.tv_sec = timeout_ms / 1000;
|
||||
tv.tv_usec = (timeout_ms % 1000) * 1000;
|
||||
|
||||
FD_ZERO(&infd);
|
||||
FD_ZERO(&outfd);
|
||||
FD_ZERO(&errfd);
|
||||
|
||||
FD_SET(sockfd, &errfd); /* always check for error */
|
||||
|
||||
if(for_recv) {
|
||||
FD_SET(sockfd, &infd);
|
||||
}
|
||||
else {
|
||||
FD_SET(sockfd, &outfd);
|
||||
}
|
||||
|
||||
/* select() returns the number of signalled sockets or -1 */
|
||||
res = select((int)sockfd + 1, &infd, &outfd, &errfd, &tv);
|
||||
return res;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
/* Minimalistic http request */
|
||||
const char *request = "GET / HTTP/1.0\r\nHost: example.com\r\n\r\n";
|
||||
size_t request_len = strlen(request);
|
||||
|
||||
/* A general note of caution here: if you are using curl_easy_recv() or
|
||||
curl_easy_send() to implement HTTP or _any_ other protocol libcurl
|
||||
supports "natively", you are doing it wrong and you should stop.
|
||||
|
||||
This example uses HTTP only to show how to use this API, it does not
|
||||
suggest that writing an application doing this is sensible.
|
||||
*/
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
CURLcode res;
|
||||
curl_socket_t sockfd;
|
||||
size_t nsent_total = 0;
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://example.com");
|
||||
/* Do not do the transfer - only connect to host */
|
||||
curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1L);
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
if(res != CURLE_OK) {
|
||||
printf("Error: %s\n", curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Extract the socket from the curl handle - we will need it for
|
||||
waiting. */
|
||||
res = curl_easy_getinfo(curl, CURLINFO_ACTIVESOCKET, &sockfd);
|
||||
|
||||
if(res != CURLE_OK) {
|
||||
printf("Error: %s\n", curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Sending request.\n");
|
||||
|
||||
do {
|
||||
/* Warning: This example program may loop indefinitely.
|
||||
* A production-quality program must define a timeout and exit this loop
|
||||
* as soon as the timeout has expired. */
|
||||
size_t nsent;
|
||||
do {
|
||||
nsent = 0;
|
||||
res = curl_easy_send(curl, request + nsent_total,
|
||||
request_len - nsent_total, &nsent);
|
||||
nsent_total += nsent;
|
||||
|
||||
if(res == CURLE_AGAIN && !wait_on_socket(sockfd, 0, 60000L)) {
|
||||
printf("Error: timeout.\n");
|
||||
return 1;
|
||||
}
|
||||
} while(res == CURLE_AGAIN);
|
||||
|
||||
if(res != CURLE_OK) {
|
||||
printf("Error: %s\n", curl_easy_strerror(res));
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Sent %lu bytes.\n", (unsigned long)nsent);
|
||||
|
||||
} while(nsent_total < request_len);
|
||||
|
||||
printf("Reading response.\n");
|
||||
|
||||
for(;;) {
|
||||
/* Warning: This example program may loop indefinitely (see above). */
|
||||
char buf[1024];
|
||||
size_t nread;
|
||||
do {
|
||||
nread = 0;
|
||||
res = curl_easy_recv(curl, buf, sizeof(buf), &nread);
|
||||
|
||||
if(res == CURLE_AGAIN && !wait_on_socket(sockfd, 1, 60000L)) {
|
||||
printf("Error: timeout.\n");
|
||||
return 1;
|
||||
}
|
||||
} while(res == CURLE_AGAIN);
|
||||
|
||||
if(res != CURLE_OK) {
|
||||
printf("Error: %s\n", curl_easy_strerror(res));
|
||||
break;
|
||||
}
|
||||
|
||||
if(nread == 0) {
|
||||
/* end of the response */
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Received %lu bytes.\n", (unsigned long)nread);
|
||||
}
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
96
Engine/lib/curl/docs/examples/sepheaders.c
Normal file
96
Engine/lib/curl/docs/examples/sepheaders.c
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Simple HTTP GET that stores the headers in a separate file
|
||||
* </DESC>
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
size_t written = fwrite(ptr, size, nmemb, (FILE *)stream);
|
||||
return written;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl_handle;
|
||||
static const char *headerfilename = "head.out";
|
||||
FILE *headerfile;
|
||||
static const char *bodyfilename = "body.out";
|
||||
FILE *bodyfile;
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
/* init the curl session */
|
||||
curl_handle = curl_easy_init();
|
||||
|
||||
/* set URL to get */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_URL, "https://example.com");
|
||||
|
||||
/* no progress meter please */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L);
|
||||
|
||||
/* send all data to this function */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
|
||||
|
||||
/* open the header file */
|
||||
headerfile = fopen(headerfilename, "wb");
|
||||
if(!headerfile) {
|
||||
curl_easy_cleanup(curl_handle);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* open the body file */
|
||||
bodyfile = fopen(bodyfilename, "wb");
|
||||
if(!bodyfile) {
|
||||
curl_easy_cleanup(curl_handle);
|
||||
fclose(headerfile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* we want the headers be written to this file handle */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_HEADERDATA, headerfile);
|
||||
|
||||
/* we want the body be written to this file handle instead of stdout */
|
||||
curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, bodyfile);
|
||||
|
||||
/* get it! */
|
||||
curl_easy_perform(curl_handle);
|
||||
|
||||
/* close the header file */
|
||||
fclose(headerfile);
|
||||
|
||||
/* close the body file */
|
||||
fclose(bodyfile);
|
||||
|
||||
/* cleanup curl stuff */
|
||||
curl_easy_cleanup(curl_handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
112
Engine/lib/curl/docs/examples/sessioninfo.c
Normal file
112
Engine/lib/curl/docs/examples/sessioninfo.c
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Uses the CURLINFO_TLS_SESSION data.
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
/* Note that this example currently requires curl to be linked against
|
||||
GnuTLS (and this program must also be linked against -lgnutls). */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
#include <gnutls/gnutls.h>
|
||||
#include <gnutls/x509.h>
|
||||
|
||||
static CURL *curl;
|
||||
|
||||
static size_t wrfu(void *ptr, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
const struct curl_tlssessioninfo *info;
|
||||
unsigned int cert_list_size;
|
||||
const gnutls_datum_t *chainp;
|
||||
CURLcode res;
|
||||
|
||||
(void)stream;
|
||||
(void)ptr;
|
||||
|
||||
res = curl_easy_getinfo(curl, CURLINFO_TLS_SESSION, &info);
|
||||
|
||||
if(!res) {
|
||||
switch(info->backend) {
|
||||
case CURLSSLBACKEND_GNUTLS:
|
||||
/* info->internals is now the gnutls_session_t */
|
||||
chainp = gnutls_certificate_get_peers(info->internals, &cert_list_size);
|
||||
if((chainp) && (cert_list_size)) {
|
||||
unsigned int i;
|
||||
|
||||
for(i = 0; i < cert_list_size; i++) {
|
||||
gnutls_x509_crt_t cert;
|
||||
gnutls_datum_t dn;
|
||||
|
||||
if(GNUTLS_E_SUCCESS == gnutls_x509_crt_init(&cert)) {
|
||||
if(GNUTLS_E_SUCCESS ==
|
||||
gnutls_x509_crt_import(cert, &chainp[i], GNUTLS_X509_FMT_DER)) {
|
||||
if(GNUTLS_E_SUCCESS ==
|
||||
gnutls_x509_crt_print(cert, GNUTLS_CRT_PRINT_FULL, &dn)) {
|
||||
fprintf(stderr, "Certificate #%u: %.*s", i, dn.size, dn.data);
|
||||
|
||||
gnutls_free(dn.data);
|
||||
}
|
||||
}
|
||||
|
||||
gnutls_x509_crt_deinit(cert);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CURLSSLBACKEND_NONE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com/");
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, wrfu);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
|
||||
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 0L);
|
||||
|
||||
(void) curl_easy_perform(curl);
|
||||
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
112
Engine/lib/curl/docs/examples/sftpget.c
Normal file
112
Engine/lib/curl/docs/examples/sftpget.c
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/***************************************************************************
|
||||
* _ _ ____ _
|
||||
* Project ___| | | | _ \| |
|
||||
* / __| | | | |_) | |
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
* are also available at https://curl.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.
|
||||
*
|
||||
* SPDX-License-Identifier: curl
|
||||
*
|
||||
***************************************************************************/
|
||||
/* <DESC>
|
||||
* Gets a file using an SFTP URL.
|
||||
* </DESC>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
/* define this to switch off the use of ssh-agent in this program */
|
||||
#undef DISABLE_SSH_AGENT
|
||||
|
||||
/*
|
||||
* This is an example showing how to get a single file from an SFTP server.
|
||||
* It delays the actual destination file creation until the first write
|
||||
* callback so that it will not create an empty file in case the remote file
|
||||
* does not exist or something else fails.
|
||||
*/
|
||||
|
||||
struct FtpFile {
|
||||
const char *filename;
|
||||
FILE *stream;
|
||||
};
|
||||
|
||||
static size_t my_fwrite(void *buffer, size_t size, size_t nmemb,
|
||||
void *stream)
|
||||
{
|
||||
struct FtpFile *out = (struct FtpFile *)stream;
|
||||
if(!out->stream) {
|
||||
/* open file for writing */
|
||||
out->stream = fopen(out->filename, "wb");
|
||||
if(!out->stream)
|
||||
return -1; /* failure, cannot open file to write */
|
||||
}
|
||||
return fwrite(buffer, size, nmemb, out->stream);
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
CURL *curl;
|
||||
CURLcode res;
|
||||
struct FtpFile ftpfile = {
|
||||
"yourfile.bin", /* name to store the file as if successful */
|
||||
NULL
|
||||
};
|
||||
|
||||
curl_global_init(CURL_GLOBAL_DEFAULT);
|
||||
|
||||
curl = curl_easy_init();
|
||||
if(curl) {
|
||||
/*
|
||||
* You better replace the URL with one that works!
|
||||
*/
|
||||
curl_easy_setopt(curl, CURLOPT_URL,
|
||||
"sftp://user@server/home/user/file.txt");
|
||||
/* Define our callback to get called when there's data to be written */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, my_fwrite);
|
||||
/* Set a pointer to our struct to pass to the callback */
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &ftpfile);
|
||||
|
||||
#ifndef DISABLE_SSH_AGENT
|
||||
/* We activate ssh agent. For this to work you need
|
||||
to have ssh-agent running (type set | grep SSH_AGENT to check) or
|
||||
pageant on Windows (there is an icon in systray if so) */
|
||||
curl_easy_setopt(curl, CURLOPT_SSH_AUTH_TYPES, CURLSSH_AUTH_AGENT);
|
||||
#endif
|
||||
|
||||
/* Switch on full protocol/debug output */
|
||||
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
/* always cleanup */
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if(CURLE_OK != res) {
|
||||
/* we failed */
|
||||
fprintf(stderr, "curl told us %d\n", res);
|
||||
}
|
||||
}
|
||||
|
||||
if(ftpfile.stream)
|
||||
fclose(ftpfile.stream); /* close the local file */
|
||||
|
||||
curl_global_cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue