worker.c: In function 'worker_file_log_read_handle':
worker.c:3851:9: error: unused variable 'limit' [-Werror=unused-variable]
3851 | int limit = limit_str ? atoi(limit_str) : 100;
| ^~~~~
worker.c:3790:11: error: unused variable 'end_time' [-Werror=unused-variable]
3790 | char *end_time = common_find_key_from_buf(buf, "End-Time");
| ^~~~~~~~
worker.c:3789:11: error: unused variable 'start_time' [-Werror=unused-variable]
3789 | char *start_time = common_find_key_from_buf(buf, "Start-Time");
| ^~~~~~~~~~
worker.c:3842:5: error: 'strncpy' output may be truncated copying 255 bytes from a string of length 255 [-Werror=stringop-truncation]
3842 | strncpy(session->filepath, filepath, sizeof(session->filepath)-1);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
// 日志读取处理函数
bool worker_file_log_read_handle(WORKER_CTX *worker_ctx, struct tpsocket_fd *sock, struct list_head *buf)
{
// 1. 解析查询参数
char *mac = common_find_key_from_buf(buf, "Device-Mac");
char *offset_str = common_find_key_from_buf(buf, "Offset");
char *limit_str = common_find_key_from_buf(buf, "Limit");
char *start_time = common_find_key_from_buf(buf, "Start-Time");
char *end_time = common_find_key_from_buf(buf, "End-Time");
char *follow = common_find_key_from_buf(buf, "Follow");
// 2. MAC验证和格式化
if (!mac || strlen(mac) < 12) {
DBG_ERR("Invalid MAC address\n");
const char *resp = "HTTP/1.1 400 Bad Request\r\n\r\n";
struct tpsocket_buf *resp_buf = tpbuf_snprintf(strlen(resp)+1, resp);
if (resp_buf) tpsocket_write(sock, resp_buf);
return false;
}
char processed_mac[18] = {0};
strncpy(processed_mac, mac, sizeof(processed_mac)-1);
for (char *p = processed_mac; *p; p++) if (*p == ':') *p = '_';
// 3. 构建日志文件路径
char filepath[256];
snprintf(filepath, sizeof(filepath), "%s/%s/log.txt", FILELOG_PATH, processed_mac);
// 4. 检查文件是否存在
if (access(filepath, F_OK) != 0) {
DBG_ERR("Log file not found: %s\n", filepath);
const char *resp = "HTTP/1.1 404 Not Found\r\n\r\n";
struct tpsocket_buf *resp_buf = tpbuf_snprintf(strlen(resp)+1, resp);
if (resp_buf) tpsocket_write(sock, resp_buf);
return false;
}
// 5. 打开日志文件
FILE *fp = fopen(filepath, "r");
if (!fp) {
DBG_ERR("Failed to open log file: %s\n", strerror(errno));
const char *resp = "HTTP/1.1 500 Internal Error\r\n\r\n";
struct tpsocket_buf *resp_buf = tpbuf_snprintf(strlen(resp)+1, resp);
if (resp_buf) tpsocket_write(sock, resp_buf);
return false;
}
// 6. 创建读取会话
LogReadSession *session = calloc(1, sizeof(LogReadSession));
if (!session) {
fclose(fp);
const char *resp = "HTTP/1.1 507 Insufficient Storage\r\n\r\n";
struct tpsocket_buf *resp_buf = tpbuf_snprintf(strlen(resp)+1, resp);
if (resp_buf) tpsocket_write(sock, resp_buf);
return false;
}
session->fp = fp;
session->follow_mode = (follow && strcmp(follow, "true") == 0);
strncpy(session->mac, mac, sizeof(session->mac)-1);
strncpy(session->filepath, filepath, sizeof(session->filepath)-1);
// 获取文件状态
struct stat st;
fstat(fileno(fp), &st);
session->last_modified = st.st_mtime;
// 7. 设置初始读取位置
int offset = offset_str ? atoi(offset_str) : 0;
int limit = limit_str ? atoi(limit_str) : 100;
if (offset > 0) {
// 跳过指定行数
char buf[1024];
int lines_skipped = 0;
while (fgets(buf, sizeof(buf), fp) && lines_skipped < offset) {
lines_skipped++;
}
}
session->current_offset = ftell(fp);
session->sent_bytes = 0;
// 8. 设置回调和私有数据
sock->handler.cb = tpsocket_event_log_read_handler;
sock->handler.priv = session;
// 9. 发送HTTP响应头
if (session->follow_mode) {
// 实时监控模式 - SSE流
const char *header = "HTTP/1.1 200 OK\r\n"
"Content-Type: text/event-stream\r\n"
"Connection: keep-alive\r\n"
"Cache-Control: no-cache\r\n\r\n";
struct tpsocket_buf *header_buf = tpbuf_snprintf(strlen(header)+1, header);
if (header_buf) tpsocket_write(sock, header_buf);
DBG_ERR("Started live log monitor for %s\n", mac);
} else {
// 普通查询模式
const char *header = "HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Transfer-Encoding: chunked\r\n\r\n";
struct tpsocket_buf *header_buf = tpbuf_snprintf(strlen(header)+1, header);
if (header_buf) tpsocket_write(sock, header_buf);
// 立即触发数据推送
struct list_head dummy_buf;
INIT_LIST_HEAD(&dummy_buf);
tpsocket_event_log_read_handler(&sock->handler, &dummy_buf, TPSOCKET_EVENT_WRITABLE);
}
return true;
}// 日志读取回调处理函数
bool tpsocket_event_log_read_handler(struct tpsocket_handler *handler, struct list_head *buf, int event)
{
struct tpsocket_fd *sock = container_of(handler, struct tpsocket_fd, handler);
LogReadSession *session = handler->priv;
if (event != TPSOCKET_EVENT_STREAM) {
DBG_ERR("sock=%p, event=%s\n", sock, tpsocket_event_name(event));
}
if (!session || !session->fp) {
DBG_ERR("Invalid log read session\n");
return false;
}
switch (event) {
case TPSOCKET_EVENT_LISTEN:
DBG_ERR("TPSOCKET_EVENT_LISTEN: %s:%s Listen\n", sock->addr, sock->port);
break;
case TPSOCKET_EVENT_SHUTDOWN:
DBG_ERR("TPSOCKET_EVENT_LISTEN: %s:%s Shutdown\n", sock->addr, sock->port);
break;
case TPSOCKET_EVENT_ACCEPT:
DBG_ERR("TPSOCKET_EVENT_LISTEN: %s:%s Accepted\n", sock->addr, sock->port);
break;
case TPSOCKET_EVENT_CONNECTED:
DBG_ERR("TPSOCKET_EVENT_LISTEN: %s:%s connected\n", sock->addr, sock->port);
break;
case TPSOCKET_EVENT_REQ_HEAD:
DBG_ERR("TPSOCKET_EVENT_LISTEN: %s Requested path: %s\n", sock->path, sock->parser.http.url);
break;
case TPSOCKET_EVENT_RSP_HEAD:
break;
case TPSOCKET_EVENT_SUB_HEAD:
DBG_ERR("TPSOCKET_EVENT_LISTEN: %s:%s connected\n", sock->addr, sock->port);
break;
case TPSOCKET_EVENT_UPGRADE:
break;
case TPSOCKET_EVENT_WRITABLE:
// 可写事件 - 推送日志数据
send_log_data(sock, session);
break;
case TPSOCKET_EVENT_STREAM:
// 非实时模式完成处理
if (!session->follow_mode) {
// 发送结束标识
const char *end_chunk = "0\r\n\r\n";
struct tpsocket_buf *end_buf= tpbuf_snprintf(strlen(end_chunk)+1, end_chunk);
if (end_buf) tpsocket_write(sock, end_buf);
// 关闭连接
tpsocket_close(sock);
}
break;
case TPSOCKET_EVENT_RESET:
break;
case TPSOCKET_EVENT_TIMEOUT:
break;
case TPSOCKET_EVENT_CLOSED:
// 连接关闭或错误 - 清理资源
DBG_ERR("Log read session closed for %s\n", session->mac);
if (session->fp) fclose(session->fp);
free(session);
handler->priv = NULL;
break;
case TPSOCKET_EVENT_ERROR:
default:
break;
}
tpsocket_free_buf(buf, tpsocket_event_name(event), 0);
return true;
}