shared_func.[hc]: normalize_path use type string_t for general purpose
parent
c18e864220
commit
22c7e31752
3
HISTORY
3
HISTORY
|
|
@ -1,4 +1,7 @@
|
|||
|
||||
Version 1.64 2022-11-07
|
||||
* shared_func.[hc]: normalize_path use type string_t for general purpose
|
||||
|
||||
Version 1.63 2022-10-16
|
||||
* sockopt.[hc]: getIpAndPort support ipv6
|
||||
|
||||
|
|
|
|||
|
|
@ -119,6 +119,11 @@ extern int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int kind);
|
|||
(strncasecmp(filename, FILE_RESOURCE_TAG_STR, \
|
||||
FILE_RESOURCE_TAG_LEN) == 0)
|
||||
|
||||
#define IS_FILE_RESOURCE_EX(filename) \
|
||||
((filename)->len >= FILE_RESOURCE_TAG_LEN && \
|
||||
memcmp((filename)->str, FILE_RESOURCE_TAG_STR, \
|
||||
FILE_RESOURCE_TAG_LEN) == 0)
|
||||
|
||||
#ifndef byte
|
||||
#define byte signed char
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@
|
|||
((strncasecmp(str, "http://", 7) == 0) || \
|
||||
(strncasecmp(str, "https://", 8) == 0))
|
||||
|
||||
#define IS_URL_RESOURCE_EX(s) \
|
||||
((s)->len >= 8 && ((memcmp((s)->str, "http://", 7) == 0) || \
|
||||
(memcmp((s)->str, "https://", 8) == 0)))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -278,6 +278,7 @@ int get_base_path_from_conf_file_ex(const char *filename, char *base_path,
|
|||
const int path_size, const int noent_log_level)
|
||||
{
|
||||
char *pBasePath;
|
||||
string_t path_string;
|
||||
IniContext iniContext;
|
||||
int result;
|
||||
|
||||
|
|
@ -303,7 +304,8 @@ int get_base_path_from_conf_file_ex(const char *filename, char *base_path,
|
|||
break;
|
||||
}
|
||||
|
||||
normalize_path(NULL, pBasePath, base_path, path_size);
|
||||
FC_SET_STRING(path_string, pBasePath);
|
||||
normalize_path(NULL, &path_string, base_path, path_size);
|
||||
chopPath(base_path);
|
||||
if (!fileExists(base_path))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1195,8 +1195,8 @@ int fc_remove_redundant_slashes(const string_t *src,
|
|||
else
|
||||
{
|
||||
input.str = full_filename;
|
||||
input.len = normalize_path(NULL, src->str,
|
||||
full_filename, sizeof(full_filename));
|
||||
input.len = normalize_path(NULL, src, full_filename,
|
||||
sizeof(full_filename));
|
||||
}
|
||||
|
||||
if (size <= input.len)
|
||||
|
|
@ -3204,27 +3204,32 @@ char *format_http_date(time_t t, BufferInfo *buffer)
|
|||
return buffer->buff;
|
||||
}
|
||||
|
||||
int normalize_path(const char *from, const char *filename,
|
||||
int normalize_path(const string_t *from, const string_t *filename,
|
||||
char *full_filename, const int size)
|
||||
{
|
||||
const char *start;
|
||||
const char *last;
|
||||
const char *end;
|
||||
char cwd[PATH_MAX];
|
||||
char buff[PATH_MAX];
|
||||
string_t true_from;
|
||||
string_t true_filename;
|
||||
int up_count;
|
||||
int path_len;
|
||||
int i;
|
||||
|
||||
if (IS_FILE_RESOURCE(filename)) {
|
||||
filename = filename + FILE_RESOURCE_TAG_LEN;
|
||||
if (IS_FILE_RESOURCE_EX(filename)) {
|
||||
true_filename.str = filename->str + FILE_RESOURCE_TAG_LEN;
|
||||
true_filename.len = filename->len - FILE_RESOURCE_TAG_LEN;
|
||||
filename = &true_filename;
|
||||
}
|
||||
|
||||
if (*filename == '/') {
|
||||
return snprintf(full_filename, size, "%s", filename);
|
||||
if (*filename->str == '/') {
|
||||
return snprintf(full_filename, size, "%.*s",
|
||||
filename->len, filename->str);
|
||||
}
|
||||
|
||||
if (from == NULL) {
|
||||
if (getcwd(cwd, sizeof(cwd)) == NULL) {
|
||||
if (getcwd(buff, sizeof(buff)) == NULL) {
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"call getcwd fail, errno: %d, error info: %s",
|
||||
__LINE__, errno, STRERROR(errno));
|
||||
|
|
@ -3232,32 +3237,35 @@ int normalize_path(const char *from, const char *filename,
|
|||
return 0;
|
||||
}
|
||||
|
||||
path_len = strlen(cwd);
|
||||
if (cwd[path_len - 1] != '/') {
|
||||
if ((path_len + 1) >= sizeof(cwd)) {
|
||||
true_from.str = buff;
|
||||
true_from.len = strlen(buff);
|
||||
if (true_from.str[true_from.len - 1] != '/') {
|
||||
if ((true_from.len + 1) > sizeof(buff)) {
|
||||
logError("file: "__FILE__", line: %d, "
|
||||
"cwd length is too long, exceeds %d",
|
||||
__LINE__, (int)sizeof(cwd));
|
||||
__LINE__, (int)sizeof(buff));
|
||||
*full_filename = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
cwd[path_len] = '/';
|
||||
cwd[path_len + 1] = '\0';
|
||||
true_from.str[true_from.len++] = '/';
|
||||
}
|
||||
from = cwd;
|
||||
} else if (IS_FILE_RESOURCE(from)) {
|
||||
from = from + FILE_RESOURCE_TAG_LEN;
|
||||
from = &true_from;
|
||||
} else if (IS_FILE_RESOURCE_EX(from)) {
|
||||
true_from.str = from->str + FILE_RESOURCE_TAG_LEN;
|
||||
true_from.len = from->len - FILE_RESOURCE_TAG_LEN;
|
||||
from = &true_from;
|
||||
}
|
||||
|
||||
last = strrchr(from, '/');
|
||||
last = fc_memrchr(from->str, '/', from->len);
|
||||
if (last != NULL) {
|
||||
end = filename + strlen(filename);
|
||||
if (memcmp(filename, "./", 2) == 0) {
|
||||
start = filename + 2;
|
||||
end = filename->str + filename->len;
|
||||
if (filename->len >= 2 && memcmp(filename->str, "./", 2) == 0) {
|
||||
start = filename->str + 2;
|
||||
} else {
|
||||
start = filename;
|
||||
start = filename->str;
|
||||
}
|
||||
|
||||
up_count = 0;
|
||||
while (start + 3 < end) {
|
||||
if (memcmp(start, "../", 3) != 0) {
|
||||
|
|
@ -3268,97 +3276,30 @@ int normalize_path(const char *from, const char *filename,
|
|||
start += 3;
|
||||
}
|
||||
|
||||
path_len = last - from;
|
||||
path_len = last - from->str;
|
||||
for (i=0; i<up_count; i++) {
|
||||
last = fc_memrchr(from, '/', path_len);
|
||||
last = fc_memrchr(from->str, '/', path_len);
|
||||
if (last == NULL) {
|
||||
logWarning("file: "__FILE__", line: %d, "
|
||||
"too many ../ in the path resolve filename: %s, "
|
||||
"from filename: %s", __LINE__, filename, from);
|
||||
"too many ../ in the path resolve filename: %.*s, "
|
||||
"from filename: %.*s", __LINE__, filename->len,
|
||||
filename->str, from->len, from->str);
|
||||
break;
|
||||
}
|
||||
path_len = last - from;
|
||||
path_len = last - from->str;
|
||||
}
|
||||
return snprintf(full_filename, size, "%.*s/%s",
|
||||
path_len, from, start);
|
||||
return snprintf(full_filename, size, "%.*s/%.*s",
|
||||
path_len, from->str, (int)(end - start), start);
|
||||
} else {
|
||||
logWarning("file: "__FILE__", line: %d, "
|
||||
"no \"/\" in the from filename: %s",
|
||||
__LINE__, from);
|
||||
return snprintf(full_filename, size, "%s", filename);
|
||||
"no \"/\" in the from filename: %.*s",
|
||||
__LINE__, from->len, from->str);
|
||||
return snprintf(full_filename, size, "%.*s",
|
||||
filename->len, filename->str);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if (memcmp(uri, "./", 2) == 0) {
|
||||
start = uri + 2;
|
||||
} else {
|
||||
start = uri;
|
||||
}
|
||||
up_count = 0;
|
||||
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, start);
|
||||
} 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<keep_count; i++) {
|
||||
len += snprintf(dest + len, size - len,
|
||||
"/%.*s", parts[i].len, parts[i].str);
|
||||
}
|
||||
|
||||
len += snprintf(dest + len, size - len, "/%s", start);
|
||||
return len;
|
||||
}
|
||||
}
|
||||
|
||||
int normalize_path_ex(const char *from, const char *filename,
|
||||
int normalize_path_ex(const string_t *from, const string_t *filename,
|
||||
char *full_filename, const int size, const int flags)
|
||||
{
|
||||
bool is_url_from;
|
||||
|
|
@ -3374,54 +3315,59 @@ int normalize_path_ex(const char *from, const char *filename,
|
|||
return normalize_path(from, filename, full_filename, size);
|
||||
}
|
||||
|
||||
is_url_from = IS_URL_RESOURCE(from);
|
||||
is_url_filename = IS_URL_RESOURCE(filename);
|
||||
is_url_from = IS_URL_RESOURCE_EX(from);
|
||||
is_url_filename = IS_URL_RESOURCE_EX(filename);
|
||||
if (!(is_url_from || is_url_filename)) {
|
||||
return normalize_path(from, filename, full_filename, size);
|
||||
}
|
||||
|
||||
if (IS_FILE_RESOURCE(filename)) {
|
||||
return snprintf(full_filename, size, "%s",
|
||||
filename + FILE_RESOURCE_TAG_LEN);
|
||||
if (IS_FILE_RESOURCE_EX(filename)) {
|
||||
return snprintf(full_filename, size, "%.*s",
|
||||
(int)(filename->len - FILE_RESOURCE_TAG_LEN),
|
||||
filename->str + FILE_RESOURCE_TAG_LEN);
|
||||
}
|
||||
|
||||
if (!is_url_from) {
|
||||
return snprintf(full_filename, size, "%s", filename);
|
||||
return snprintf(full_filename, size, "%.*s",
|
||||
filename->len, filename->str);
|
||||
}
|
||||
|
||||
if (is_url_filename) {
|
||||
full_len = snprintf(full_filename, size, "%s", filename);
|
||||
full_len = snprintf(full_filename, size, "%.*s",
|
||||
filename->len, filename->str);
|
||||
if ((flags & NORMALIZE_FLAGS_URL_APPEND_PARAMS) == 0) {
|
||||
return full_len;
|
||||
}
|
||||
from_ask = strchr(from + 8, '?');
|
||||
from_ask = memchr(from->str + 8, '?', from->len);
|
||||
} else {
|
||||
base_end = strchr(from + 8, '/');
|
||||
base_end = memchr(from->str + 8, '/', from->len);
|
||||
if (base_end == NULL) {
|
||||
return snprintf(full_filename, size, "%s%s%s",
|
||||
from, (*filename == '/' ? "" : "/"), filename);
|
||||
return snprintf(full_filename, size, "%.*s%s%.*s",
|
||||
from->len, from->str, (*filename->str == '/' ?
|
||||
"" : "/"), filename->len, filename->str);
|
||||
}
|
||||
|
||||
base_len = base_end - from;
|
||||
from_ask = strchr(base_end + 1, '?');
|
||||
base_len = base_end - from->str;
|
||||
from_ask = memchr(base_end + 1, '?', from->len - (base_len + 1));
|
||||
from_uri.str = (char *)base_end;
|
||||
if (from_ask == NULL) {
|
||||
from_uri.len = strlen(from_uri.str);
|
||||
from_uri.len = from->len - base_len;
|
||||
} else {
|
||||
from_uri.len = from_ask - from_uri.str;
|
||||
}
|
||||
|
||||
full_len = snprintf(full_filename, size, "%.*s", base_len, from);
|
||||
full_len = normalize_uri(&from_uri, filename,
|
||||
full_len = snprintf(full_filename, size, "%.*s", base_len, from->str);
|
||||
full_len += normalize_path(&from_uri, filename,
|
||||
full_filename + full_len, size - full_len);
|
||||
}
|
||||
|
||||
if ((flags & NORMALIZE_FLAGS_URL_APPEND_PARAMS) != 0) {
|
||||
if (from_ask != NULL) {
|
||||
dest_ask = strchr(filename, '?');
|
||||
dest_ask = memchr(filename->str, '?', filename->len);
|
||||
full_len += snprintf(full_filename + full_len,
|
||||
size - full_len, "%c%s", (dest_ask == NULL ?
|
||||
'?' : '&'), from_ask + 1);
|
||||
size - full_len, "%c%.*s", (dest_ask == NULL ?
|
||||
'?' : '&'), (int)((from->str + from->len) -
|
||||
(from_ask + 1)), from_ask + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,10 +37,6 @@
|
|||
#define NORMALIZE_FLAGS_URL_ENABLED_AND_APPEND_PARAMS \
|
||||
(NORMALIZE_FLAGS_URL_ENABLED | NORMALIZE_FLAGS_URL_APPEND_PARAMS)
|
||||
|
||||
#define resolve_path(from, filename, full_filename, size) \
|
||||
normalize_path_ex(from, filename, full_filename, size, \
|
||||
NORMALIZE_FLAGS_URL_ENABLED_AND_APPEND_PARAMS)
|
||||
|
||||
#define FC_SET_CLOEXEC(fd) \
|
||||
if (g_set_cloexec) fd_set_cloexec(fd)
|
||||
|
||||
|
|
@ -1019,19 +1015,19 @@ char *format_http_date(time_t t, BufferInfo *buffer);
|
|||
* size: the max size of full_filename
|
||||
* return: length of the resolved full path
|
||||
*/
|
||||
int normalize_path(const char *from, const char *filename,
|
||||
int normalize_path(const string_t *from, const string_t *filename,
|
||||
char *full_filename, const int size);
|
||||
|
||||
/** return absolute uri (the second parameter)
|
||||
* parameters:
|
||||
* from: the input uri to get base path
|
||||
* uri: the uri to resolve
|
||||
* dest: store the resolved absolute uri
|
||||
* size: the max size of dest
|
||||
* return: length of the resolved uri
|
||||
*/
|
||||
int normalize_uri(const string_t *from, const char *uri,
|
||||
char *dest, const int size);
|
||||
static inline int normalize_path1(const char *from, const char *filename,
|
||||
char *full_filename, const int size)
|
||||
{
|
||||
string_t from_string;
|
||||
string_t filename_string;
|
||||
|
||||
FC_SET_STRING(from_string, (char *)from);
|
||||
FC_SET_STRING(filename_string, (char *)filename);
|
||||
return normalize_path(&from_string, &filename_string, full_filename, size);
|
||||
}
|
||||
|
||||
/** return full path for the filename (the second parameter)
|
||||
* parameters:
|
||||
|
|
@ -1044,9 +1040,20 @@ int normalize_uri(const string_t *from, const char *uri,
|
|||
* NORMALIZE_FLAGS_URL_APPEND_PARAMS: append params of from
|
||||
* return: length of the resolved full path
|
||||
*/
|
||||
int normalize_path_ex(const char *from, const char *filename,
|
||||
int normalize_path_ex(const string_t *from, const string_t *filename,
|
||||
char *full_filename, const int size, const int flags);
|
||||
|
||||
static inline int resolve_path(const char *from, const char *filename,
|
||||
char *full_filename, const int size)
|
||||
{
|
||||
string_t from_string;
|
||||
string_t filename_string;
|
||||
|
||||
FC_SET_STRING(from_string, (char *)from);
|
||||
FC_SET_STRING(filename_string, (char *)filename);
|
||||
return normalize_path_ex(&from_string, &filename_string, full_filename,
|
||||
size, NORMALIZE_FLAGS_URL_ENABLED_AND_APPEND_PARAMS);
|
||||
}
|
||||
|
||||
/** get gzip command full filename
|
||||
* return: the gzip command full filename
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@
|
|||
int main(int argc, char *argv[])
|
||||
{
|
||||
char full_filename[PATH_MAX];
|
||||
const char *from;
|
||||
const char *filename;
|
||||
string_t from;
|
||||
string_t filename;
|
||||
int filename_len;
|
||||
int result;
|
||||
|
||||
|
|
@ -38,12 +38,14 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
|
||||
log_init();
|
||||
from = argv[1];
|
||||
filename = argv[2];
|
||||
filename_len = normalize_path_ex(from, filename,
|
||||
|
||||
FC_SET_STRING(from, argv[1]);
|
||||
FC_SET_STRING(filename, argv[2]);
|
||||
filename_len = normalize_path_ex(&from, &filename,
|
||||
full_filename, sizeof(full_filename),
|
||||
NORMALIZE_FLAGS_URL_ENABLED_AND_APPEND_PARAMS);
|
||||
printf("%s\n", full_filename);
|
||||
printf("%s => {len1: %d, len2: %d}\n", full_filename,
|
||||
(int)strlen(full_filename), filename_len);
|
||||
|
||||
if (IS_URL_RESOURCE(full_filename)) {
|
||||
const int connect_timeout = 2;
|
||||
|
|
|
|||
Loading…
Reference in New Issue