Lighttpd基础篇(一):Array.c

//作者:京东瀚览家居官方旗舰店     <--点击关注

//文件名:Array.c

 

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

#include <errno.h>
#include <assert.h>

#include "array.h"
#include "buffer.h"

/* 创建并初始化一个array 数据结构体*/
array *array_init(void) {
	array *a;

	a = calloc(1, sizeof(*a));
	assert(a);

	a->next_power_of_2 = 1;

	return a;
}

/*  拷贝一个指定的array  结构体变量 , 并返回其副本*/
array *array_init_array(array *src) {
	size_t i;
	array *a = array_init();

	a->used = src->used;
	a->size = src->size;
	a->next_power_of_2 = src->next_power_of_2;
	a->unique_ndx = src->unique_ndx;

	a->data = malloc(sizeof(*src->data) * src->size);
	for (i = 0; i < src->size; i++) { /* copy  函数指向data_xxxxx_copy 函数*/
		if (src->data[i]) a->data[i] = src->data[i]->copy(src->data[i]);
		else a->data[i] = NULL;
	}

	a->sorted = malloc(sizeof(*src->sorted)   * src->size);
	memcpy(a->sorted, src->sorted, sizeof(*src->sorted)   * src->size);
	return a;
}

/* 释放array 结构体	*/
void array_free(array *a) {
	size_t i;
	if (!a) return;

      /* 如果数据不是其他数据的引用(即该数据是否被独占)  ,*/
     /*   则释放*/
	if (!a->is_weakref) {
		for (i = 0; i < a->size; i++) {/* free 函数指向data_xxxxx_free 函数*/
			if (a->data[i]) a->data[i]->free(a->data[i]);
		}
	}

	if (a->data) free(a->data);
	if (a->sorted) free(a->sorted);

	free(a);
}

/* 重置array 结构体*/
void array_reset(array *a) {
	size_t i;
	if (!a) return;

/* 如果数据是独占的, 则调用重置函数*/
	if (!a->is_weakref) {
		for (i = 0; i < a->used; i++) {
			a->data[i]->reset(a->data[i]);
		}
	}

	a->used = 0;
}

/* 弹出并返回数组的最后一个元素*/
data_unset *array_pop(array *a) {
	data_unset *du;

	assert(a->used != 0);

	a->used --;
	du = a->data[a->used];
	a->data[a->used] = NULL;

	return du;
}

/* 以关键字key 的前keylen 的数据在array 中查找*/
/*  返回数据在array 中的下标,同时将此下标在sorted 的索引,*/
/*  通过 rndx 返回*/
/* 若查找不成功 rndx 和ndx 的值都为-1 */
static int array_get_index(array *a, const char *key, size_t keylen, int *rndx) {
	int ndx = -1;
	int i, pos = 0;

	if (key == NULL) return -1;

	/* try to find the string */
	for (i = pos = a->next_power_of_2 / 2; ; i >>= 1) {
		int cmp;

		if (pos < 0) {
			pos += i;
		} else if (pos >= (int)a->used) {
			pos -= i;
		} else {
			cmp = buffer_caseless_compare(key, keylen, a->data[a->sorted[pos]]->key->ptr, a->data[a->sorted[pos]]->key->used);

			if (cmp == 0) {
				/* found */
				ndx = a->sorted[pos];
				break;
			} else if (cmp < 0) {
				pos -= i;
			} else {
				pos += i;
			}
		}
		if (i == 0) break;
	}

	if (rndx) *rndx = pos;

	return ndx;
}

/* 在array中获取给定key 的元素*/
data_unset *array_get_element(array *a, const char *key) {
	int ndx;

	if (-1 != (ndx = array_get_index(a, key, strlen(key) + 1, NULL))) {
		/* found, leave here */

		return a->data[ndx];
	}

	return NULL;
}

/* 获得一个未使用的data 元素*/
data_unset *array_get_unused_element(array *a, data_type_t t) {
	data_unset *ds = NULL;

	UNUSED(t);

	if (a->size == 0) return NULL;

	if (a->used == a->size) return NULL;

	if (a->data[a->used]) {
		ds = a->data[a->used];

		a->data[a->used] = NULL;
	}

	return ds;
}

/* replace or insert data, return the old one with the same key */
data_unset *array_replace(array *a, data_unset *du) {
	int ndx;

	if (-1 == (ndx = array_get_index(a, du->key->ptr, du->key->used, NULL))) {
		array_insert_unique(a, du);
		return NULL;
	} else {
		data_unset *old = a->data[ndx];
		a->data[ndx] = du;
		return old;
	}
}

int array_insert_unique(array *a, data_unset *str) {
	int ndx = -1;
	int pos = 0;
	size_t j;

	/* generate unique index if neccesary */
	if (str->key->used == 0 || str->is_index_key) {
		buffer_copy_long(str->key, a->unique_ndx++);
		str->is_index_key = 1;
	}

	/* try to find the string */
	if (-1 != (ndx = array_get_index(a, str->key->ptr, str->key->used, &pos))) {
		/* found, leave here */
		if (a->data[ndx]->type == str->type) {
			str->insert_dup(a->data[ndx], str);
		} else {
			fprintf(stderr, "a\n");
		}
		return 0;
	}

	/* insert */

	if (a->used+1 > INT_MAX) {
		/* we can't handle more then INT_MAX entries: see array_get_index() */
		return -1;
	}

	if (a->size == 0) {
		a->size   = 16;
		a->data   = malloc(sizeof(*a->data)     * a->size);
		a->sorted = malloc(sizeof(*a->sorted)   * a->size);
		assert(a->data);
		assert(a->sorted);
		for (j = a->used; j < a->size; j++) a->data[j] = NULL;
	} else if (a->size == a->used) {
		a->size  += 16;
		a->data   = realloc(a->data,   sizeof(*a->data)   * a->size);
		a->sorted = realloc(a->sorted, sizeof(*a->sorted) * a->size);
		assert(a->data);
		assert(a->sorted);
		for (j = a->used; j < a->size; j++) a->data[j] = NULL;
	}

	ndx = (int) a->used;

	a->data[a->used++] = str;

	if (pos != ndx &&
	    ((pos < 0) ||
	     buffer_caseless_compare(str->key->ptr, str->key->used, a->data[a->sorted[pos]]->key->ptr, a->data[a->sorted[pos]]->key->used) > 0)) {
		pos++;
	}

	/* move everything on step to the right */
	if (pos != ndx) {
		memmove(a->sorted + (pos + 1), a->sorted + (pos), (ndx - pos) * sizeof(*a->sorted));
	}

	/* insert */
	a->sorted[pos] = ndx;

	if (a->next_power_of_2 == (size_t)ndx) a->next_power_of_2 <<= 1;

	return 0;
}


/* 按需打印空格*/
void array_print_indent(int depth) {
	int i;
	for (i = 0; i < depth; i ++) {
		fprintf(stdout, "    ");
	}
}

/* 获取数据元素array *a 中key 的最长长度*/
size_t array_get_max_key_length(array *a) {
	size_t maxlen, i;

	maxlen = 0;
	for (i = 0; i < a->used; i ++) {
		data_unset *du = a->data[i];
		size_t len = strlen(du->key->ptr);

		if (len > maxlen) {
			maxlen = len;
		}
	}
	return maxlen;
}

/*  打印array */
int array_print(array *a, int depth) {
	size_t i;
	size_t maxlen;
	int oneline = 1;

	if (a->used > 5) {
		oneline = 0;
	}
	for (i = 0; i < a->used && oneline; i++) {
		data_unset *du = a->data[i];
		if (!du->is_index_key) {
			oneline = 0;
			break;
		}
		switch (du->type) {
			case TYPE_INTEGER:
			case TYPE_STRING:
			case TYPE_COUNT:
				break;
			default:
				oneline = 0;
				break;
		}
	}
	if (oneline) {
		fprintf(stdout, "(");
		for (i = 0; i < a->used; i++) {
			data_unset *du = a->data[i];
			if (i != 0) {
				fprintf(stdout, ", ");
			}
			du->print(du, depth + 1);
		}
		fprintf(stdout, ")");
		return 0;
	}

	maxlen = array_get_max_key_length(a);
	fprintf(stdout, "(\n");
	for (i = 0; i < a->used; i++) {
		data_unset *du = a->data[i];
		array_print_indent(depth + 1);
		if (!du->is_index_key) {
			int j;

			if (i && (i % 5) == 0) {
				fprintf(stdout, "# %zd\n", i);
				array_print_indent(depth + 1);
			}
			fprintf(stdout, "\"%s\"", du->key->ptr);
			for (j = maxlen - strlen(du->key->ptr); j > 0; j --) {
				fprintf(stdout, " ");
			}
			fprintf(stdout, " => ");
		}
		du->print(du, depth + 1);
		fprintf(stdout, ",\n");
	}
	if (!(i && (i - 1 % 5) == 0)) {
		array_print_indent(depth + 1);
		fprintf(stdout, "# %zd\n", i);
	}
	array_print_indent(depth);
	fprintf(stdout, ")");

	return 0;
}

#ifdef DEBUG_ARRAY
int main (int argc, char **argv) {
	array *a;
	data_string *ds;
	data_count *dc;

	UNUSED(argc);
	UNUSED(argv);

	a = array_init();

	ds = data_string_init();
	buffer_copy_string_len(ds->key, CONST_STR_LEN("abc"));
	buffer_copy_string_len(ds->value, CONST_STR_LEN("alfrag"));

	array_insert_unique(a, (data_unset *)ds);

	ds = data_string_init();
	buffer_copy_string_len(ds->key, CONST_STR_LEN("abc"));
	buffer_copy_string_len(ds->value, CONST_STR_LEN("hameplman"));

	array_insert_unique(a, (data_unset *)ds);

	ds = data_string_init();
	buffer_copy_string_len(ds->key, CONST_STR_LEN("123"));
	buffer_copy_string_len(ds->value, CONST_STR_LEN("alfrag"));

	array_insert_unique(a, (data_unset *)ds);

	dc = data_count_init();
	buffer_copy_string_len(dc->key, CONST_STR_LEN("def"));

	array_insert_unique(a, (data_unset *)dc);

	dc = data_count_init();
	buffer_copy_string_len(dc->key, CONST_STR_LEN("def"));

	array_insert_unique(a, (data_unset *)dc);

	array_print(a, 0);

	array_free(a);

	fprintf(stderr, "%d\n",
	       buffer_caseless_compare(CONST_STR_LEN("Content-Type"), CONST_STR_LEN("Content-type")));

	return 0;
}
#endif

 

<think>好的,我需要分析用户提供的lighttpd服务器日志,帮助用户理解这些日志的含义以及可能存在的问题。首先,用户给出的日志包含了服务器停止、启动以及些配置相关的警告信息。我需要逐解析每个条目,解释它们的意义,并给出相应的解决方案建议。 首先,用户的问题是关于这些日志消息的,所以我需要先分解每条日志,指出关键点。例如,第行显示服务器被UID 0和PID 4759停止,这可能涉及到使用root用户执行了停止操作。然后服务器启动,版本是1.4.67。接下来是几个关于mod_deflate模块的DEPRECATED警告,说明配置中使用了过时的指令,需要替换为新的指令名称。然后是几个未知配置键的警告,可能是配置文件中存在错误或过时的认证配置。 我需要确保解释清晰,每个警告或错误的原因和可能的解决方法。对于DEPRECATED的提示,用户需要更新配置文件中的旧指令,比如将compress.filetype改为deflate.mimetypes。对于未知的配置键auth.debug等,需要检查认证相关的配置是否正确,是否使用了过时的模块或配置方式。另外,可能涉及到auth模块未被正确加载或者配置格式错误的情况。 还要提醒用户检查lighttpd的文档,确认当前版本的配置语法,确保所有配置项都是有效的。此外,建议用户逐步排查配置问题,可以先注释掉有问题的配置行,逐步测试,或者查看是否有拼写错误。 需要确保回答结构清晰,分步骤说明问题,可能的原因和解决方法。同时,使用中文,避免专业术语过于复杂,保持易懂。另外,注意系统级指令中提到的数学表达式格式,但当前问题不涉及数学公式,所以可能不需要使用。但如果有需要的地方,比如举例时,要正确应用格式。 最后,总结问题,强调检查配置更新和模块加载的重要性,确保服务器配置符合当前版本的要求。可能还需要提醒用户备份配置文件再进行修改,避免服务不可用。</think>以下是您提供的lighttpd服务器日志的逐行解析及问题诊断: --- ### **1. 服务器停止记录** `2025-03-21 10:58:28: (server.c.2097) server stopped by UID = 0 PID = 4759` - **含义**:服务器被系统用户`UID=0`(root用户)通过进程`PID=4759`主动终止。 - **可能原因**:管理员手动执行关闭命令(如`lighttpd -k stop`)或系统服务重启。 --- ### **2. 服务器启动记录** `2025-03-21 10:58:31: (server.c.1588) server started (lighttpd/1.4.67)` - **含义**:服务器成功重启,版本为`1.4.67`。 - **注意**:当前版本较旧(截至2023年最新版本为1.4.71),建议检查更新以修复潜在漏洞。 --- ### **3. 配置废弃警告** 以下三行提示`mod_deflate`模块的旧配置语法已被弃用: ```log 2025-03-21 10:58:31: (mod_deflate.c.740) DEPRECATED: compress.filetype replaced with deflate.mimetypes 2025-03-21 10:58:31: (mod_deflate.c.761) DEPRECATED: compress.allowed-encodings replaced with deflate.allowed-encodings 2025-03-21 10:58:31: (mod_deflate.c.803) DEPRECATED: compress.cache-dir replaced with deflate.cache-dir ``` - **问题**:配置文件中使用了旧版参数名称(如`compress.filetype`),需替换为新名称(如`deflate.mimetypes`)。 - **解决方法**: 修改`lighttpd.conf`文件,将`compress.`前缀的配置项替换为`deflate.`前缀。例如: ```conf deflate.mimetypes = ("text/", "application/json") deflate.allowed-encodings = ("gzip", "br") ``` --- ### **4. 未知配置项警告** 以下四行提示配置文件中存在无效的`auth`相关配置: ```log 2025-03-21 10:58:31: (configfile.c.1287) WARNING: unknown config-key: auth.debug (ignored) 2025-03-21 10:58:31: (configfile.c.1287) WARNING: unknown config-key: auth.backend (ignored) 2025-03-21 10:58:31: (configfile.c.1287) WARNING: unknown config-key: auth.backend.plain.userfile (ignored) 2025-03-21 10:58:31: (configfile.c.1287) WARNING: unknown config-key: auth.require (ignored) ``` - **原因**: - 旧版`mod_auth`模块的配置语法已过时(例如`auth.backend`)。 - 当前版本可能未加载`mod_auth`模块,或使用了错误的认证后端(如`auth.backend.plain`)。 - **解决方法**: 1. **检查模块加载**:确保配置中包含`server.modules += ("mod_auth")`。 2. **更新认证配置**:使用新版语法,例如: ```conf auth.backend = "plain" auth.backend.plain.userfile = "/path/to/users" auth.require = ( "/protected" => ("method" => "basic", "realm" => "private") ) ``` 3. **替换为`mod_authn_file`**:若仍无效,建议改用`mod_authn_file`模块(需参考官方文档更新语法)。 --- ### **总结与建议** 1. **更新配置文件**:替换所有废弃的`compress.*`为`deflate.*`。 2. **检查认证模块**:确认`mod_auth`已加载且配置符合新版语法。 3. **升级lighttpd版本**:从官方源获取最新版本以修复兼容性问题。 4. **验证配置文件**:使用命令`lighttpd -t -f /path/to/lighttpd.conf`测试配置语法。 通过以上调整,可消除日志中的警告并确保服务器稳定运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值