added username and password support

This commit is contained in:
Fufu Fang 2018-07-30 14:20:04 +01:00
parent 62aee1c657
commit 5744a3338a
4 changed files with 113 additions and 48 deletions

16
link.c
View File

@ -14,7 +14,7 @@
#define HTTP_RANGE_NOT_SATISFIABLE 416
/* ---------------- External variables -----------------------*/
LinkTable *ROOT_LINK_TBL;
LinkTable *ROOT_LINK_TBL = NULL;
static void HTML_to_LinkTable(GumboNode *node, LinkTable *linktbl);
static Link *Link_new(const char *p_url, LinkType type);
@ -90,12 +90,20 @@ static CURL *Link_to_curl(Link *link)
curl_easy_setopt(curl, CURLOPT_URL, link->f_url);
curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15);
curl_easy_setopt(curl, CURLOPT_SHARE, curl_share);
curl_easy_setopt(curl, CURLOPT_SHARE, CURL_SHARE);
/*
* The write back function pointer has to be set at curl handle creation,
* for thread safety
*/
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_memory_callback);
if (NETWORK_CONFIG.username) {
curl_easy_setopt(curl, CURLOPT_USERNAME, NETWORK_CONFIG.username);
}
if (NETWORK_CONFIG.password) {
curl_easy_setopt(curl, CURLOPT_PASSWORD, NETWORK_CONFIG.password);
}
return curl;
}
@ -229,7 +237,7 @@ LinkTable *LinkTable_new(const char *url)
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_resp);
if (http_resp != HTTP_OK) {
fprintf(stderr, "link.c: LinkTable_new() cannot retrive the base URL, \
URL: %s, HTTP %ld\n", url, http_resp);
URL: %s, HTTP %ld\n", url, http_resp);
LinkTable_free(linktbl);
linktbl = NULL;

79
main.c
View File

@ -4,20 +4,11 @@
#include <getopt.h>
#include <string.h>
void add_arg(char ***fuse_argv_ptr, int *fuse_argc, char *opt_string);
static void print_help(char *program_name);
#define ARG_LEN_MAX 64
/**
* \brief add an argument to an argv array
* \details This is basically how you add a string to an array of string
*/
void add_arg(char ***fuse_argv_ptr, int *fuse_argc, char *opt_string)
{
(*fuse_argc)++;
*fuse_argv_ptr = realloc(*fuse_argv_ptr, *fuse_argc * sizeof(char *));
char **fuse_argv = *fuse_argv_ptr;
fuse_argv[*fuse_argc - 1] = opt_string;
}
void add_arg(char ***fuse_argv_ptr, int *fuse_argc, char *opt_string);
static void print_help(char *program_name, int long_help);
static void print_http_options();
int main(int argc, char **argv)
{
@ -28,17 +19,23 @@ int main(int argc, char **argv)
add_arg(&fuse_argv, &fuse_argc, argv[0]);
/* Automatically print help if not enough arguments are supplied */
if (argc < 2) {
add_arg(&fuse_argv, &fuse_argc, "--help");
goto fuse_start;
print_help(argv[0], 0);
fprintf(stderr, "For more information, run \"%s --help.\"\n", argv[0]);
exit(EXIT_FAILURE);
}
/* initialise network configuration struct */
network_config_init();
char c;
int opts_index = 0;
const char *short_opts = "o:hVdfs";
const char *short_opts = "o:hVdfsp:u:";
const struct option long_opts[] = {
{"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 'V'},
{"debug", no_argument, NULL, 'd'},
{"username", required_argument, NULL, 'u'},
{"password", required_argument, NULL, 'p'},
{0, 0, 0, 0}
};
while ((c =
@ -50,7 +47,7 @@ int main(int argc, char **argv)
add_arg(&fuse_argv, &fuse_argc, optarg);
break;
case 'h':
print_help(argv[0]);
print_help(argv[0], 1);
add_arg(&fuse_argv, &fuse_argc, "-h");
goto fuse_start;
break;
@ -66,22 +63,33 @@ int main(int argc, char **argv)
case 's':
add_arg(&fuse_argv, &fuse_argc, "-s");
break;
case 'p':
NETWORK_CONFIG.username = strndup(optarg, ARG_LEN_MAX);
break;
case 'u':
NETWORK_CONFIG.password = strndup(optarg, ARG_LEN_MAX);
break;
case '?':
exit(EXIT_FAILURE);
fprintf(stderr, "Error: Invalid option\n");
add_arg(&fuse_argv, &fuse_argc, "--help");
goto fuse_start;
}
};
/* Add the last remaining argument, which is the mount point */
/* Add the last remaining argument, which is the mountpoint */
add_arg(&fuse_argv, &fuse_argc, argv[argc-1]);
/* The second last remaining argument is the URL */
char *base_url = argv[argc-2];
if (strncmp(base_url, "http://", 7) && strncmp(base_url, "https://", 8)) {
fprintf(stderr, "Error: Please supply a valid URL.\n");
print_help(argv[0]);
print_help(argv[0], 0);
exit(EXIT_FAILURE);
} else {
network_init(base_url);
if(!network_init(base_url)) {
fprintf(stderr, "Error: Network initialisation failed.\n");
exit(EXIT_FAILURE);
}
}
fuse_start:
@ -90,9 +98,32 @@ int main(int argc, char **argv)
return 0;
}
static void print_help(char *program_name)
/**
* \brief add an argument to an argv array
* \details This is basically how you add a string to an array of string
*/
void add_arg(char ***fuse_argv_ptr, int *fuse_argc, char *opt_string)
{
fprintf(stderr,
"Usage: %s [options] URL mount_point\n", program_name);
(*fuse_argc)++;
*fuse_argv_ptr = realloc(*fuse_argv_ptr, *fuse_argc * sizeof(char *));
char **fuse_argv = *fuse_argv_ptr;
fuse_argv[*fuse_argc - 1] = strndup(opt_string, ARG_LEN_MAX);
}
static void print_help(char *program_name, int long_help)
{
fprintf(stderr,
"Usage: %s [options] URL mountpoint\n", program_name);
if (long_help) {
print_http_options();
}
}
static void print_http_options()
{
fprintf(stderr,
"HTTP options:\n\
-u --username HTTP authentication username\n\
-p --password HTTP authentication password\n\n\
libfuse options:\n");
}

View File

@ -8,8 +8,9 @@
#include <stdio.h>
#include <unistd.h>
/* ----------------- External variables ----------------------*/
CURLSH *curl_share;
/* ----------------- External variables ---------------------- */
CURLSH *CURL_SHARE;
NetworkConfigStruct NETWORK_CONFIG;
/* ----------------- Static variable ----------------------- */
/** \brief curl multi interface handle */
@ -18,8 +19,9 @@ static CURLM *curl_multi;
static pthread_mutex_t transfer_lock;
/** \brief the lock array for cryptographic functions */
static pthread_mutex_t *crypto_lockarray;
/** \brief mutex for curl share interface itself */
/** \brief mutex for curl share interface itself */
static pthread_mutex_t curl_lock;
/** \brief network configuration */
/* ---------------- Static function prototype ---------------*/
static void crypto_lock_callback(int mode, int type, char *file, int line);
@ -188,10 +190,18 @@ void curl_process_msgs(CURLMsg *curl_msg, int n_running_curl, int n_mesgs)
}
}
void network_init(const char *url)
void network_config_init()
{
NETWORK_CONFIG.username = NULL;
NETWORK_CONFIG.password = NULL;
NETWORK_CONFIG.proxy_url = NULL;
NETWORK_CONFIG.proxy_password = NULL;
NETWORK_CONFIG.proxy_password = NULL;
NETWORK_CONFIG.max_conns = NETWORK_MAX_CONNS;
}
LinkTable *network_init(const char *url)
{
/* ------- Global related ----------*/
if (curl_global_init(CURL_GLOBAL_ALL)) {
fprintf(stderr, "network_init(): curl_global_init() failed!\n");
@ -199,22 +209,22 @@ void network_init(const char *url)
}
/* -------- Share related ----------*/
curl_share = curl_share_init();
if (!(curl_share)) {
CURL_SHARE = curl_share_init();
if (!(CURL_SHARE)) {
fprintf(stderr, "network_init(): curl_share_init() failed!\n");
exit(EXIT_FAILURE);
}
curl_share_setopt(curl_share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
curl_share_setopt(curl_share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
curl_share_setopt(curl_share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT);
curl_share_setopt(CURL_SHARE, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
curl_share_setopt(CURL_SHARE, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
curl_share_setopt(CURL_SHARE, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT);
if (pthread_mutex_init(&curl_lock, NULL) != 0) {
printf(
"network_init(): curl_lock initialisation failed!\n");
exit(EXIT_FAILURE);
}
curl_share_setopt(curl_share, CURLSHOPT_LOCKFUNC, curl_callback_lock);
curl_share_setopt(curl_share, CURLSHOPT_UNLOCKFUNC, curl_callback_unlock);
curl_share_setopt(CURL_SHARE, CURLSHOPT_LOCKFUNC, curl_callback_lock);
curl_share_setopt(CURL_SHARE, CURLSHOPT_UNLOCKFUNC, curl_callback_unlock);
/* ------------- Multi related -----------*/
curl_multi = curl_multi_init();
@ -223,7 +233,7 @@ void network_init(const char *url)
exit(EXIT_FAILURE);
}
curl_multi_setopt(curl_multi, CURLMOPT_MAXCONNECTS,
CURL_MULTI_MAX_CONNECTION);
NETWORK_CONFIG.max_conns);
/* ------------ Initialise locks ---------*/
if (pthread_mutex_init(&transfer_lock, NULL) != 0) {
@ -244,6 +254,7 @@ void network_init(const char *url)
/* ----------- create the root link table --------------*/
ROOT_LINK_TBL = LinkTable_new(url);
return ROOT_LINK_TBL;
}
void transfer_blocking(CURL *curl)
@ -295,7 +306,7 @@ static unsigned long thread_id(void)
}
size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
write_memory_callback(void *contents, size_t size, size_t nmemb, void *userp)
{
size_t realsize = size * nmemb;
MemoryStruct *mem = (MemoryStruct *)userp;
@ -303,7 +314,7 @@ WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
mem->memory = realloc(mem->memory, mem->size + realsize + 1);
if(!mem->memory) {
/* out of memory! */
fprintf(stderr, "WriteMemoryCallback(): realloc failure!\n");
fprintf(stderr, "write_memory_callback(): realloc failure!\n");
exit(EXIT_FAILURE);
return 0;
}

View File

@ -3,7 +3,7 @@
#include "link.h"
#define CURL_MULTI_MAX_CONNECTION 20
#define NETWORK_MAX_CONNS 20
typedef struct {
char *memory;
@ -21,14 +21,29 @@ typedef struct {
Link *link;
} TransferStruct;
typedef struct {
char *username;
char *password;
char *proxy_url;
char *proxy_username;
char *proxy_password;
long max_conns;
} NetworkConfigStruct;
/** \brief CURL configuration */
extern NetworkConfigStruct NETWORK_CONFIG;
/** \brief curl shared interface */
extern CURLSH *curl_share;
extern CURLSH *CURL_SHARE;
/** \brief perform one transfer cycle */
int curl_multi_perform_once();
/** \brief Initialise the network module */
void network_init(const char *url);
/** \brief initialise network config struct */
void network_config_init();
/** \brief initialise the network module */
LinkTable *network_init(const char *url);
/** \brief blocking file transfer */
void transfer_blocking(CURL *curl);
@ -38,6 +53,6 @@ void transfer_nonblocking(CURL *curl);
/** \brief callback function for file transfer */
size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp);
write_memory_callback(void *contents, size_t size, size_t nmemb, void *userp);
#endif