文章目录
- 一、基础知识
- 二、代码解析
- 1. 载入数据库表
- 2. 提取用户名和密码
- 3. 同步线程登录注册
- 4. 页面跳转
- 参考文献
一、基础知识
二、代码解析
1. 载入数据库表
// 用户名和密码
map<string, string> users;
// 初始化数据库
void http_conn::initmysql_result(connection_pool *connPool)
{
// 先从连接池中取一个连接
MYSQL *mysql = NULL;
connectionRAII mysqlcon(&mysql, connPool);
// 在user表中检索username,passwd数据,浏览器端输入
if (mysql_query(mysql, "SELECT username, passwd FROM user"))
{
LOG_ERROR("SELECT error: %s\n", mysql_error(mysql));
}
// 从表中检索完整的结果集
MYSQL_RES *result = mysql_store_result(mysql);
// 返回结果集中的列数
int num_fields = mysql_num_fields(result);
// 返回所有字段结构的数组
MYSQL_FIELD *fields = mysql_fetch_fields(result);
// 从结果集中获取下一行,将对应的用户名和密码,存入map中
while (MYSQL_ROW row = mysql_fetch_row(result))
{
string temp1(row[0]);
string temp2(row[1]);
users[temp1] = temp2;
}
}
2. 提取用户名和密码
// 主状态机,判断http请求是否被完整读入
http_conn::HTTP_CODE http_conn::parse_content(char *text)
{
// 判断buffer中是否读取了消息体
if (m_read_idx >= (m_content_length + m_checked_idx))
{
// 标记已读完的部分
text[m_content_length] = '\0';
// POST请求中最后为输入的用户名和密码
m_string = text;
// 还需读取请求
return GET_REQUEST;
}
return NO_REQUEST;
}
// 根据标志判断是登录检测还是注册检测,即/符号后的第一位
char flag = m_url[1];
// 申请url空间
char *m_url_real = (char *)malloc(sizeof(char) * 200);
// 存入/
strcpy(m_url_real, "/");
// 存入/后的第二位之后的url
strcat(m_url_real, m_url + 2);
// 文件存储区在文件路径之后存入真实url
strncpy(m_real_file + len, m_url_real, FILENAME_LEN - len - 1);
// 释放真实url存储空间
free(m_url_real);
// 将用户名和密码提取出来
// user=123&passwd=123
char name[100], password[100];
int i;
for (i = 5; m_string[i] != '&'; ++i)
name[i - 5] = m_string[i];
name[i - 5] = '\0';
int j = 0;
for (i = i + 10; m_string[i] != '\0'; ++i, ++j)
password[j] = m_string[i];
password[j] = '\0';
3. 同步线程登录注册
if (cgi == 1 && (*(p + 1) == '2' || *(p + 1) == '3'))
{
if (*(p + 1) == '3')
{
// 如果是注册,先检测数据库中是否有重名的
// 没有重名的,进行增加数据
char *sql_insert = (char *)malloc(sizeof(char) * 200);
strcpy(sql_insert, "INSERT INTO user(username, passwd) VALUES(");
strcat(sql_insert, "'");
strcat(sql_insert, name);
strcat(sql_insert, "', '");
strcat(sql_insert, password);
strcat(sql_insert, "')");
// 没找到则insert数据
if (users.find(name) == users.end())
{
m_lock.lock();
int res = mysql_query(mysql, sql_insert);
users.insert(pair<string, string>(name, password));
m_lock.unlock();
if (!res)
strcpy(m_url, "/log.html");
else
strcpy(m_url, "/registerError.html");
}
else
strcpy(m_url, "/registerError.html");
}
// 如果是登录,直接判断
// 若浏览器端输入的用户名和密码在表中可以查找到,返回1,否则返回0
else if (*(p + 1) == '2')
{
if (users.find(name) != users.end() && users[name] == password)
strcpy(m_url, "/welcome.html");
else
strcpy(m_url, "/logError.html");
}
}
4. 页面跳转
// 如果请求资源为/0,表示跳转注册界面
if (*(p + 1) == '0')
{
char *m_url_real = (char *)malloc(sizeof(char) * 200);
strcpy(m_url_real, "/register.html");
strncpy(m_real_file + len, m_url_real, strlen(m_url_real));
free(m_url_real);
}
// 如果请求资源为/1,表示跳转登录界面
else if (*(p + 1) == '1')
{
char *m_url_real = (char *)malloc(sizeof(char) * 200);
strcpy(m_url_real, "/log.html");
strncpy(m_real_file + len, m_url_real, strlen(m_url_real));
free(m_url_real);
}
// 指向图片页面
else if (*(p + 1) == '5')
{
char *m_url_real = (char *)malloc(sizeof(char) * 200);
strcpy(m_url_real, "/picture.html");
strncpy(m_real_file + len, m_url_real, strlen(m_url_real));
free(m_url_real);
}
// 指向视频页面
else if (*(p + 1) == '6')
{
char *m_url_real = (char *)malloc(sizeof(char) * 200);
strcpy(m_url_real, "/video.html");
strncpy(m_real_file + len, m_url_real, strlen(m_url_real));
free(m_url_real);
}
// 指向粉丝页面
else if (*(p + 1) == '7')
{
char *m_url_real = (char *)malloc(sizeof(char) * 200);
strcpy(m_url_real, "/fans.html");
strncpy(m_real_file + len, m_url_real, strlen(m_url_real));
free(m_url_real);
}
// 指向原始路径
else
strncpy(m_real_file + len, m_url, FILENAME_LEN - len - 1);
参考文献
[1] 最新版Web服务器项目详解 - 12 注册登录