completed crypto lock array

This commit is contained in:
Fufu Fang 2018-07-24 17:37:23 +01:00
parent 7dacb88307
commit 41de727f8f
4 changed files with 69 additions and 10 deletions

View File

@ -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

View File

@ -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.

4
main.c
View File

@ -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--;

View File

@ -1,5 +1,7 @@
#include "network.h"
#include <openssl/crypto.h>
#include <ctype.h>
#include <errno.h>
#include <pthread.h>
@ -8,10 +10,14 @@
#include <stdlib.h>
#include <unistd.h>
#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; i<CRYPTO_num_locks(); i++) {
pthread_mutex_init(&(crypto_lockarray[i]), NULL);
}
CRYPTO_set_id_callback((unsigned long (*)())thread_id);
CRYPTO_set_locking_callback((void (*)())lock_callback);
}
static void pthread_lock_cb(CURL *handle, curl_lock_data data,
curl_lock_access access, void *userptr)
{
@ -67,6 +110,12 @@ static void pthread_unlock_cb(CURL *handle, curl_lock_data data,
void network_init(const char *url)
{
/*
* Intialise the cryptographic locks, these are shamelessly copied from
* https://curl.haxx.se/libcurl/c/threaded-ssl.html
*/
init_locks();
/* Global related */
if (curl_global_init(CURL_GLOBAL_ALL)) {
fprintf(stderr, "network_init(): curl_global_init() failed!\n");
@ -109,6 +158,9 @@ void network_init(const char *url)
exit(EXIT_FAILURE);
}
curl_version_info_data *data = curl_version_info(CURLVERSION_NOW);
printf("libcurl SSL engine: %s\n", data->ssl_version);
/* create the root link table */
ROOT_LINK_TBL = LinkTable_new(url);
}