简单记录使用mongoose上传文件的使用过程。
-
查看mongoose源码,源码中有默认的处理方式,先看
默认处理方式
吧。
* void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
* switch (ev) {
* case MG_EV_HTTP_MULTIPART_REQUEST:
* {
* // 协议解析
* break;
* }
* case MG_EV_HTTP_PART_BEGIN:
* case MG_EV_HTTP_PART_DATA:
* case MG_EV_HTTP_PART_END:
* mg_file_upload_handler(nc, ev, ev_data, upload_fname);
* break;
* }
* }
上面代码部分来自于mongoose源码摘要
-
mongoose允许用户
自己创建特定协议类型的handler
,去处理请求过程。
#define MG_F_HAS_ERROR MG_F_USER_1 //上传文件的过程中,如果出现错误,设置该标志。
void myHandler(mg_connection* nc, const int ev, void* data)
{
switch(ev)
{
case MG_EV_HTTP_REQUEST:
{
//request no body的情况
...
break;
}
case MG_EV_HTTP_MULTIPART_REQUEST:
{
try
{
//协议解析
}
catch(const std::invalid_argument& e)
{
nc->flags |= MG_F_HAS_ERROR;
}
break;
}
case MG_EV_HTTP_PART_BEGIN:
{
if(nc->flags & MG_F_HAS_ERROR)
break;
try
{
auto mp = (struct mg_http_multipart_part*)data;
//...
}
catch(const std::invalid_argument& e)
{
nc->falgs |= MG_F_HAS_ERROR;
}
break;
}
case MG_EV_HTTP_PART_DATA:
{
if(nc->flags & MG_F_HAS_ERROR)
break;
auto mp = (struct mg_http_multipart_part *) data;
//...
break;
}
case MG_EV_HTTP_PART_END:
{
//注:MULTIPART_REQUEST、BEGIN、DATA过程中出现错误的话,
//会在END的阶段设置MG_F_SEND_AND_CLOSE,发送close
if(nc->falgs & MG_F_HAS_ERROR)
{
nc->flags |= MG_F_SEND_AND_CLOSE;
break;
}
auto mp = (struct mg_http_multipart_part *) data;
if(mp->status < 0)//上传文件的过程中如果客户端主动关闭,status属性会被设为-1。
{
//...
break;
}
break;
}
}
//写个函数调用上面的handler
void main()
{
mg_mgr mgr;
mg_mgr_init(&mgr, /*void* user_Data*/);
const auto connection = mg_bind(&mgr, listenPort.c_str(), (mg_event_handler_t)errorProtocolHandler);
if(connection)
{
mg_set_protocol_http_websocket(connection);
mg_register_http_endpoint(connection, "/myHandler", myHandler);
}
}
画个mongoose上传流程图巩固下:
mongoose的
错误处理策略
:
mongoose上传文件的过程中不能主动断开停止接受文件。当上传出现错误时,前端要想拿到reponse的话得等到END阶段。
版权声明:本文为W96866原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。