From 41de727f8f9a25720e1c8f00c78792e7ef96c7c2 Mon Sep 17 00:00:00 2001 From: Fufu Fang Date: Tue, 24 Jul 2018 17:37:23 +0100 Subject: [PATCH] completed crypto lock array --- Makefile | 4 ++-- README.md | 11 ++++++++++ main.c | 4 ---- network.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 69 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index d6ee4ad..f1f314f 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ CC=gcc -CFLAGS= -g -Wall -Wextra -lgumbo -lcurl -lfuse -D_FILE_OFFSET_BITS=64 \ --DHTTPDIRFS_INFO +CFLAGS= -O2 -Wall -Wextra -lgumbo -lcurl -lfuse -lcrypto \ +-D_FILE_OFFSET_BITS=64 -DHTTPDIRFS_INFO OBJ = main.o network.o %.o: %.c diff --git a/README.md b/README.md index 73a702d..0fe9492 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,21 @@ Have you ever wanted to mount those HTTP directory listings as if it was a parti The performance of the program is excellent, due to the use of curl-multi interface. HTTP connections are reused, and HTTP pipelining is used when available. I haven't benchmarked it, but I feel this is faster than ``rclone mount``. The FUSE component itself also runs in multithreaded mode. +## Compilation +This program was developed under Debian Stretch. If you are using the same operation system as me, you need ``libgumbo-dev``, ``libfuse-dev`` and ``libcurl4-openssl-dev``. + ## Usage + ./httpdirfs -f $URL $YOUR_MOUNT_POINT + An example URL would be [Debian CD Image Server](https://cdimage.debian.org/debian-cd/). The ``-f`` flag keeps the program in the foreground, which is useful for monitoring which URL the filesystem is visiting. +If you run the program in the foreground, when it starts up, it will output the SSL engine version string. Please verify that your libcurl is linked agains OpenSSL, otherwise it might crash when you are downloading from HTTPS websites. + +The SSL engine version string looks something like this: + + libcurl SSL engine: OpenSSL/1.0.2l + ## The Technical Details I noticed that most HTTP directory listings don't provide the file size for the web page itself. I suppose this makes perfect sense, as they are generated on the fly. Whereas the actual files have got file sizes. So the listing pages can be treated as folders, and the rest are files. diff --git a/main.c b/main.c index 45f4413..e825e85 100644 --- a/main.c +++ b/main.c @@ -40,10 +40,6 @@ int main(int argc, char **argv) { } BASE_URL = argv[argc-2]; - if (!strncmp(BASE_URL, "https", 5)) { - fprintf(stderr, "You have supplied an HTTPS link, the program might \ -crash, due to thread safety issues."); - } argv[argc-2] = argv[argc-1]; argv[argc-1] = NULL; argc--; diff --git a/network.c b/network.c index 8f5a0d8..0975149 100644 --- a/network.c +++ b/network.c @@ -1,5 +1,7 @@ #include "network.h" +#include + #include #include #include @@ -8,10 +10,14 @@ #include #include + #define HTTP_OK 200 #define HTTP_PARTIAL_CONTENT 206 #define HTTP_RANGE_NOT_SATISFIABLE 416 +/* ------------------------ External variables ----------------------------*/ +LinkTable *ROOT_LINK_TBL; + /* ------------------------ Local structs ---------------------------------*/ typedef struct { char *memory; @@ -29,16 +35,16 @@ typedef struct { Link *link; } TransferStruct; -/* ------------------------ External variables ----------------------------*/ -LinkTable *ROOT_LINK_TBL; - /* ------------------------ Static variable ------------------------------ */ /** \brief curl shared interface - not actually being used. */ static CURLSH *curl_share; /** \brief curl multi interface handle */ static CURLM *curl_multi; -/** \brief pthread mutex for transfer functions/ */ +/** \brief pthread mutex for transfer functions */ static pthread_mutex_t transfer_lock; + +/** \brief the lock array for cryptographic functions */ +static pthread_mutex_t *crypto_lockarray; /** * \brief pthread mutex for curl itself * \note I am sure if it is being used properly @@ -46,6 +52,43 @@ static pthread_mutex_t transfer_lock; static pthread_mutex_t curl_lock; /* -------------------------- Functions ---------------------------------- */ +#pragma GCC diagnostic ignored "-Wunused-function" +static void lock_callback(int mode, int type, char *file, int line) +{ +#pragma GCC diagnostic pop + (void)file; + (void)line; + if(mode & CRYPTO_LOCK) { + pthread_mutex_lock(&(crypto_lockarray[type])); + } + else { + pthread_mutex_unlock(&(crypto_lockarray[type])); + } +} +#pragma GCC diagnostic ignored "-Wunused-function" +static unsigned long thread_id(void) +{ +#pragma GCC diagnostic pop + unsigned long ret; + + ret = (unsigned long)pthread_self(); + return ret; +} + +static void init_locks(void) +{ + int i; + + crypto_lockarray = (pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() * + sizeof(pthread_mutex_t)); + for(i = 0; issl_version); + /* create the root link table */ ROOT_LINK_TBL = LinkTable_new(url); }