整体概述
本项目中,使用数据库连接池实现服务器访问数据库的功能,使用POST请求完成注册和登录的校验工作。
本文内容
本篇将介绍同步实现注册登录功能,具体的涉及到流程图,载入数据库表,提取用户名和密码,注册登录流程与页面跳转的的代码实现。
流程图
具体的,描述了GET和POST请求下的页面跳转流程。
载入数据库表
将数据库中的用户名和密码载入到服务器的map中来,map中的key为用户名,value为密码。
//用户名和密码
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(
);
//返回所有字段结构的数组
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;
}
}
提取用户名和密码
服务器端解析浏览器的请求报文,当解析为POST请求时,cgi标志位设置为1,并将请求报文的消息体赋值给m_string,进而提取出用户名和密码。
//判断http请求是否被完整读入
http_conn::HTTP_CODE http_conn::parse_content(char *text)
{
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];
char *m_url_real = (char *)malloc(sizeof(char) * 200);
strcpy(m_url_real, "/");
strcat(m_url_real, m_url + 2);
strncpy(m_real_file + len, m_url_real, FILENAME_LEN - len - 1);
free(m_url_real);
//将用户名和密码提取出来
//user=123&password=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';
同步线程登录注册
通过m_url定位/所在位置,根据/后的第一个字符判断是登录还是注册校验。
- 2
- 登录校验
- 3
- 注册校验
根据校验结果,跳转对应页面。另外,对数据库进行操作时,需要通过锁来同步。
const char *p = strrchr(m_url, '/');
if (0 == m_SQLVerify)
{
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, "')");
//判断map中能否找到重复的用户名
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");
}
}
页面跳转
通过m_url定位/所在位置,根据/后的第一个字符,使用分支语句实现页面跳转。具体的,
- 0
- 跳转注册页面,GET
- 1
- 跳转登录页面,GET
- 5
- 显示图片页面,POST
- 6
- 显示视频页面,POST
- 7
- 显示关注页面,POST
//找到url中/所在位置,进而判断/后第一个字符
const char *p = strrchr(m_url, '/');
//注册页面
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);
}
//登录页面
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);
}
//否则发送url实际请求的文件
else
strncpy(m_real_file + len, m_url, FILENAME_LEN - len - 1);
转载文章:
最新版Web服务器项目详解 - 12 注册登录 (qq.com)
标签:real,12,登录,url,TinyWebServer,char,strcpy,mysql,页面 From: https://www.cnblogs.com/Wangzx000/p/17745040.html