Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
Z
ZLMediaKit
概览
Overview
Details
Activity
Cycle Analytics
版本库
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
问题
0
Issues
0
列表
Board
标记
里程碑
合并请求
0
Merge Requests
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
Snippets
成员
Collapse sidebar
Close sidebar
活动
图像
聊天
创建新问题
作业
提交
Issue Boards
Open sidebar
张翔宇
ZLMediaKit
Commits
13221ad7
Commit
13221ad7
authored
Jan 02, 2021
by
xiongziliang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
http回复根据状态码自动生成status message: #602
parent
c69e9b8e
全部展开
显示空白字符变更
内嵌
并排
正在显示
10 个修改的文件
包含
318 行增加
和
188 行删除
+318
-188
api/include/mk_events_objects.h
+4
-4
api/source/mk_events_objects.cpp
+2
-2
server/WebApi.cpp
+13
-13
src/Http/HttpConst.cpp
+216
-0
src/Http/HttpConst.h
+35
-0
src/Http/HttpFileManager.cpp
+18
-141
src/Http/HttpFileManager.h
+6
-5
src/Http/HttpSession.cpp
+22
-21
src/Http/HttpSession.h
+1
-1
tests/test_httpApi.cpp
+1
-1
没有找到文件。
api/include/mk_events_objects.h
查看文件 @
13221ad7
...
@@ -169,23 +169,23 @@ typedef void* mk_http_response_invoker;
...
@@ -169,23 +169,23 @@ typedef void* mk_http_response_invoker;
/**
/**
* HttpSession::HttpResponseInvoker(const string &codeOut, const StrCaseMap &headerOut, const HttpBody::Ptr &body);
* HttpSession::HttpResponseInvoker(const string &codeOut, const StrCaseMap &headerOut, const HttpBody::Ptr &body);
* @param response_code 譬如200
OK
* @param response_code 譬如200
* @param response_header 返回的http头,譬如 {"Content-Type","text/html",NULL} 必须以NULL结尾
* @param response_header 返回的http头,譬如 {"Content-Type","text/html",NULL} 必须以NULL结尾
* @param response_body body对象
* @param response_body body对象
*/
*/
API_EXPORT
void
API_CALL
mk_http_response_invoker_do
(
const
mk_http_response_invoker
ctx
,
API_EXPORT
void
API_CALL
mk_http_response_invoker_do
(
const
mk_http_response_invoker
ctx
,
const
char
*
response_code
,
int
response_code
,
const
char
**
response_header
,
const
char
**
response_header
,
const
mk_http_body
response_body
);
const
mk_http_body
response_body
);
/**
/**
* HttpSession::HttpResponseInvoker(const string &codeOut, const StrCaseMap &headerOut, const string &body);
* HttpSession::HttpResponseInvoker(const string &codeOut, const StrCaseMap &headerOut, const string &body);
* @param response_code 譬如200
OK
* @param response_code 譬如200
* @param response_header 返回的http头,譬如 {"Content-Type","text/html",NULL} 必须以NULL结尾
* @param response_header 返回的http头,譬如 {"Content-Type","text/html",NULL} 必须以NULL结尾
* @param response_content 返回的content部分,譬如一个网页内容
* @param response_content 返回的content部分,譬如一个网页内容
*/
*/
API_EXPORT
void
API_CALL
mk_http_response_invoker_do_string
(
const
mk_http_response_invoker
ctx
,
API_EXPORT
void
API_CALL
mk_http_response_invoker_do_string
(
const
mk_http_response_invoker
ctx
,
const
char
*
response_code
,
int
response_code
,
const
char
**
response_header
,
const
char
**
response_header
,
const
char
*
response_content
);
const
char
*
response_content
);
/**
/**
...
...
api/source/mk_events_objects.cpp
查看文件 @
13221ad7
...
@@ -288,7 +288,7 @@ API_EXPORT void API_CALL mk_http_body_release(mk_http_body ctx){
...
@@ -288,7 +288,7 @@ API_EXPORT void API_CALL mk_http_body_release(mk_http_body ctx){
///////////////////////////////////////////HttpResponseInvoker/////////////////////////////////////////////
///////////////////////////////////////////HttpResponseInvoker/////////////////////////////////////////////
API_EXPORT
void
API_CALL
mk_http_response_invoker_do_string
(
const
mk_http_response_invoker
ctx
,
API_EXPORT
void
API_CALL
mk_http_response_invoker_do_string
(
const
mk_http_response_invoker
ctx
,
const
char
*
response_code
,
int
response_code
,
const
char
**
response_header
,
const
char
**
response_header
,
const
char
*
response_content
){
const
char
*
response_content
){
assert
(
ctx
&&
response_code
&&
response_header
&&
response_content
);
assert
(
ctx
&&
response_code
&&
response_header
&&
response_content
);
...
@@ -308,7 +308,7 @@ API_EXPORT void API_CALL mk_http_response_invoker_do_file(const mk_http_response
...
@@ -308,7 +308,7 @@ API_EXPORT void API_CALL mk_http_response_invoker_do_file(const mk_http_response
}
}
API_EXPORT
void
API_CALL
mk_http_response_invoker_do
(
const
mk_http_response_invoker
ctx
,
API_EXPORT
void
API_CALL
mk_http_response_invoker_do
(
const
mk_http_response_invoker
ctx
,
const
char
*
response_code
,
int
response_code
,
const
char
**
response_header
,
const
char
**
response_header
,
const
mk_http_body
response_body
){
const
mk_http_body
response_body
){
assert
(
ctx
&&
response_code
&&
response_header
&&
response_body
);
assert
(
ctx
&&
response_code
&&
response_header
&&
response_body
);
...
...
server/WebApi.cpp
查看文件 @
13221ad7
...
@@ -62,7 +62,7 @@ static void responseApi(const Json::Value &res, const HttpSession::HttpResponseI
...
@@ -62,7 +62,7 @@ static void responseApi(const Json::Value &res, const HttpSession::HttpResponseI
GET_CONFIG
(
string
,
charSet
,
Http
::
kCharSet
);
GET_CONFIG
(
string
,
charSet
,
Http
::
kCharSet
);
HttpSession
::
KeyValue
headerOut
;
HttpSession
::
KeyValue
headerOut
;
headerOut
[
"Content-Type"
]
=
string
(
"application/json; charset="
)
+
charSet
;
headerOut
[
"Content-Type"
]
=
string
(
"application/json; charset="
)
+
charSet
;
invoker
(
"200 OK"
,
headerOut
,
res
.
toStyledString
());
invoker
(
200
,
headerOut
,
res
.
toStyledString
());
};
};
static
void
responseApi
(
int
code
,
const
string
&
msg
,
const
HttpSession
::
HttpResponseInvoker
&
invoker
){
static
void
responseApi
(
int
code
,
const
string
&
msg
,
const
HttpSession
::
HttpResponseInvoker
&
invoker
){
...
@@ -92,7 +92,7 @@ static HttpApi toApi(const function<void(API_ARGS_MAP_ASYNC)> &cb) {
...
@@ -92,7 +92,7 @@ static HttpApi toApi(const function<void(API_ARGS_MAP_ASYNC)> &cb) {
static
HttpApi
toApi
(
const
function
<
void
(
API_ARGS_MAP
)
>
&
cb
)
{
static
HttpApi
toApi
(
const
function
<
void
(
API_ARGS_MAP
)
>
&
cb
)
{
return
toApi
([
cb
](
API_ARGS_MAP_ASYNC
)
{
return
toApi
([
cb
](
API_ARGS_MAP_ASYNC
)
{
cb
(
API_ARGS_VALUE
);
cb
(
API_ARGS_VALUE
);
invoker
(
"200 OK"
,
headerOut
,
val
.
toStyledString
());
invoker
(
200
,
headerOut
,
val
.
toStyledString
());
});
});
}
}
...
@@ -120,7 +120,7 @@ static HttpApi toApi(const function<void(API_ARGS_JSON_ASYNC)> &cb) {
...
@@ -120,7 +120,7 @@ static HttpApi toApi(const function<void(API_ARGS_JSON_ASYNC)> &cb) {
static
HttpApi
toApi
(
const
function
<
void
(
API_ARGS_JSON
)
>
&
cb
)
{
static
HttpApi
toApi
(
const
function
<
void
(
API_ARGS_JSON
)
>
&
cb
)
{
return
toApi
([
cb
](
API_ARGS_JSON_ASYNC
)
{
return
toApi
([
cb
](
API_ARGS_JSON_ASYNC
)
{
cb
(
API_ARGS_VALUE
);
cb
(
API_ARGS_VALUE
);
invoker
(
"200 OK"
,
headerOut
,
val
.
toStyledString
());
invoker
(
200
,
headerOut
,
val
.
toStyledString
());
});
});
}
}
...
@@ -182,7 +182,7 @@ static inline void addHttpListener(){
...
@@ -182,7 +182,7 @@ static inline void addHttpListener(){
consumed
=
true
;
consumed
=
true
;
if
(
api_debug
){
if
(
api_debug
){
auto
newInvoker
=
[
invoker
,
parser
](
const
string
&
codeOut
,
auto
newInvoker
=
[
invoker
,
parser
](
int
code
,
const
HttpSession
::
KeyValue
&
headerOut
,
const
HttpSession
::
KeyValue
&
headerOut
,
const
HttpBody
::
Ptr
&
body
)
{
const
HttpBody
::
Ptr
&
body
)
{
...
@@ -199,13 +199,13 @@ static inline void addHttpListener(){
...
@@ -199,13 +199,13 @@ static inline void addHttpListener(){
<<
"# content:
\r\n
"
<<
parser
.
Content
()
<<
"
\r\n
"
<<
"# content:
\r\n
"
<<
parser
.
Content
()
<<
"
\r\n
"
<<
"# response:
\r\n
"
<<
"# response:
\r\n
"
<<
contentOut
<<
"
\r\n
"
;
<<
contentOut
<<
"
\r\n
"
;
invoker
(
code
Out
,
headerOut
,
contentOut
);
invoker
(
code
,
headerOut
,
contentOut
);
}
else
{
}
else
{
DebugL
<<
"
\r\n
# request:
\r\n
"
<<
parser
.
Method
()
<<
" "
<<
parser
.
FullUrl
()
<<
"
\r\n
"
DebugL
<<
"
\r\n
# request:
\r\n
"
<<
parser
.
Method
()
<<
" "
<<
parser
.
FullUrl
()
<<
"
\r\n
"
<<
"# content:
\r\n
"
<<
parser
.
Content
()
<<
"
\r\n
"
<<
"# content:
\r\n
"
<<
parser
.
Content
()
<<
"
\r\n
"
<<
"# response size:"
<<
"# response size:"
<<
size
<<
"
\r\n
"
;
<<
size
<<
"
\r\n
"
;
invoker
(
code
Out
,
headerOut
,
body
);
invoker
(
code
,
headerOut
,
body
);
}
}
};
};
((
HttpSession
::
HttpResponseInvoker
&
)
invoker
)
=
newInvoker
;
((
HttpSession
::
HttpResponseInvoker
&
)
invoker
)
=
newInvoker
;
...
@@ -268,7 +268,7 @@ void installWebApi() {
...
@@ -268,7 +268,7 @@ void installWebApi() {
val
[
"data"
].
append
(
obj
);
val
[
"data"
].
append
(
obj
);
}
}
val
[
"code"
]
=
API
::
Success
;
val
[
"code"
]
=
API
::
Success
;
invoker
(
"200 OK"
,
headerOut
,
val
.
toStyledString
());
invoker
(
200
,
headerOut
,
val
.
toStyledString
());
});
});
});
});
...
@@ -286,7 +286,7 @@ void installWebApi() {
...
@@ -286,7 +286,7 @@ void installWebApi() {
val
[
"data"
].
append
(
obj
);
val
[
"data"
].
append
(
obj
);
}
}
val
[
"code"
]
=
API
::
Success
;
val
[
"code"
]
=
API
::
Success
;
invoker
(
"200 OK"
,
headerOut
,
val
.
toStyledString
());
invoker
(
200
,
headerOut
,
val
.
toStyledString
());
});
});
});
});
...
@@ -649,7 +649,7 @@ void installWebApi() {
...
@@ -649,7 +649,7 @@ void installWebApi() {
}
else
{
}
else
{
const_cast
<
Value
&>
(
val
)[
"data"
][
"key"
]
=
key
;
const_cast
<
Value
&>
(
val
)[
"data"
][
"key"
]
=
key
;
}
}
invoker
(
"200 OK"
,
headerOut
,
val
.
toStyledString
());
invoker
(
200
,
headerOut
,
val
.
toStyledString
());
});
});
});
});
...
@@ -712,7 +712,7 @@ void installWebApi() {
...
@@ -712,7 +712,7 @@ void installWebApi() {
}
else
{
}
else
{
const_cast
<
Value
&>
(
val
)[
"data"
][
"key"
]
=
key
;
const_cast
<
Value
&>
(
val
)[
"data"
][
"key"
]
=
key
;
}
}
invoker
(
"200 OK"
,
headerOut
,
val
.
toStyledString
());
invoker
(
200
,
headerOut
,
val
.
toStyledString
());
});
});
});
});
...
@@ -818,7 +818,7 @@ void installWebApi() {
...
@@ -818,7 +818,7 @@ void installWebApi() {
const_cast
<
Value
&>
(
val
)[
"msg"
]
=
ex
.
what
();
const_cast
<
Value
&>
(
val
)[
"msg"
]
=
ex
.
what
();
}
}
const_cast
<
Value
&>
(
val
)[
"local_port"
]
=
local_port
;
const_cast
<
Value
&>
(
val
)[
"local_port"
]
=
local_port
;
invoker
(
"200 OK"
,
headerOut
,
val
.
toStyledString
());
invoker
(
200
,
headerOut
,
val
.
toStyledString
());
});
});
});
});
...
@@ -1092,7 +1092,7 @@ void installWebApi() {
...
@@ -1092,7 +1092,7 @@ void installWebApi() {
}
else
{
}
else
{
const_cast
<
Value
&>
(
val
)[
"data"
][
"key"
]
=
key
;
const_cast
<
Value
&>
(
val
)[
"data"
][
"key"
]
=
key
;
}
}
invoker
(
"200 OK"
,
headerOut
,
val
.
toStyledString
());
invoker
(
200
,
headerOut
,
val
.
toStyledString
());
});
});
});
});
#endif//!defined(_WIN32)
#endif//!defined(_WIN32)
...
@@ -1117,7 +1117,7 @@ void installWebApi() {
...
@@ -1117,7 +1117,7 @@ void installWebApi() {
}
else
{
}
else
{
const_cast
<
Value
&>
(
val
)[
"data"
][
"key"
]
=
key
;
const_cast
<
Value
&>
(
val
)[
"data"
][
"key"
]
=
key
;
}
}
invoker
(
"200 OK"
,
headerOut
,
val
.
toStyledString
());
invoker
(
200
,
headerOut
,
val
.
toStyledString
());
});
});
});
});
...
...
src/Http/HttpConst.cpp
0 → 100644
查看文件 @
13221ad7
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#include <string.h>
#include "HttpConst.h"
#include "Common/Parser.h"
#include "Util/onceToken.h"
namespace
mediakit
{
const
char
*
getHttpStatusMessage
(
int
status
)
{
switch
(
status
)
{
case
100
:
return
"Continue"
;
case
101
:
return
"Switching Protocol"
;
case
102
:
return
"Processing"
;
case
103
:
return
"Early Hints"
;
case
200
:
return
"OK"
;
case
201
:
return
"Created"
;
case
202
:
return
"Accepted"
;
case
203
:
return
"Non-Authoritative Information"
;
case
204
:
return
"No Content"
;
case
205
:
return
"Reset Content"
;
case
206
:
return
"Partial Content"
;
case
207
:
return
"Multi-Status"
;
case
208
:
return
"Already Reported"
;
case
226
:
return
"IM Used"
;
case
300
:
return
"Multiple Choice"
;
case
301
:
return
"Moved Permanently"
;
case
302
:
return
"Found"
;
case
303
:
return
"See Other"
;
case
304
:
return
"Not Modified"
;
case
305
:
return
"Use Proxy"
;
case
306
:
return
"unused"
;
case
307
:
return
"Temporary Redirect"
;
case
308
:
return
"Permanent Redirect"
;
case
400
:
return
"Bad Request"
;
case
401
:
return
"Unauthorized"
;
case
402
:
return
"Payment Required"
;
case
403
:
return
"Forbidden"
;
case
404
:
return
"Not Found"
;
case
405
:
return
"Method Not Allowed"
;
case
406
:
return
"Not Acceptable"
;
case
407
:
return
"Proxy Authentication Required"
;
case
408
:
return
"Request Timeout"
;
case
409
:
return
"Conflict"
;
case
410
:
return
"Gone"
;
case
411
:
return
"Length Required"
;
case
412
:
return
"Precondition Failed"
;
case
413
:
return
"Payload Too Large"
;
case
414
:
return
"URI Too Long"
;
case
415
:
return
"Unsupported Media Type"
;
case
416
:
return
"Range Not Satisfiable"
;
case
417
:
return
"Expectation Failed"
;
case
418
:
return
"I'm a teapot"
;
case
421
:
return
"Misdirected Request"
;
case
422
:
return
"Unprocessable Entity"
;
case
423
:
return
"Locked"
;
case
424
:
return
"Failed Dependency"
;
case
425
:
return
"Too Early"
;
case
426
:
return
"Upgrade Required"
;
case
428
:
return
"Precondition Required"
;
case
429
:
return
"Too Many Requests"
;
case
431
:
return
"Request Header Fields Too Large"
;
case
451
:
return
"Unavailable For Legal Reasons"
;
case
501
:
return
"Not Implemented"
;
case
502
:
return
"Bad Gateway"
;
case
503
:
return
"Service Unavailable"
;
case
504
:
return
"Gateway Timeout"
;
case
505
:
return
"HTTP Version Not Supported"
;
case
506
:
return
"Variant Also Negotiates"
;
case
507
:
return
"Insufficient Storage"
;
case
508
:
return
"Loop Detected"
;
case
510
:
return
"Not Extended"
;
case
511
:
return
"Network Authentication Required"
;
default
:
case
500
:
return
"Internal Server Error"
;
}
}
static
const
char
*
s_mime_src
[][
2
]
=
{
{
"html"
,
"text/html"
},
{
"htm"
,
"text/html"
},
{
"shtml"
,
"text/html"
},
{
"css"
,
"text/css"
},
{
"xml"
,
"text/xml"
},
{
"gif"
,
"image/gif"
},
{
"jpeg"
,
"image/jpeg"
},
{
"jpg"
,
"image/jpeg"
},
{
"js"
,
"application/javascript"
},
{
"map"
,
"application/javascript"
},
{
"atom"
,
"application/atom+xml"
},
{
"rss"
,
"application/rss+xml"
},
{
"mml"
,
"text/mathml"
},
{
"txt"
,
"text/plain"
},
{
"jad"
,
"text/vnd.sun.j2me.app-descriptor"
},
{
"wml"
,
"text/vnd.wap.wml"
},
{
"htc"
,
"text/x-component"
},
{
"png"
,
"image/png"
},
{
"tif"
,
"image/tiff"
},
{
"tiff"
,
"image/tiff"
},
{
"wbmp"
,
"image/vnd.wap.wbmp"
},
{
"ico"
,
"image/x-icon"
},
{
"jng"
,
"image/x-jng"
},
{
"bmp"
,
"image/x-ms-bmp"
},
{
"svg"
,
"image/svg+xml"
},
{
"svgz"
,
"image/svg+xml"
},
{
"webp"
,
"image/webp"
},
{
"woff"
,
"application/font-woff"
},
{
"woff2"
,
"application/font-woff"
},
{
"jar"
,
"application/java-archive"
},
{
"war"
,
"application/java-archive"
},
{
"ear"
,
"application/java-archive"
},
{
"json"
,
"application/json"
},
{
"hqx"
,
"application/mac-binhex40"
},
{
"doc"
,
"application/msword"
},
{
"pdf"
,
"application/pdf"
},
{
"ps"
,
"application/postscript"
},
{
"eps"
,
"application/postscript"
},
{
"ai"
,
"application/postscript"
},
{
"rtf"
,
"application/rtf"
},
{
"m3u8"
,
"application/vnd.apple.mpegurl"
},
{
"xls"
,
"application/vnd.ms-excel"
},
{
"eot"
,
"application/vnd.ms-fontobject"
},
{
"ppt"
,
"application/vnd.ms-powerpoint"
},
{
"wmlc"
,
"application/vnd.wap.wmlc"
},
{
"kml"
,
"application/vnd.google-earth.kml+xml"
},
{
"kmz"
,
"application/vnd.google-earth.kmz"
},
{
"7z"
,
"application/x-7z-compressed"
},
{
"cco"
,
"application/x-cocoa"
},
{
"jardiff"
,
"application/x-java-archive-diff"
},
{
"jnlp"
,
"application/x-java-jnlp-file"
},
{
"run"
,
"application/x-makeself"
},
{
"pl"
,
"application/x-perl"
},
{
"pm"
,
"application/x-perl"
},
{
"prc"
,
"application/x-pilot"
},
{
"pdb"
,
"application/x-pilot"
},
{
"rar"
,
"application/x-rar-compressed"
},
{
"rpm"
,
"application/x-redhat-package-manager"
},
{
"sea"
,
"application/x-sea"
},
{
"swf"
,
"application/x-shockwave-flash"
},
{
"sit"
,
"application/x-stuffit"
},
{
"tcl"
,
"application/x-tcl"
},
{
"tk"
,
"application/x-tcl"
},
{
"der"
,
"application/x-x509-ca-cert"
},
{
"pem"
,
"application/x-x509-ca-cert"
},
{
"crt"
,
"application/x-x509-ca-cert"
},
{
"xpi"
,
"application/x-xpinstall"
},
{
"xhtml"
,
"application/xhtml+xml"
},
{
"xspf"
,
"application/xspf+xml"
},
{
"zip"
,
"application/zip"
},
{
"bin"
,
"application/octet-stream"
},
{
"exe"
,
"application/octet-stream"
},
{
"dll"
,
"application/octet-stream"
},
{
"deb"
,
"application/octet-stream"
},
{
"dmg"
,
"application/octet-stream"
},
{
"iso"
,
"application/octet-stream"
},
{
"img"
,
"application/octet-stream"
},
{
"msi"
,
"application/octet-stream"
},
{
"msp"
,
"application/octet-stream"
},
{
"msm"
,
"application/octet-stream"
},
{
"docx"
,
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
},
{
"xlsx"
,
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
},
{
"pptx"
,
"application/vnd.openxmlformats-officedocument.presentationml.presentation"
},
{
"mid"
,
"audio/midi"
},
{
"midi"
,
"audio/midi"
},
{
"kar"
,
"audio/midi"
},
{
"mp3"
,
"audio/mpeg"
},
{
"ogg"
,
"audio/ogg"
},
{
"m4a"
,
"audio/x-m4a"
},
{
"ra"
,
"audio/x-realaudio"
},
{
"3gpp"
,
"video/3gpp"
},
{
"3gp"
,
"video/3gpp"
},
{
"ts"
,
"video/mp2t"
},
{
"mp4"
,
"video/mp4"
},
{
"mpeg"
,
"video/mpeg"
},
{
"mpg"
,
"video/mpeg"
},
{
"mov"
,
"video/quicktime"
},
{
"webm"
,
"video/webm"
},
{
"flv"
,
"video/x-flv"
},
{
"m4v"
,
"video/x-m4v"
},
{
"mng"
,
"video/x-mng"
},
{
"asx"
,
"video/x-ms-asf"
},
{
"asf"
,
"video/x-ms-asf"
},
{
"wmv"
,
"video/x-ms-wmv"
},
{
"avi"
,
"video/x-msvideo"
},
};
const
string
&
getHttpContentType
(
const
char
*
name
)
{
const
char
*
dot
;
dot
=
strrchr
(
name
,
'.'
);
static
StrCaseMap
mapType
;
static
onceToken
token
([
&
]()
{
for
(
unsigned
int
i
=
0
;
i
<
sizeof
(
s_mime_src
)
/
sizeof
(
s_mime_src
[
0
]);
++
i
)
{
mapType
.
emplace
(
s_mime_src
[
i
][
0
],
s_mime_src
[
i
][
1
]);
}
});
static
string
defaultType
=
"text/plain"
;
if
(
!
dot
)
{
return
defaultType
;
}
auto
it
=
mapType
.
find
(
dot
+
1
);
if
(
it
==
mapType
.
end
())
{
return
defaultType
;
}
return
it
->
second
;
}
}
//namespace mediakit
src/Http/HttpConst.h
0 → 100644
查看文件 @
13221ad7
/*
* Copyright (c) 2016 The ZLMediaKit project authors. All Rights Reserved.
*
* This file is part of ZLMediaKit(https://github.com/xiongziliang/ZLMediaKit).
*
* Use of this source code is governed by MIT license that can be found in the
* LICENSE file in the root of the source tree. All contributing project authors
* may be found in the AUTHORS file in the root of the source tree.
*/
#ifndef ZLMEDIAKIT_HTTPCONST_H
#define ZLMEDIAKIT_HTTPCONST_H
#include <string>
using
namespace
std
;
namespace
mediakit
{
/**
* 根据http错误代码获取字符说明
* @param status 譬如404
* @return 错误代码字符说明,譬如Not Found
*/
const
char
*
getHttpStatusMessage
(
int
status
);
/**
* 根据文件后缀返回http mime
* @param name 文件后缀,譬如html
* @return mime值,譬如text/html
*/
const
string
&
getHttpContentType
(
const
char
*
name
);
}
//mediakit
#endif //ZLMEDIAKIT_HTTPCONST_H
src/Http/HttpFileManager.cpp
查看文件 @
13221ad7
差异被折叠。
点击展开。
src/Http/HttpFileManager.h
查看文件 @
13221ad7
...
@@ -21,8 +21,8 @@ namespace mediakit {
...
@@ -21,8 +21,8 @@ namespace mediakit {
class
HttpResponseInvokerImp
{
class
HttpResponseInvokerImp
{
public
:
public
:
typedef
std
::
function
<
void
(
const
string
&
codeOut
,
const
StrCaseMap
&
headerOut
,
const
HttpBody
::
Ptr
&
body
)
>
HttpResponseInvokerLambda0
;
typedef
std
::
function
<
void
(
int
code
,
const
StrCaseMap
&
headerOut
,
const
HttpBody
::
Ptr
&
body
)
>
HttpResponseInvokerLambda0
;
typedef
std
::
function
<
void
(
const
string
&
codeOut
,
const
StrCaseMap
&
headerOut
,
const
string
&
body
)
>
HttpResponseInvokerLambda1
;
typedef
std
::
function
<
void
(
int
code
,
const
StrCaseMap
&
headerOut
,
const
string
&
body
)
>
HttpResponseInvokerLambda1
;
HttpResponseInvokerImp
(){}
HttpResponseInvokerImp
(){}
~
HttpResponseInvokerImp
(){}
~
HttpResponseInvokerImp
(){}
...
@@ -31,8 +31,9 @@ public:
...
@@ -31,8 +31,9 @@ public:
HttpResponseInvokerImp
(
const
HttpResponseInvokerLambda0
&
lambda
);
HttpResponseInvokerImp
(
const
HttpResponseInvokerLambda0
&
lambda
);
HttpResponseInvokerImp
(
const
HttpResponseInvokerLambda1
&
lambda
);
HttpResponseInvokerImp
(
const
HttpResponseInvokerLambda1
&
lambda
);
void
operator
()(
const
string
&
codeOut
,
const
StrCaseMap
&
headerOut
,
const
HttpBody
::
Ptr
&
body
)
const
;
void
operator
()(
int
code
,
const
StrCaseMap
&
headerOut
,
const
HttpBody
::
Ptr
&
body
)
const
;
void
operator
()(
const
string
&
codeOut
,
const
StrCaseMap
&
headerOut
,
const
string
&
body
)
const
;
void
operator
()(
int
code
,
const
StrCaseMap
&
headerOut
,
const
string
&
body
)
const
;
void
responseFile
(
const
StrCaseMap
&
requestHeader
,
const
StrCaseMap
&
responseHeader
,
const
string
&
filePath
)
const
;
void
responseFile
(
const
StrCaseMap
&
requestHeader
,
const
StrCaseMap
&
responseHeader
,
const
string
&
filePath
)
const
;
operator
bool
();
operator
bool
();
private
:
private
:
...
@@ -44,7 +45,7 @@ private:
...
@@ -44,7 +45,7 @@ private:
*/
*/
class
HttpFileManager
{
class
HttpFileManager
{
public
:
public
:
typedef
function
<
void
(
const
string
&
status_
code
,
const
string
&
content_type
,
const
StrCaseMap
&
responseHeader
,
const
HttpBody
::
Ptr
&
body
)
>
invoker
;
typedef
function
<
void
(
int
code
,
const
string
&
content_type
,
const
StrCaseMap
&
responseHeader
,
const
HttpBody
::
Ptr
&
body
)
>
invoker
;
/**
/**
* 访问文件或文件夹
* 访问文件或文件夹
...
...
src/Http/HttpSession.cpp
查看文件 @
13221ad7
...
@@ -14,6 +14,7 @@
...
@@ -14,6 +14,7 @@
#include "Common/config.h"
#include "Common/config.h"
#include "strCoding.h"
#include "strCoding.h"
#include "HttpSession.h"
#include "HttpSession.h"
#include "HttpConst.h"
#include "Util/base64.h"
#include "Util/base64.h"
#include "Util/SHA1.h"
#include "Util/SHA1.h"
using
namespace
toolkit
;
using
namespace
toolkit
;
...
@@ -34,7 +35,7 @@ void HttpSession::Handle_Req_HEAD(int64_t &content_len){
...
@@ -34,7 +35,7 @@ void HttpSession::Handle_Req_HEAD(int64_t &content_len){
//暂时全部返回200 OK,因为HTTP GET存在按需生成流的操作,所以不能按照HTTP GET的流程返回
//暂时全部返回200 OK,因为HTTP GET存在按需生成流的操作,所以不能按照HTTP GET的流程返回
//如果直接返回404,那么又会导致按需生成流的逻辑失效,所以HTTP HEAD在静态文件或者已存在资源时才有效
//如果直接返回404,那么又会导致按需生成流的逻辑失效,所以HTTP HEAD在静态文件或者已存在资源时才有效
//对于按需生成流的直播场景并不适用
//对于按需生成流的直播场景并不适用
sendResponse
(
"200 OK"
,
true
);
sendResponse
(
200
,
true
);
}
}
int64_t
HttpSession
::
onRecvHeader
(
const
char
*
header
,
uint64_t
len
)
{
int64_t
HttpSession
::
onRecvHeader
(
const
char
*
header
,
uint64_t
len
)
{
...
@@ -52,7 +53,7 @@ int64_t HttpSession::onRecvHeader(const char *header,uint64_t len) {
...
@@ -52,7 +53,7 @@ int64_t HttpSession::onRecvHeader(const char *header,uint64_t len) {
auto
it
=
s_func_map
.
find
(
cmd
);
auto
it
=
s_func_map
.
find
(
cmd
);
if
(
it
==
s_func_map
.
end
())
{
if
(
it
==
s_func_map
.
end
())
{
WarnP
(
this
)
<<
"不支持该命令:"
<<
cmd
;
WarnP
(
this
)
<<
"不支持该命令:"
<<
cmd
;
sendResponse
(
"405 Not Allowed"
,
true
);
sendResponse
(
405
,
true
);
return
0
;
return
0
;
}
}
...
@@ -139,7 +140,7 @@ bool HttpSession::checkWebSocket(){
...
@@ -139,7 +140,7 @@ bool HttpSession::checkWebSocket(){
auto
res_cb
=
[
this
,
headerOut
]()
{
auto
res_cb
=
[
this
,
headerOut
]()
{
_live_over_websocket
=
true
;
_live_over_websocket
=
true
;
sendResponse
(
"101 Switching Protocols"
,
false
,
nullptr
,
headerOut
,
nullptr
,
true
);
sendResponse
(
101
,
false
,
nullptr
,
headerOut
,
nullptr
,
true
);
};
};
//判断是否为websocket-flv
//判断是否为websocket-flv
...
@@ -162,10 +163,10 @@ bool HttpSession::checkWebSocket(){
...
@@ -162,10 +163,10 @@ bool HttpSession::checkWebSocket(){
//这是普通的websocket连接
//这是普通的websocket连接
if
(
!
onWebSocketConnect
(
_parser
))
{
if
(
!
onWebSocketConnect
(
_parser
))
{
sendResponse
(
"501 Not Implemented"
,
true
,
nullptr
,
headerOut
);
sendResponse
(
501
,
true
,
nullptr
,
headerOut
);
return
true
;
return
true
;
}
}
sendResponse
(
"101 Switching Protocols"
,
false
,
nullptr
,
headerOut
,
nullptr
,
true
);
sendResponse
(
101
,
false
,
nullptr
,
headerOut
,
nullptr
,
true
);
return
true
;
return
true
;
}
}
...
@@ -198,7 +199,7 @@ bool HttpSession::checkLiveStream(const string &schema, const string &url_suffi
...
@@ -198,7 +199,7 @@ bool HttpSession::checkLiveStream(const string &schema, const string &url_suffi
if
(
!
err
.
empty
())
{
if
(
!
err
.
empty
())
{
//播放鉴权失败
//播放鉴权失败
strong_self
->
sendResponse
(
"401 Unauthorized"
,
close_flag
,
nullptr
,
KeyValue
(),
std
::
make_shared
<
HttpStringBody
>
(
err
));
strong_self
->
sendResponse
(
401
,
close_flag
,
nullptr
,
KeyValue
(),
std
::
make_shared
<
HttpStringBody
>
(
err
));
return
;
return
;
}
}
...
@@ -245,7 +246,7 @@ bool HttpSession::checkLiveStreamFMP4(const function<void()> &cb){
...
@@ -245,7 +246,7 @@ bool HttpSession::checkLiveStreamFMP4(const function<void()> &cb){
assert
(
fmp4_src
);
assert
(
fmp4_src
);
if
(
!
cb
)
{
if
(
!
cb
)
{
//找到源,发送http头,负载后续发送
//找到源,发送http头,负载后续发送
sendResponse
(
"200 OK"
,
false
,
HttpFileManager
::
getContentType
(
".mp4"
).
data
(),
KeyValue
(),
nullptr
,
true
);
sendResponse
(
200
,
false
,
HttpFileManager
::
getContentType
(
".mp4"
).
data
(),
KeyValue
(),
nullptr
,
true
);
}
else
{
}
else
{
//自定义发送http头
//自定义发送http头
cb
();
cb
();
...
@@ -286,7 +287,7 @@ bool HttpSession::checkLiveStreamTS(const function<void()> &cb){
...
@@ -286,7 +287,7 @@ bool HttpSession::checkLiveStreamTS(const function<void()> &cb){
assert
(
ts_src
);
assert
(
ts_src
);
if
(
!
cb
)
{
if
(
!
cb
)
{
//找到源,发送http头,负载后续发送
//找到源,发送http头,负载后续发送
sendResponse
(
"200 OK"
,
false
,
HttpFileManager
::
getContentType
(
".ts"
).
data
(),
KeyValue
(),
nullptr
,
true
);
sendResponse
(
200
,
false
,
HttpFileManager
::
getContentType
(
".ts"
).
data
(),
KeyValue
(),
nullptr
,
true
);
}
else
{
}
else
{
//自定义发送http头
//自定义发送http头
cb
();
cb
();
...
@@ -326,7 +327,7 @@ bool HttpSession::checkLiveStreamFlv(const function<void()> &cb){
...
@@ -326,7 +327,7 @@ bool HttpSession::checkLiveStreamFlv(const function<void()> &cb){
assert
(
rtmp_src
);
assert
(
rtmp_src
);
if
(
!
cb
)
{
if
(
!
cb
)
{
//找到源,发送http头,负载后续发送
//找到源,发送http头,负载后续发送
sendResponse
(
"200 OK"
,
false
,
HttpFileManager
::
getContentType
(
".flv"
).
data
(),
KeyValue
(),
nullptr
,
true
);
sendResponse
(
200
,
false
,
HttpFileManager
::
getContentType
(
".flv"
).
data
(),
KeyValue
(),
nullptr
,
true
);
}
else
{
}
else
{
//自定义发送http头
//自定义发送http头
cb
();
cb
();
...
@@ -375,18 +376,18 @@ void HttpSession::Handle_Req_GET_l(int64_t &content_len, bool sendBody) {
...
@@ -375,18 +376,18 @@ void HttpSession::Handle_Req_GET_l(int64_t &content_len, bool sendBody) {
bool
bClose
=
!
strcasecmp
(
_parser
[
"Connection"
].
data
(),
"close"
);
bool
bClose
=
!
strcasecmp
(
_parser
[
"Connection"
].
data
(),
"close"
);
weak_ptr
<
HttpSession
>
weakSelf
=
dynamic_pointer_cast
<
HttpSession
>
(
shared_from_this
());
weak_ptr
<
HttpSession
>
weakSelf
=
dynamic_pointer_cast
<
HttpSession
>
(
shared_from_this
());
HttpFileManager
::
onAccessPath
(
*
this
,
_parser
,
[
weakSelf
,
bClose
](
const
string
&
status_
code
,
const
string
&
content_type
,
HttpFileManager
::
onAccessPath
(
*
this
,
_parser
,
[
weakSelf
,
bClose
](
int
code
,
const
string
&
content_type
,
const
StrCaseMap
&
responseHeader
,
const
HttpBody
::
Ptr
&
body
)
{
const
StrCaseMap
&
responseHeader
,
const
HttpBody
::
Ptr
&
body
)
{
auto
strongSelf
=
weakSelf
.
lock
();
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
if
(
!
strongSelf
)
{
return
;
return
;
}
}
strongSelf
->
async
([
weakSelf
,
bClose
,
status_
code
,
content_type
,
responseHeader
,
body
]()
{
strongSelf
->
async
([
weakSelf
,
bClose
,
code
,
content_type
,
responseHeader
,
body
]()
{
auto
strongSelf
=
weakSelf
.
lock
();
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
if
(
!
strongSelf
)
{
return
;
return
;
}
}
strongSelf
->
sendResponse
(
status_code
.
data
()
,
bClose
,
content_type
.
data
(),
responseHeader
,
body
);
strongSelf
->
sendResponse
(
code
,
bClose
,
content_type
.
data
(),
responseHeader
,
body
);
});
});
});
});
}
}
...
@@ -480,7 +481,7 @@ static const string kContentLength = "Content-Length";
...
@@ -480,7 +481,7 @@ static const string kContentLength = "Content-Length";
static
const
string
kAccessControlAllowOrigin
=
"Access-Control-Allow-Origin"
;
static
const
string
kAccessControlAllowOrigin
=
"Access-Control-Allow-Origin"
;
static
const
string
kAccessControlAllowCredentials
=
"Access-Control-Allow-Credentials"
;
static
const
string
kAccessControlAllowCredentials
=
"Access-Control-Allow-Credentials"
;
void
HttpSession
::
sendResponse
(
const
char
*
pcStatus
,
void
HttpSession
::
sendResponse
(
int
code
,
bool
bClose
,
bool
bClose
,
const
char
*
pcContentType
,
const
char
*
pcContentType
,
const
HttpSession
::
KeyValue
&
header
,
const
HttpSession
::
KeyValue
&
header
,
...
@@ -543,7 +544,7 @@ void HttpSession::sendResponse(const char *pcStatus,
...
@@ -543,7 +544,7 @@ void HttpSession::sendResponse(const char *pcStatus,
string
str
;
string
str
;
str
.
reserve
(
256
);
str
.
reserve
(
256
);
str
+=
"HTTP/1.1 "
;
str
+=
"HTTP/1.1 "
;
str
+=
pcStatus
;
str
+=
getHttpStatusMessage
(
code
)
;
str
+=
"
\r\n
"
;
str
+=
"
\r\n
"
;
for
(
auto
&
pr
:
header
)
{
for
(
auto
&
pr
:
header
)
{
str
+=
pr
.
first
;
str
+=
pr
.
first
;
...
@@ -558,7 +559,7 @@ void HttpSession::sendResponse(const char *pcStatus,
...
@@ -558,7 +559,7 @@ void HttpSession::sendResponse(const char *pcStatus,
if
(
!
size
){
if
(
!
size
){
//没有body
//没有body
if
(
bClose
){
if
(
bClose
){
shutdown
(
SockException
(
Err_shutdown
,
StrPrinter
<<
"close connection after send http header completed with status code:"
<<
pcStatus
));
shutdown
(
SockException
(
Err_shutdown
,
StrPrinter
<<
"close connection after send http header completed with status code:"
<<
code
));
}
}
return
;
return
;
}
}
...
@@ -600,18 +601,18 @@ bool HttpSession::emitHttpEvent(bool doInvoke){
...
@@ -600,18 +601,18 @@ bool HttpSession::emitHttpEvent(bool doInvoke){
bool
bClose
=
!
strcasecmp
(
_parser
[
"Connection"
].
data
(),
"close"
);
bool
bClose
=
!
strcasecmp
(
_parser
[
"Connection"
].
data
(),
"close"
);
/////////////////////异步回复Invoker///////////////////////////////
/////////////////////异步回复Invoker///////////////////////////////
weak_ptr
<
HttpSession
>
weakSelf
=
dynamic_pointer_cast
<
HttpSession
>
(
shared_from_this
());
weak_ptr
<
HttpSession
>
weakSelf
=
dynamic_pointer_cast
<
HttpSession
>
(
shared_from_this
());
HttpResponseInvoker
invoker
=
[
weakSelf
,
bClose
](
const
string
&
codeOut
,
const
KeyValue
&
headerOut
,
const
HttpBody
::
Ptr
&
body
){
HttpResponseInvoker
invoker
=
[
weakSelf
,
bClose
](
int
code
,
const
KeyValue
&
headerOut
,
const
HttpBody
::
Ptr
&
body
){
auto
strongSelf
=
weakSelf
.
lock
();
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
if
(
!
strongSelf
)
{
return
;
return
;
}
}
strongSelf
->
async
([
weakSelf
,
bClose
,
codeOut
,
headerOut
,
body
]()
{
strongSelf
->
async
([
weakSelf
,
bClose
,
code
,
headerOut
,
body
]()
{
auto
strongSelf
=
weakSelf
.
lock
();
auto
strongSelf
=
weakSelf
.
lock
();
if
(
!
strongSelf
)
{
if
(
!
strongSelf
)
{
//本对象已经销毁
//本对象已经销毁
return
;
return
;
}
}
strongSelf
->
sendResponse
(
code
Out
.
data
()
,
bClose
,
nullptr
,
headerOut
,
body
);
strongSelf
->
sendResponse
(
code
,
bClose
,
nullptr
,
headerOut
,
body
);
});
});
};
};
///////////////////广播HTTP事件///////////////////////////
///////////////////广播HTTP事件///////////////////////////
...
@@ -619,7 +620,7 @@ bool HttpSession::emitHttpEvent(bool doInvoke){
...
@@ -619,7 +620,7 @@ bool HttpSession::emitHttpEvent(bool doInvoke){
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastHttpRequest
,
_parser
,
invoker
,
consumed
,
static_cast
<
SockInfo
&>
(
*
this
));
NoticeCenter
::
Instance
().
emitEvent
(
Broadcast
::
kBroadcastHttpRequest
,
_parser
,
invoker
,
consumed
,
static_cast
<
SockInfo
&>
(
*
this
));
if
(
!
consumed
&&
doInvoke
){
if
(
!
consumed
&&
doInvoke
){
//该事件无人消费,所以返回404
//该事件无人消费,所以返回404
invoker
(
"404 Not Found"
,
KeyValue
(),
HttpBody
::
Ptr
());
invoker
(
404
,
KeyValue
(),
HttpBody
::
Ptr
());
}
}
return
consumed
;
return
consumed
;
}
}
...
@@ -690,7 +691,7 @@ void HttpSession::Handle_Req_POST(int64_t &content_len) {
...
@@ -690,7 +691,7 @@ void HttpSession::Handle_Req_POST(int64_t &content_len) {
void
HttpSession
::
sendNotFound
(
bool
bClose
)
{
void
HttpSession
::
sendNotFound
(
bool
bClose
)
{
GET_CONFIG
(
string
,
notFound
,
Http
::
kNotFound
);
GET_CONFIG
(
string
,
notFound
,
Http
::
kNotFound
);
sendResponse
(
"404 Not Found"
,
bClose
,
"text/html"
,
KeyValue
(),
std
::
make_shared
<
HttpStringBody
>
(
notFound
));
sendResponse
(
404
,
bClose
,
"text/html"
,
KeyValue
(),
std
::
make_shared
<
HttpStringBody
>
(
notFound
));
}
}
void
HttpSession
::
setSocketFlags
(){
void
HttpSession
::
setSocketFlags
(){
...
...
src/Http/HttpSession.h
查看文件 @
13221ad7
...
@@ -116,7 +116,7 @@ private:
...
@@ -116,7 +116,7 @@ private:
bool
emitHttpEvent
(
bool
doInvoke
);
bool
emitHttpEvent
(
bool
doInvoke
);
void
urlDecode
(
Parser
&
parser
);
void
urlDecode
(
Parser
&
parser
);
void
sendNotFound
(
bool
bClose
);
void
sendNotFound
(
bool
bClose
);
void
sendResponse
(
const
char
*
pcStatus
,
bool
bClose
,
const
char
*
pcContentType
=
nullptr
,
void
sendResponse
(
int
code
,
bool
bClose
,
const
char
*
pcContentType
=
nullptr
,
const
HttpSession
::
KeyValue
&
header
=
HttpSession
::
KeyValue
(),
const
HttpSession
::
KeyValue
&
header
=
HttpSession
::
KeyValue
(),
const
HttpBody
::
Ptr
&
body
=
nullptr
,
bool
no_content_length
=
false
);
const
HttpBody
::
Ptr
&
body
=
nullptr
,
bool
no_content_length
=
false
);
...
...
tests/test_httpApi.cpp
查看文件 @
13221ad7
...
@@ -79,7 +79,7 @@ void initEventListener(){
...
@@ -79,7 +79,7 @@ void initEventListener(){
//请勿覆盖Connection、Content-Length键
//请勿覆盖Connection、Content-Length键
//键名覆盖时不区分大小写
//键名覆盖时不区分大小写
headerOut
[
"TestHeader"
]
=
"HeaderValue"
;
headerOut
[
"TestHeader"
]
=
"HeaderValue"
;
invoker
(
"200 OK"
,
headerOut
,
contentOut
);
invoker
(
200
,
headerOut
,
contentOut
);
});
});
});
});
},
nullptr
);
},
nullptr
);
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论