From 6fddce73c53d47485c9dca835aaf3468325d1c71 Mon Sep 17 00:00:00 2001 From: YuQing <384681@qq.com> Date: Tue, 25 May 2021 16:41:11 +0800 Subject: [PATCH] add function normalize_path_ex and normalize_uri --- .gitignore | 4 + HISTORY | 3 +- libfastcommon.spec | 2 +- src/http_func.h | 4 + src/shared_func.c | 143 ++++++++++++++++++++++++++++++-- src/shared_func.h | 40 ++++++++- src/tests/Makefile | 3 +- src/tests/test_normalize_path.c | 44 ++++++++++ src/tests/test_pthread_wait.c | 134 ++++++++++++++++++++++++++++++ 9 files changed, 365 insertions(+), 12 deletions(-) create mode 100644 src/tests/test_normalize_path.c create mode 100644 src/tests/test_pthread_wait.c diff --git a/.gitignore b/.gitignore index de70dc9..e50a5cc 100644 --- a/.gitignore +++ b/.gitignore @@ -54,6 +54,10 @@ src/tests/test_file_write_hole src/tests/test_file_lock src/tests/test_thread_pool src/tests/test_data_visible +src/tests/test_pthread_wait +src/tests/test_mutex_lock_perf +src/tests/test_queue_perf +src/tests/test_normalize_path # other *.swp diff --git a/HISTORY b/HISTORY index d46f017..419f31e 100644 --- a/HISTORY +++ b/HISTORY @@ -1,7 +1,8 @@ -Version 1.51 2021-05-20 +Version 1.51 2021-05-25 * fast_mblock.[hc]: support batch alloc and batch free * uniq_skiplist.[hc]: init function add parameter: allocator_use_lock + * add function normalize_path_ex and normalize_uri Version 1.50 2021-05-11 * add function is_digital_string diff --git a/libfastcommon.spec b/libfastcommon.spec index fb3b7a3..eedbf67 100644 --- a/libfastcommon.spec +++ b/libfastcommon.spec @@ -4,7 +4,7 @@ %define CommitVersion %(echo $COMMIT_VERSION) Name: libfastcommon -Version: 1.0.50 +Version: 1.0.51 Release: 1%{?dist} Summary: c common functions library extracted from my open source projects FastDFS License: LGPL diff --git a/src/http_func.h b/src/http_func.h index 3a8061f..490a632 100644 --- a/src/http_func.h +++ b/src/http_func.h @@ -23,6 +23,10 @@ #include #include "common_define.h" +#define IS_URL_RESOURCE(str) \ + ((strncasecmp(str, "http://", 7) == 0) || \ + (strncasecmp(str, "https://", 8) == 0)) + #ifdef __cplusplus extern "C" { #endif diff --git a/src/shared_func.c b/src/shared_func.c index 7d81e7e..832fa8e 100644 --- a/src/shared_func.c +++ b/src/shared_func.c @@ -34,6 +34,7 @@ #include "logger.h" #include "sockopt.h" #include "fc_memory.h" +#include "http_func.h" #include "shared_func.h" #ifdef OS_LINUX @@ -2989,28 +2990,156 @@ char *format_http_date(time_t t, BufferInfo *buffer) return buffer->buff; } -char *resolve_path(const char *from, const char *filename, +int normalize_path(const char *from, const char *filename, char *full_filename, const int size) { const char *last; int len; if (*filename == '/') { - snprintf(full_filename, size, "%s", filename); - return full_filename; + return snprintf(full_filename, size, "%s", filename); } last = strrchr(from, '/'); if (last != NULL) { len = last - from; - snprintf(full_filename, size, "%.*s/%s", len, from, filename); + return snprintf(full_filename, size, "%.*s/%s", len, from, filename); } else { - logWarning("file: "__FILE__", line: %d, " + logWarning("file: "__FILE__", line: %d, " "no \"/\" in the from filename: %s", __LINE__, from); - snprintf(full_filename, size, "%s", filename); + return snprintf(full_filename, size, "%s", filename); } - return full_filename; +} + +int normalize_uri(const string_t *from, const char *uri, + char *dest, const int size) +{ +#define MAX_UP_PATH_COUNT 8 + const char *start; + const char *end; + const char *last; + string_t fpath; + string_t parts[MAX_UP_PATH_COUNT]; + int up_count; + int path_count; + int keep_count; + int len; + int i; + + if (*uri == '/') { + return snprintf(dest, size, "%s", uri); + } + + end = uri + strlen(uri); + up_count = 0; + start = uri; + while (start + 3 < end) { + if (memcmp(start, "../", 3) != 0) { + break; + } + + ++up_count; + start += 3; + } + + last = fc_memrchr(from->str, '/', from->len); + if (last == NULL) { + logWarning("file: "__FILE__", line: %d, " + "no \"/\" in the from uri: %s", + __LINE__, from->str); + return snprintf(dest, size, "/%s", start); + } + + if (up_count == 0) { + return snprintf(dest, size, "%.*s/%s", + (int)(last - from->str), from->str, uri); + } else { + fpath.str = (char *)from->str; + fpath.len = last - from->str; + path_count = split_string_ex(&fpath, '/', + parts, MAX_UP_PATH_COUNT, true); + keep_count = path_count - up_count; + if (keep_count < 0) { + logWarning("file: "__FILE__", line: %d, " + "uri: %s, contails too many \"../\"", + __LINE__, uri); + } + + len = 0; + for (i=0; i + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the Lesser GNU General Public License, version 3 + * or later ("LGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the Lesser GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include "fastcommon/logger.h" +#include "fastcommon/shared_func.h" + +int main(int argc, char *argv[]) +{ + char full_filename[PATH_MAX]; + const char *from; + const char *filename; + + if (argc < 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + log_init(); + from = argv[1]; + filename = argv[2]; + normalize_path_ex(from, filename, full_filename, sizeof(full_filename), + NORMALIZE_FLAGS_URL_ENABLED_AND_APPEND_PARAMS); + printf("%s\n", full_filename); + return 0; +} diff --git a/src/tests/test_pthread_wait.c b/src/tests/test_pthread_wait.c new file mode 100644 index 0000000..ab51d3a --- /dev/null +++ b/src/tests/test_pthread_wait.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2020 YuQing <384681@qq.com> + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the Lesser GNU General Public License, version 3 + * or later ("LGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the Lesser GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include "fastcommon/logger.h" +#include "fastcommon/shared_func.h" +#include "fastcommon/pthread_func.h" + +static bool continue_flag = true; +static pthread_lock_cond_pair_t lcp; + +static void *thread_func(void *arg) +{ + printf("file: "__FILE__", line: %d, " + "thread enter ...\n", __LINE__); + + PTHREAD_MUTEX_LOCK(&lcp.lock); + pthread_cond_wait(&lcp.cond, &lcp.lock); + PTHREAD_MUTEX_UNLOCK(&lcp.lock); + + printf("file: "__FILE__", line: %d, " + "thread done! \n", __LINE__); + return NULL; +} + +static void sigQuitHandler(int sig) +{ + if (continue_flag) { + continue_flag = false; + printf("file: "__FILE__", line: %d, " + "catch signal %d, program exiting...\n", + __LINE__, sig); + } +} + +static void sigHupHandler(int sig) +{ + printf("file: "__FILE__", line: %d, " + "catch signal %d\n", __LINE__, sig); +} + +static int setup_signal_handler() +{ + struct sigaction act; + memset(&act, 0, sizeof(act)); + sigemptyset(&act.sa_mask); + + signal(SIGHUP, sigHupHandler); + + /* + act.sa_handler = sigHupHandler; + if(sigaction(SIGHUP, &act, NULL) < 0) { + fprintf(stderr, "file: "__FILE__", line: %d, " + "call sigaction fail, errno: %d, error info: %s\n", + __LINE__, errno, strerror(errno)); + return errno; + } + */ + + act.sa_handler = sigQuitHandler; + if(sigaction(SIGINT, &act, NULL) < 0 || + sigaction(SIGTERM, &act, NULL) < 0 || + sigaction(SIGQUIT, &act, NULL) < 0) + { + fprintf(stderr, "file: "__FILE__", line: %d, " + "call sigaction fail, errno: %d, error info: %s\n", + __LINE__, errno, strerror(errno)); + return errno; + } + + return 0; +} + +int main(int argc, char *argv[]) +{ + int result; + int i; + pthread_t tid; + + log_init(); + + if ((result=setup_signal_handler()) != 0) { + return result; + } + if ((result=init_pthread_lock_cond_pair(&lcp)) != 0) { + return result; + } + + if ((result=pthread_create(&tid, NULL, thread_func, NULL)) != 0) { + return result; + } + + while (continue_flag) { + + /* + printf("file: "__FILE__", line: %d, " + "loop before ...\n", __LINE__); + PTHREAD_MUTEX_LOCK(&lcp.lock); + pthread_cond_wait(&lcp.cond, &lcp.lock); + PTHREAD_MUTEX_UNLOCK(&lcp.lock); + + printf("file: "__FILE__", line: %d, " + "loop after\n", __LINE__); + */ + sleep(1); + } + + //pthread_cond_signal(&lcp.cond); + for (i=0; i<3; i++) { + sleep(1); + } + + printf("file: "__FILE__", line: %d, " + "program exit.\n", __LINE__); + return 0; +}