Skip to content

Commit

Permalink
优化下载 等
Browse files Browse the repository at this point in the history
  • Loading branch information
lzpong committed Jul 18, 2018
1 parent 868446b commit baa2c7a
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 42 deletions.
6 changes: 3 additions & 3 deletions Main.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,19 +120,19 @@ char on_socket_data(void* data, uv_stream_t* client, tw_peerAddr* pa, membuf_t*

char on_close(void* data, uv_stream_t* client, tw_peerAddr* pa)
{
printf("closed: sk=%d [%s:%d] flag=%d\n", pa->sk, pa->ip, pa->port,pa->flag);
printf("closed: sk=%zd [%s:%d] flag=%d\n", pa->sk, pa->ip, pa->port,pa->flag);
return 0;
}

char on_error(void* data, uv_stream_t* client, tw_peerAddr* pa, int errcode, char* errstr)
{
printf("error: sk=%d [%s:%d] flag=%d %s\n", pa->sk, pa->ip, pa->port,pa->flag, errstr);
printf("error: sk=%zd [%s:%d] flag=%d %s\n", pa->sk, pa->ip, pa->port,pa->flag, errstr);
return 0;
}

char on_connect(void* data, uv_stream_t* client, tw_peerAddr* pa)
{
printf("connected: sk=%d [%s:%d]\n",pa->sk,pa->ip,pa->port);
printf("connected: sk=%zd [%s:%d]\n",pa->sk,pa->ip,pa->port);
return 0;
}

Expand Down
44 changes: 21 additions & 23 deletions tinyweb.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@

//TinyWeb 增加与完善功能,by lzpong 2016/11/24

#define TW_SEND_SIZE 1024*8
//值大,发送文件时磁盘和CPU性能更好,占用内存增加
#define TW_SEND_SIZE 1024*1024*16

typedef struct tw_file_t {
//uchar flag; //连接的标志
Expand All @@ -31,16 +32,14 @@ typedef struct tw_client {
}tw_client;
//=================================================

//发送文件到客户端
static char tw_http_send_file(uv_stream_t* client, const char* content_type,const char* ext_heads, const char* file, tw_reqHeads* heads);

//关闭客户端连接后,释放客户端连接的数据
static void after_uv_close_client(uv_handle_t* client) {
tw_client* clidata = (tw_client*)client->data;
//如果有发送文件
if (clidata->ft.fp) {
fclose(clidata->ft.fp);
printf("send file close left:%lld\n", clidata->ft.lsize);
printf("send file close sk:%lld left:%lld\n",clidata->pa.sk, clidata->ft.lsize);
}
//如果是WebSocket
if (clidata->pa.flag & 0x2) { //WebSocket
Expand All @@ -65,14 +64,13 @@ void tw_close_client(uv_stream_t* client) {
static void after_uv_write(uv_write_t* w, int status) {
tw_client* clidata = (tw_client*)w->handle->data;
if (w->data)
free(w->data); //copyed data
free(w->data); //sended data
//长连接就不关闭了
if (clidata->ft.fp)
tw_http_send_file(w->handle, NULL, NULL, NULL, NULL);
else if (!(clidata->pa.flag & 0x1)){
if (w->handle->flags & 0x01) {
printf("after_uv_write:: error: handle Has been closed\n");
return;
}
else
uv_close((uv_handle_t*)w->handle, after_uv_close_client);
Expand Down Expand Up @@ -105,7 +103,7 @@ void tw_send_data(uv_stream_t* client, const void* data, size_t len, char need_c
uv_write(w, client, &buf, 1, after_uv_write); //free w and w->data in after_uv_write()
}

//获取头部 SetCookie 字段值
//制造头部 SetCookie 字段和值
//setCookie: 缓存区(至少 110+strlen(domain)=strlen(path) ),外部传入
//ckLen: set_cookie的长度
//expires: 多少秒后过期
Expand Down Expand Up @@ -194,12 +192,13 @@ static void tw_404_not_found(uv_stream_t* client, const char* pathinfo, const ch
respone = tw_format_http_respone(client, "404 Not Found", ext_heads, "text/html", buffer, -1, NULL);
tw_send_data(client, respone, -1, 0, 1);
}
//发送301响应
//
static void tw_301_Moved(uv_stream_t* client, tw_reqHeads* heads, const char* ext_heads) {

//发送301响应,路径重定位
void tw_301_Moved(uv_stream_t* client, tw_reqHeads* heads, const char* ext_heads) {
size_t len = 76 + strlen(heads->path);
char buffer[10245];
char szDate[30];
ext_heads == NULL ? ext_heads = "" : 0;
getGmtTime(szDate,30,0);
tw_config* tw_conf = (tw_config*)(client->loop->data);
snprintf(buffer, sizeof(buffer), "HTTP/1.1 301 Moved Permanently\r\nDate: %s\r\n"
Expand All @@ -213,17 +212,18 @@ static void tw_301_Moved(uv_stream_t* client, tw_reqHeads* heads, const char* ex
tw_send_data(client, buffer, -1, 1, 1);
}

//发送文件到客户端
static char tw_http_send_file(uv_stream_t* client, const char* content_type, const char* ext_heads, const char* file, tw_reqHeads* heads) {
//http协议发送文件,异步
//file_path: 文件路径
void tw_http_send_file(uv_stream_t* client, tw_reqHeads* heads, const char* ext_heads, const char* content_type, const char* file_path) {
char *respone;
tw_config* tw_conf = (tw_config*)(client->loop->data);
tw_client* clidata = (tw_client*)client->data;
tw_file_t* filet = &clidata->ft;
char szDate[30];

//发送头部
if (!filet->fp && file) {
filet->fp = fopen(file, "rb");
if (!filet->fp && file_path) {
filet->fp = fopen(file_path, "rb");
if (filet->fp) {
#ifdef _WIN64
_fseeki64(filet->fp, 0, SEEK_END);
Expand All @@ -249,8 +249,9 @@ static char tw_http_send_file(uv_stream_t* client, const char* content_type, con
}
else {
tw_404_not_found(client, heads->path, ext_heads);
return 0;
return;
}
ext_heads == NULL ? ext_heads = "" : 0;
getGmtTime(szDate,30,0);
respone = (char*)malloc(300 + 1);
int respone_size;
Expand All @@ -261,7 +262,6 @@ static char tw_http_send_file(uv_stream_t* client, const char* content_type, con
respone_size = snprintf(respone, 300, "HTTP/1.1 206 Partial Content\r\nDate: %s\r\nServer: TinyWeb\r\nConnection: close\r\nContent-Type:%s;charset=%s\r\nAccept-Range: bytes\r\nContent-Range: %lld-%lld/%lld\r\nContent-Length:%lld%s\r\n\r\n"
, szDate, content_type, tw_conf->charset, heads->Range_frm, heads->Range_to, filet->fsize, (heads->Range_to- heads->Range_frm),ext_heads);
tw_send_data(client, respone, respone_size, 0, 1);
return 1;
}
else { //发送文件
size_t read_size;// read_bytes;
Expand All @@ -285,9 +285,7 @@ static char tw_http_send_file(uv_stream_t* client, const char* content_type, con
filet->fsize = 0;
tw_send_data(client, respone, TW_SEND_SIZE, 0, 1);
}
return 1;
}
return 0;
}
}

Expand Down Expand Up @@ -339,7 +337,7 @@ const char* tw_get_content_type(const char* fileExt) {
else if (strcmpi(fileExt, "apk") == 0)
return "application/vnd.android.package-archive";
else
return "application/octet-stream";
return octet;
}

//处理客户端请求
Expand All @@ -348,7 +346,7 @@ const char* tw_get_content_type(const char* fileExt) {
//if not handle this request (by invoking write_uv_data()), you can close connection using tw_close_client(client).
//pathinfo: "/" or "/book/view/1"
//query_stirng: the string after '?' in url, such as "id=0&value=123", maybe NULL or ""
void tw_request(uv_stream_t* client, tw_reqHeads* heads) {
static void tw_request(uv_stream_t* client, tw_reqHeads* heads) {
tw_config* tw_conf = (tw_config*)(client->loop->data);
char fullpath[260];//绝对路径(末尾不带斜杠)
snprintf(fullpath, 259, "%s/%s\0", tw_conf->doc_dir, (heads->path[0] == '/' ? heads->path + 1 : heads->path));
Expand Down Expand Up @@ -377,7 +375,7 @@ void tw_request(uv_stream_t* client, tw_reqHeads* heads) {
p--;
}
}
tw_http_send_file(client, postfix ? tw_get_content_type(postfix) : "application/octet-stream", NULL, fullpath, heads);
tw_http_send_file(client, heads, NULL, tw_get_content_type(postfix), fullpath);
}
break;
case 2://存在:文件夹
Expand All @@ -396,7 +394,7 @@ void tw_request(uv_stream_t* client, tw_reqHeads* heads) {
snprintf(tmp, 259, "%s/%s", fullpath, p);
if (isFile(tmp))
{
tw_http_send_file(client, "text/html", NULL, tmp, heads);
tw_http_send_file(client, heads, NULL, "text/html", tmp);
break;
}
tmp[0] = 0;
Expand Down Expand Up @@ -685,7 +683,7 @@ static void on_uv_read(uv_stream_t* client, ssize_t nread, const uv_buf_t* buf)
free(p2);
}
else if (heads.method) { //HTTP
//所有请求全部回调,返回非0,则继续
//所有请求全部回调,返回非0表示已处理
if (tw_conf->on_request == 0 || 0 == tw_conf->on_request(tw_conf->data, client, &clidata->pa, &heads)) {
tw_request(client, &heads);
}
Expand Down
31 changes: 15 additions & 16 deletions tinyweb.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ auth lzpong 2016/11/24
4.支持指定根目录默认程序所在目录
5.支持任意格式文件访问(/不带扩展名, 文件下载)
a.支持静态网页访问html/htm
b.支持其他静态文件js, css, png, jpeg/jpg, gif, ico, txt, xml, json, log, wam, wav, mp3, apk
b.支持其他静态文件js, css, png, jpeg/jpg, gif, ico, txt, xml, json, log, wam, wav, mp3, mp4, apk
c.支持其他文件格式, 默认文件类型为"application/octet-stream"
d.支持不带扩展名文件访问
e.支持 Range 请求参数下载大文件(Range: bytes=sizeFrom-[sizeTo],都可正可负)
e.支持 Range 请求参数下载大文件(Range: bytes=sizeFrom-[sizeTo],支持负反向计算)
6.支持默认index页面(index.html/index.htm),可以自定义设置
7.支持目录列表
8.不允许访问根目录上级文件或文件夹
Expand All @@ -68,7 +68,7 @@ typedef struct tw_peerAddr {
uchar flag;//标志字节 ([0~7]: [0]是否需要保持连接 [1]是否WebSocket [2]是否WebSocket文本帧)
ushort port;
ushort fport;
uint sk;
size_t sk;
char ip[17];
char fip[17];
}tw_peerAddr;
Expand All @@ -86,10 +86,10 @@ typedef struct tw_reqHeads {

//服务配置
typedef struct tw_config {
//private data:
//private data:
uv_tcp_t _server;

//public data:
//public data:
uchar dirlist:1; //是否允许列出目录
char* doc_dir; //Web根目录,绝对路径,末尾带斜杠'\'(uninx为'/'); 默认程序文件所在目录
char* doc_index;//默认主页文件名,逗号分隔; 默认"index.html,index.htm"
Expand All @@ -115,7 +115,7 @@ typedef struct tw_config {
char (*on_data)(void* data, uv_stream_t* client, tw_peerAddr* pa, membuf_t* buf);

//Socket 检测到错误(此时链接可能已经断开)
//错误消息格式:"%d:%s,%s,%s"
//错误消息格式:"%d:%s,%s"
//pa->flag:标志字节 ([0~7]: [0]是否需要保持连接 [1]是否WebSocket [2]是否WebSocket文本帧
char (*on_error)(void* data, uv_stream_t* client, tw_peerAddr* pa,int errcode, char* errstr);

Expand All @@ -137,22 +137,14 @@ void tinyweb_stop(uv_loop_t* loop);

//=================================================

//获取头部 SetCookie 字段值
//制造头部 SetCookie 字段和值
//set_cookie: 缓存区(至少 110+strlen(domain)=strlen(path) ),外部传入
//ckLen: set_cookie的长度
//expires: 多少秒后过期
//domain: Domain, 可以是 heads->host,外部传入
//path: Path, 可以是 heads->path,外部传入
void tw_make_cookie(char* set_cookie, int ckLen, int expires, char* domain, char* path);

//处理客户端请求
//invoked by tinyweb when GET request comes in
//please invoke write_uv_data() once and only once on every request, to send respone to client and close the connection.
//if not handle this request (by invoking write_uv_data()), you can close connection using tw_close_client(client).
//path: "/" or "/book/view/1"
//query: the string after '?' in url, such as "id=0&value=123", maybe NULL or ""
void tw_request(uv_stream_t* client, tw_reqHeads* heads);

//返回格式华的HTTP响应内容 (需要free返回数据)
//status:http状态,如:"200 OK"
//ext_heads:额外的头部字符串,如:"head1: this-is-head1\r\nSetCookie: TINY_SSID=Tiny1531896250879; Expires=...\r\n"
Expand All @@ -179,7 +171,14 @@ void tw_send_data(uv_stream_t* client, const void* data, size_t len, char need_c
//u8data:utf-8编码的数据
//content_length:数据长度,为-1时自动计算(strlen)
//respone_size:获取响应最终发送的数据长度,为0表示放不需要取此长度
void tw_send_200_OK(uv_stream_t* client, const char* content_type, const char* ext_heads, const void* u8data, size_t content_length, size_t* respone_size);
void tw_send_200_OK(uv_stream_t* client, const char* ext_heads, const char* content_type, const void* u8data, size_t content_length, size_t* respone_size);

//http协议发送文件,异步
//file_path: 文件路径
void tw_http_send_file(uv_stream_t* client, tw_reqHeads* heads, const char* ext_heads, const char* content_type, const char* file_path);

//发送301响应,路径重定位
void tw_301_Moved(uv_stream_t* client, tw_reqHeads* heads, const char* ext_heads);

//关闭客户端连接
void tw_close_client(uv_stream_t* client);
Expand Down

0 comments on commit baa2c7a

Please sign in to comment.