162 lines
5.9 KiB
C++
162 lines
5.9 KiB
C++
/*!
|
||
* 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;
|
||
}
|