Files
domo-iot/src/web/web-server.cpp

162 lines
5.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*!
* web-server.cpp
*
* Copyright (c) 2015-2019, NADAL Jean-Baptiste. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*
* @Author: NADAL Jean-Baptiste
* @Date: 13/11/2019
*
*/
// This is an independent project of an individual developer. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com
/*------------------------------- INCLUDES ----------------------------------*/
#include <string.h>
#include "web-server.h"
//404前回调(未找到页面/文件时回调,此功能便于程序返回自定义功能)返回0表示没有适合的处理请求需要发送404错误
char on_request(void* data, uv_stream_t* client, tw_peerAddr* pa, tw_reqHeads* heads)
{
// struct sockaddr_in serveraddr, peeraddr;
// char serv_ip[17],peer_ip[17], tmp[1024];
// int addrlen = sizeof(struct sockaddr);
// int r;
//
// //获取clientAddr: http://www.codes51.com/article/detail_113112.html
// //本地接入地址
// r = uv_tcp_getsockname((uv_tcp_t*)client, (struct sockaddr*)&serveraddr, &addrlen);
// //网络字节序转换成主机字符序
// uv_ip4_name(&serveraddr, (char*)serv_ip, sizeof(serv_ip));
// //客户端的地址
// r = uv_tcp_getpeername((uv_tcp_t*)client, (struct sockaddr*)&peeraddr, &addrlen);
// //网络字节序转换成主机字符序
// uv_ip4_name(&peeraddr, (char*)peer_ip, sizeof(peer_ip));
//
// sprintf(tmp, "<h1>Page not found:</h1><url>%s<br>%s<br></url><br><br><br><i>server%s:%d\t\tpeer%s:%d</i>\n", heads->path, (heads->query?heads->query:""), serv_ip, ntohs(serveraddr.sin_port), peer_ip, ntohs(peeraddr.sin_port));
//#ifdef _MSC_VER //Windows下需要转换编码
// size_t ll = strlen(tmp);
// char *ch = GB2U8(tmp, &ll);
// tw_send_200_OK(client, "text/html", ch, -1, 0);
// free(ch);
//#else //linux 下系统是和源代码文件编码都是是utf8的就不需要转换
// tw_send_200_OK(client, "text/html", tmp, -1, 0);
//#endif // _MSC_VER
//
printf(" sk:%zd Request:\n",pa->sk);
printf(" Query: %s\n",heads->query);
printf(" Path: %s\n",heads->path);
printf(" Host: %s\n",heads->host);
printf(" Cookie: %s\n", heads->cookie);
printf(" Range: %lld-%lld\n",heads->Range_frm,heads->Range_to);
printf(" data(%zd): %s\n", heads->len,heads->data);
if (!heads->cookie)
{
char ck[512];
tw_make_setcookie(ck, 255,"TINYSSID","FDSAFdfafdsafds", 3600 * 8, NULL, heads->path);
tw_make_setcookie(ck + strlen(ck),255,"TINYSSID2","faFDSAF45dsafds", 0, heads->host, NULL);
sprintf(ck + strlen(ck), "WWW-Authenticate: Basic realm=\".\"\r\n");
size_t len;
char* rp = tw_format_http_respone(client, "401 Unauthorized", ck, "text/plan", "", -1, &len);
tw_send_data(client, rp, len, 0, 1);
return 1;
}
return 0;
}
char on_socket_data(void* data, uv_stream_t* client, tw_peerAddr* pa, membuf_t* buf)
{
if (buf->size < 1)
return 1;//防止发生数据为空
if (pa->flag & 0x2) { //WebSocket
printf((const char*)buf->data, buf->size < 256 ? buf->size : 256);
printf("-------------------------------------------ws:%zd dlen=%zd\n%s\n-------------------------------------------\n",pa->sk, buf->size, buf->data);
ulong len = buf->size;
char* p = WebSocketMakeFrame(buf->data, &len, 1);//文本帧
tw_send_data(client, p, len, 0, 1);
} else { //Socket
printf("-------------------------------------------sk:%zd dlen=%zd\n%s\n-------------------------------------------\n",pa->sk, buf->size, buf->data);
tw_send_data(client, buf->data, buf->size, 1, 0);
}
return 1;
}
char on_close(void* data, uv_stream_t* client, tw_peerAddr* pa)
{
//printf("closed: sk=%zd [%s:%d] from:%s:%d cli:%d\n", pa->sk, pa->ip, pa->port, pa->fip, pa->fport, client->loop->active_tcp_streams);
return 0;
}
char on_connect(void* data, uv_stream_t* client, tw_peerAddr* pa)
{
//printf("connected: sk=%zd [%s:%d] from:%s:%d cli:%d\n",pa->sk,pa->ip,pa->port,pa->fip,pa->fport, client->loop->active_tcp_streams);
return 0;
}
char on_error(void* data, uv_stream_t* client, tw_peerAddr* pa, int errcode, char* errstr)
{
//printf("error: sk=%zd [%s:%d] from:%s:%d cli:%d %s\n", pa->sk, pa->ip, pa->port, pa->fip, pa->fport, client->loop->active_tcp_streams,errstr);
return 0;
}
/*! ----------------------------------------------------------------------------
* @fn WebServer
*
* @brief Constructor of the Web Server Object.
*/
WebServer::WebServer(void)
{
}
/*! ----------------------------------------------------------------------------
* @fn ~WebServer
*
* @brief Destructor of the Web Server Object.
*/
WebServer::~WebServer(void)
{
}
/*! ----------------------------------------------------------------------------
* @fn setup
*
* @brief Setup the Web server
*/
int WebServer::setup(char *a_document_root, int a_port, uv_loop_t *an_evt_loop)
{
memset(&m_conf, 0, sizeof(m_conf));
m_conf.dirlist = 1;//目录列表
//conf.ip = NULL;// "127.0.0.1";
m_conf.port = a_port;
m_conf.doc_dir = a_document_root;
m_conf.doc_index = NULL;// Default homepage
//m_conf.doc_dir = NULL;// The directory where the default program files are located
m_conf.on_request = on_request;
m_conf.on_data = on_socket_data;
m_conf.on_close = on_close;
m_conf.on_connect = on_connect;
m_conf.on_error = on_error;
tinyweb_start(an_evt_loop, &m_conf);
return 0;
}