Compare commits
5 Commits
fba8e8eb39
...
0ec3cd562e
Author | SHA1 | Date |
---|---|---|
Archilocos | 0ec3cd562e | |
Fufu Fang | 03ce864e70 | |
Fufu Fang | 6775564354 | |
Fufu Fang | 707d9b9253 | |
liuchenghao | f361527459 |
|
@ -0,0 +1,4 @@
|
||||||
|
version = 1
|
||||||
|
|
||||||
|
[[analyzers]]
|
||||||
|
name = "cxx"
|
|
@ -0,0 +1,89 @@
|
||||||
|
# For most projects, this workflow file will not need changing; you simply need
|
||||||
|
# to commit it to your repository.
|
||||||
|
#
|
||||||
|
# You may wish to alter this file to override the set of languages analyzed,
|
||||||
|
# or to provide custom queries or build logic.
|
||||||
|
#
|
||||||
|
# ******** NOTE ********
|
||||||
|
# We have attempted to detect the languages in your repository. Please check
|
||||||
|
# the `language` matrix defined below to confirm you have the correct set of
|
||||||
|
# supported CodeQL languages.
|
||||||
|
#
|
||||||
|
name: "CodeQL"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "master" ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ "master" ]
|
||||||
|
schedule:
|
||||||
|
- cron: '18 19 * * 1'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Analyze
|
||||||
|
# Runner size impacts CodeQL analysis time. To learn more, please see:
|
||||||
|
# - https://gh.io/recommended-hardware-resources-for-running-codeql
|
||||||
|
# - https://gh.io/supported-runners-and-hardware-resources
|
||||||
|
# - https://gh.io/using-larger-runners
|
||||||
|
# Consider using larger runners for possible analysis time improvements.
|
||||||
|
runs-on: 'ubuntu-latest'
|
||||||
|
timeout-minutes: 360
|
||||||
|
permissions:
|
||||||
|
# required for all workflows
|
||||||
|
security-events: write
|
||||||
|
|
||||||
|
# only required for workflows in private repositories
|
||||||
|
actions: read
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
language: [ 'c-cpp' ]
|
||||||
|
# CodeQL supports [ 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift' ]
|
||||||
|
# Use only 'java-kotlin' to analyze code written in Java, Kotlin or both
|
||||||
|
# Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
|
||||||
|
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install libgumbo-dev libfuse-dev libssl-dev libcurl4-openssl-dev uuid-dev help2man
|
||||||
|
|
||||||
|
# Initializes the CodeQL tools for scanning.
|
||||||
|
- name: Initialize CodeQL
|
||||||
|
uses: github/codeql-action/init@v3
|
||||||
|
with:
|
||||||
|
languages: ${{ matrix.language }}
|
||||||
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
|
# By default, queries listed here will override any specified in a config file.
|
||||||
|
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||||
|
|
||||||
|
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||||
|
# queries: security-extended,security-and-quality
|
||||||
|
|
||||||
|
|
||||||
|
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
|
||||||
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
|
- name: Autobuild
|
||||||
|
uses: github/codeql-action/autobuild@v3
|
||||||
|
|
||||||
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
|
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||||
|
|
||||||
|
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||||
|
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||||
|
|
||||||
|
# - run: |
|
||||||
|
# echo "Run, Build Application using script"
|
||||||
|
# ./location_of_script_within_repo/buildscript.sh
|
||||||
|
|
||||||
|
- name: Perform CodeQL Analysis
|
||||||
|
uses: github/codeql-action/analyze@v3
|
||||||
|
with:
|
||||||
|
category: "/language:${{matrix.language}}"
|
22
README.md
22
README.md
|
@ -1,3 +1,7 @@
|
||||||
|
[![CodeQL](https://github.com/fangfufu/httpdirfs/actions/workflows/codeql.yml/badge.svg)](https://github.com/fangfufu/httpdirfs/actions/workflows/codeql.yml)
|
||||||
|
[![CodeFactor](https://www.codefactor.io/repository/github/fangfufu/httpdirfs/badge)](https://www.codefactor.io/repository/github/fangfufu/httpdirfs)
|
||||||
|
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/30af0a5b4d6f4a4d83ddb68f5193ad23)](https://app.codacy.com/gh/fangfufu/httpdirfs/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
|
||||||
|
|
||||||
# HTTPDirFS - HTTP Directory Filesystem with a permanent cache, and Airsonic / Subsonic server support!
|
# HTTPDirFS - HTTP Directory Filesystem with a permanent cache, and Airsonic / Subsonic server support!
|
||||||
|
|
||||||
Have you ever wanted to mount those HTTP directory listings as if it was a
|
Have you ever wanted to mount those HTTP directory listings as if it was a
|
||||||
|
@ -22,9 +26,9 @@ present a HTTP directory listing.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
Please note if you install HTTDirFS from a repository, it can be outdated.
|
Please note if you install HTTDirFS from a repository, it can be outdated.
|
||||||
### Debian 11 "Bullseye"
|
### Debian 12 "Bookworm"
|
||||||
HTTPDirFS is available as a package in Debian 11 "Bullseye", If you are on
|
HTTPDirFS is available as a package in Debian 12 "Bookworm", If you are on
|
||||||
Debian Bullseye, you can simply run the following
|
Debian Bookworm, you can simply run the following
|
||||||
command as ``root``:
|
command as ``root``:
|
||||||
|
|
||||||
apt install httpdirfs
|
apt install httpdirfs
|
||||||
|
@ -42,14 +46,14 @@ HTTPDirFS is available in the
|
||||||
|
|
||||||
## Compilation
|
## Compilation
|
||||||
### Ubuntu
|
### Ubuntu
|
||||||
Under Ubuntu 18.04.4 LTS, you need the following packages:
|
Under Ubuntu 22.04 LTS, you need the following packages:
|
||||||
|
|
||||||
libgumbo-dev libfuse-dev libssl-dev libcurl4-openssl-dev uuid-dev
|
libgumbo-dev libfuse-dev libssl-dev libcurl4-openssl-dev uuid-dev help2man
|
||||||
|
|
||||||
### Debian 11 "Bullseye" and Debian 10 "Buster"
|
### Debian 12 "Bookworm"
|
||||||
Under Debian 10 "Buster" and newer versions, you need the following packages:
|
Under Debian 12 "Bookworm" and newer versions, you need the following packages:
|
||||||
|
|
||||||
libgumbo-dev libfuse-dev libssl-dev libcurl4-openssl-dev uuid-dev
|
libgumbo-dev libfuse-dev libssl-dev libcurl4-openssl-dev uuid-dev help2man
|
||||||
|
|
||||||
### FreeBSD
|
### FreeBSD
|
||||||
The following dependencies are required from either pkg or ports:
|
The following dependencies are required from either pkg or ports:
|
||||||
|
@ -300,6 +304,8 @@ for the technical and moral support. Your wisdom is much appreciated!
|
||||||
compatibility patches.
|
compatibility patches.
|
||||||
- I would like to thank [hiliev](https://github.com/hiliev) for providing macOS
|
- I would like to thank [hiliev](https://github.com/hiliev) for providing macOS
|
||||||
compatibility patches.
|
compatibility patches.
|
||||||
|
- I would like to thank [Jonathan Kamens](https://github.com/jikamens) for providing
|
||||||
|
a whole bunch of code improvements and the improved build system.
|
||||||
- I would like to thank [-Archivist](https://www.reddit.com/user/-Archivist/)
|
- I would like to thank [-Archivist](https://www.reddit.com/user/-Archivist/)
|
||||||
for not providing FTP or WebDAV access to his server. This piece of software was
|
for not providing FTP or WebDAV access to his server. This piece of software was
|
||||||
written in direct response to his appalling behaviour.
|
written in direct response to his appalling behaviour.
|
||||||
|
|
|
@ -5,7 +5,7 @@ AC_PROG_CC
|
||||||
AC_SEARCH_LIBS([backtrace],[execinfo])
|
AC_SEARCH_LIBS([backtrace],[execinfo])
|
||||||
|
|
||||||
# Because we use $(fuse_LIBS) in $(CFLAGS); see comment in Makefile.in
|
# Because we use $(fuse_LIBS) in $(CFLAGS); see comment in Makefile.in
|
||||||
AX_CHECK_COMPILE_FLAG([-Wunused-command-line-argument],[NUCLA=-Wno-unused-command-line-argument],,[-Werror])
|
AX_CHECK_COMPILE_FLAG([-Wunused-command-line-argument],[NUCLA=-Wno-unused-command-line-argument],[-Werror])
|
||||||
AC_SUBST([NUCLA])
|
AC_SUBST([NUCLA])
|
||||||
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
AM_INIT_AUTOMAKE([foreign subdir-objects])
|
||||||
PKG_CHECK_MODULES([pkgconf],[gumbo libcurl uuid expat openssl])
|
PKG_CHECK_MODULES([pkgconf],[gumbo libcurl uuid expat openssl])
|
||||||
|
|
10
src/link.c
10
src/link.c
|
@ -237,11 +237,13 @@ static void LinkTable_uninitialised_fill(LinkTable *linktbl)
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Block until the gaps are filled
|
* Block until the gaps are filled
|
||||||
|
* result is an invalid variable
|
||||||
*/
|
*/
|
||||||
int n = curl_multi_perform_once();
|
int result = 0;
|
||||||
|
int n = curl_multi_perform_once(&result);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int j = 0;
|
int j = 0;
|
||||||
while ((i = curl_multi_perform_once())) {
|
while ((i = curl_multi_perform_once(&result))) {
|
||||||
if (CONFIG.log_type & debug) {
|
if (CONFIG.log_type & debug) {
|
||||||
if (j) {
|
if (j) {
|
||||||
erase_string(stderr, STATUS_LEN, s);
|
erase_string(stderr, STATUS_LEN, s);
|
||||||
|
@ -949,7 +951,7 @@ TransferStruct Link_download_full(Link *link)
|
||||||
*/
|
*/
|
||||||
long http_resp = 0;
|
long http_resp = 0;
|
||||||
do {
|
do {
|
||||||
transfer_blocking(curl);
|
transfer_blocking(curl, ts.curr_size);
|
||||||
ret = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_resp);
|
ret = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_resp);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
lprintf(error, "%s", curl_easy_strerror(ret));
|
lprintf(error, "%s", curl_easy_strerror(ret));
|
||||||
|
@ -1075,7 +1077,7 @@ long Link_download(Link *link, char *output_buf, size_t req_size, off_t offset)
|
||||||
|
|
||||||
CURL *curl = Link_download_curl_setup(link, req_size, offset, &header, &ts);
|
CURL *curl = Link_download_curl_setup(link, req_size, offset, &header, &ts);
|
||||||
|
|
||||||
transfer_blocking(curl);
|
transfer_blocking(curl, offset);
|
||||||
|
|
||||||
curl_off_t recv = Link_download_cleanup(curl, &header);
|
curl_off_t recv = Link_download_cleanup(curl, &header);
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ----------------- External variables ----------------------
|
* ----------------- External variables ----------------------
|
||||||
|
@ -110,9 +111,10 @@ curl_callback_unlock(CURL *handle, curl_lock_data data, void *userptr)
|
||||||
* \details Adapted from:
|
* \details Adapted from:
|
||||||
* https://curl.haxx.se/libcurl/c/10-at-a-time.html
|
* https://curl.haxx.se/libcurl/c/10-at-a-time.html
|
||||||
*/
|
*/
|
||||||
static void
|
static int
|
||||||
curl_process_msgs(CURLMsg *curl_msg, int n_running_curl, int n_mesgs)
|
curl_process_msgs(CURLMsg *curl_msg, int n_running_curl, int n_mesgs)
|
||||||
{
|
{
|
||||||
|
int result = 0;
|
||||||
(void) n_running_curl;
|
(void) n_running_curl;
|
||||||
(void) n_mesgs;
|
(void) n_mesgs;
|
||||||
static volatile int slept = 0;
|
static volatile int slept = 0;
|
||||||
|
@ -163,6 +165,7 @@ curl_process_msgs(CURLMsg *curl_msg, int n_running_curl, int n_mesgs)
|
||||||
lprintf(error, "%d - %s <%s>\n",
|
lprintf(error, "%d - %s <%s>\n",
|
||||||
curl_msg->data.result,
|
curl_msg->data.result,
|
||||||
curl_easy_strerror(curl_msg->data.result), url);
|
curl_easy_strerror(curl_msg->data.result), url);
|
||||||
|
result = curl_msg->data.result;
|
||||||
}
|
}
|
||||||
curl_multi_remove_handle(curl_multi, curl);
|
curl_multi_remove_handle(curl_multi, curl);
|
||||||
/*
|
/*
|
||||||
|
@ -175,13 +178,50 @@ curl_process_msgs(CURLMsg *curl_msg, int n_running_curl, int n_mesgs)
|
||||||
} else {
|
} else {
|
||||||
lprintf(warning, "curl_msg->msg: %d\n", curl_msg->msg);
|
lprintf(warning, "curl_msg->msg: %d\n", curl_msg->msg);
|
||||||
}
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int http_error_result(int http_response)
|
||||||
|
{
|
||||||
|
switch(http_response)
|
||||||
|
{
|
||||||
|
case 0: //eg connection down from kick-off ~suggest retrying till some max limit
|
||||||
|
case 200: //yay we at least got to our url
|
||||||
|
case 206: //Partial Content
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 416:
|
||||||
|
//cannot d/l range ~ either cos no server support
|
||||||
|
//or cos we're asking for an invalid range ~ie: we already d/ld the file
|
||||||
|
printf("HTTP416: either the d/l is already complete or the http server cannot d/l a range\n");
|
||||||
|
default:
|
||||||
|
return 0;//suggest quitting on an unhandled error
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int curl_error_result(int curl_result)
|
||||||
|
{
|
||||||
|
switch (curl_result)
|
||||||
|
{
|
||||||
|
case CURLE_OK:
|
||||||
|
case CURLE_COULDNT_CONNECT: //no network connectivity ?
|
||||||
|
case CURLE_OPERATION_TIMEDOUT: //cos of CURLOPT_LOW_SPEED_TIME
|
||||||
|
case CURLE_COULDNT_RESOLVE_HOST: //host/DNS down ?
|
||||||
|
break; //we'll keep trying
|
||||||
|
default://see: http://curl.haxx.se/libcurl/c/libcurl-errors.html
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \details effectively based on
|
* \details effectively based on
|
||||||
* https://curl.haxx.se/libcurl/c/multi-double.html
|
* https://curl.haxx.se/libcurl/c/multi-double.html
|
||||||
*/
|
*/
|
||||||
int curl_multi_perform_once(void)
|
int curl_multi_perform_once(int *result)
|
||||||
{
|
{
|
||||||
lprintf(network_lock_debug,
|
lprintf(network_lock_debug,
|
||||||
"thread %x: locking transfer_lock;\n", pthread_self());
|
"thread %x: locking transfer_lock;\n", pthread_self());
|
||||||
|
@ -207,7 +247,12 @@ int curl_multi_perform_once(void)
|
||||||
int n_mesgs;
|
int n_mesgs;
|
||||||
CURLMsg *curl_msg;
|
CURLMsg *curl_msg;
|
||||||
while ((curl_msg = curl_multi_info_read(curl_multi, &n_mesgs))) {
|
while ((curl_msg = curl_multi_info_read(curl_multi, &n_mesgs))) {
|
||||||
curl_process_msgs(curl_msg, n_running_curl, n_mesgs);
|
int nResult = curl_process_msgs(curl_msg, n_running_curl, n_mesgs);
|
||||||
|
if (!http_error_result(n_mesgs) || !curl_error_result(nResult)) {
|
||||||
|
*result = 1;
|
||||||
|
}else{
|
||||||
|
*result = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lprintf(network_lock_debug,
|
lprintf(network_lock_debug,
|
||||||
|
@ -272,7 +317,7 @@ void NetworkSystem_init(void)
|
||||||
crypto_lock_init();
|
crypto_lock_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void transfer_blocking(CURL *curl)
|
void transfer_blocking(CURL *curl, size_t start)
|
||||||
{
|
{
|
||||||
TransferStruct *ts;
|
TransferStruct *ts;
|
||||||
CURLcode ret = curl_easy_getinfo(curl, CURLINFO_PRIVATE, &ts);
|
CURLcode ret = curl_easy_getinfo(curl, CURLINFO_PRIVATE, &ts);
|
||||||
|
@ -293,8 +338,22 @@ void transfer_blocking(CURL *curl)
|
||||||
"thread %x: unlocking transfer_lock;\n", pthread_self());
|
"thread %x: unlocking transfer_lock;\n", pthread_self());
|
||||||
PTHREAD_MUTEX_UNLOCK(&transfer_lock);
|
PTHREAD_MUTEX_UNLOCK(&transfer_lock);
|
||||||
|
|
||||||
while (ts->transferring) {
|
int result = 0;
|
||||||
curl_multi_perform_once();
|
bool restartDown = false;
|
||||||
|
|
||||||
|
while (ts->transferring && !restartDown) {
|
||||||
|
/*
|
||||||
|
* When the network is abnormal during the file download, start to resume the transfer
|
||||||
|
*/
|
||||||
|
if (0 != result) {
|
||||||
|
curl_multi_remove_handle(curl_multi,curl);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_RESUME_FROM_LARGE, start);
|
||||||
|
res = curl_multi_add_handle(curl_multi, curl);
|
||||||
|
if (res > 0) {
|
||||||
|
lprintf(error, "%d, %s\n", res, curl_multi_strerror(res));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
curl_multi_perform_once(&result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,13 +26,13 @@ typedef enum {
|
||||||
extern CURLSH *CURL_SHARE;
|
extern CURLSH *CURL_SHARE;
|
||||||
|
|
||||||
/** \brief perform one transfer cycle */
|
/** \brief perform one transfer cycle */
|
||||||
int curl_multi_perform_once(void);
|
int curl_multi_perform_once(int *result);
|
||||||
|
|
||||||
/** \brief initialise the network module */
|
/** \brief initialise the network module */
|
||||||
void NetworkSystem_init(void);
|
void NetworkSystem_init(void);
|
||||||
|
|
||||||
/** \brief blocking file transfer */
|
/** \brief blocking file transfer */
|
||||||
void transfer_blocking(CURL *curl);
|
void transfer_blocking(CURL *curl, size_t start);
|
||||||
|
|
||||||
/** \brief non blocking file transfer */
|
/** \brief non blocking file transfer */
|
||||||
void transfer_nonblocking(CURL *curl);
|
void transfer_nonblocking(CURL *curl);
|
||||||
|
|
Loading…
Reference in New Issue