瀏覽代碼

ft: 代码修改

master
SisMaker 3 年之前
父節點
當前提交
7357069eea
共有 7 個檔案被更改,包括 82 行新增76 行删除
  1. +25
    -19
      include/eWSrv.hrl
  2. +11
    -12
      include/wsCom.hrl
  3. +6
    -2
      src/eWSrv.erl
  4. +6
    -6
      src/wsSrv/wsHer.erl
  5. +10
    -11
      src/wsSrv/wsHttp.erl
  6. +23
    -25
      src/wsSrv/wsHttpProtocol.erl
  7. +1
    -1
      src/wsSrv/wsTPHer.erl

+ 25
- 19
include/eWSrv.hrl 查看文件

@ -2,40 +2,46 @@
-export_type([wsOpt/0]).
-type wsOpt() ::
listenOpt() |
{wsMod, module()}.
listenOpt() | %% eNet相关配置
{wsMod, module()} | %%
{maxSize, infinity | pos_integer()} | %% Content-Length的最大值 infinity
{chunkedSupp, boolean()}. %% Transfer-Encoding
-record(wsReq, {
method :: method(),
method :: wsMethod(),
path :: binary(),
version :: wsHttp:version(),
version :: wsHttp:wsVersion(),
scheme :: undefined | binary(),
host :: undefined | binary(),
port :: undefined | 1..65535,
socket :: inet:socket() | ssl:sslsocket(),
args :: [{binary(), any()}],
headers :: headers(),
body = <<>> :: body()
headers :: wsHeaders(),
body = <<>> :: wsBody()
}).
-export_type([
wsReq/0
, method/0
, body/0
, path/0
, headers/0
, httpCode/0
, version/0
, wsMethod/0
, wsBody/0
, wsPath/0
, wsHeaders/0
, wsHttpCode/0
, wsVersion/0
, header_key/0
, wsSocket/0
]).
-type wsReq() :: #wsReq{}.
-type method() :: 'OPTIONS' | 'GET' | 'HEAD' | 'POST'| 'PUT' | 'DELETE' | 'TRACE' | binary().
-type body() :: binary() | iolist().
-type path() :: binary().
-type header() :: {Key :: binary(), Value :: binary() | string()}.
-type headers() :: [header()].
-type httpCode() :: 100..999.
-type version() :: {0, 9} | {1, 0} | {1, 1}.
-type wsMethod() :: 'OPTIONS' | 'GET' | 'HEAD' | 'POST'| 'PUT' | 'DELETE' | 'TRACE' | binary().
-type wsBody() :: binary() | iolist().
-type wsPath() :: binary().
-type wsHeader() :: {Key :: binary(), Value :: binary() | string()}.
-type wsHeaders() :: [wsHeader()].
-type wsHttpCode() :: 100..999.
-type wsVersion() :: {0, 9} | {1, 0} | {1, 1}.
-type wsSocket() :: inet:socket() | ssl:sslsocket().
-define(CONTENT_LENGTH_HEADER, 'Content-Length').
-define(CONNECTION_HEADER, 'Connection').

+ 11
- 12
include/wsCom.hrl 查看文件

@ -27,22 +27,21 @@
-type sendfile_opts() :: [{chunk_size, non_neg_integer()}].
-type stage() :: reqLine | header | body | done. %% http请求可能会有多个包
-type stage() :: reqLine | wsHeader | wsBody | done. %% http请求可能会有多个包
-record(wsState, {
stage = reqLine :: stage() %%
, buffer = <<>> :: binary() %%
, wsReq :: undefined | #wsReq{} %% http
, headerCnt = 0 :: pos_integer() %% header计数
, temHeader = [] :: [headers()] %% header临时数据
, temHeader = [] :: [wsHeaders()] %% header临时数据
, contentLength :: undefined | non_neg_integer() | chunked %%
, temChunked = <<>> :: binary()
, method :: method()
, path :: binary()
, rn :: undefined | binary:cp()
, socket :: undefined | wsNet:socket()
, isSsl = false :: boolean()
, wsMod :: module()
, maxSize = infinity :: pos_integer() %%
, maxChunkCnt = 0 :: pos_integer() %% chunk
, maxRecvCnt = 0 :: pos_integer() %% recv最大的次数
, temChunked = <<>> :: binary() %% chunked
, method :: wsMethod() %% method
, path :: binary() %% URL
, rn :: undefined | binary:cp() %% binary:cp()
, socket :: undefined | inet:socket() | ssl:sslsocket() %% socket
, isSsl = false :: boolean() %% ssl
, wsMod :: module() %%
, maxSize = infinity :: pos_integer() %%
, chunkedSupp = false :: boolean() %% chunked
}).

+ 6
- 2
src/eWSrv.erl 查看文件

@ -23,7 +23,9 @@ wSrvName(Port) ->
openSrv(Port, WsOpts) ->
T1WsOpts = lists:keystore(conMod, 1, WsOpts, {conMod, wsHttp}),
WsMod = ?wsGLV(wsMod, WsOpts, wsTPHer),
T2WsOpts = lists:keystore(conArgs, 1, T1WsOpts, {conArgs, WsMod}),
MaxSize = ?wsGLV(maxSize, WsOpts, infinity),
ChunkedSupp = ?wsGLV(chunkedSupp, WsOpts, false),
T2WsOpts = lists:keystore(conArgs, 1, T1WsOpts, {conArgs, {WsMod, MaxSize, ChunkedSupp}}),
TcpOpts = ?wsGLV(tcpOpts, T2WsOpts, []),
NewTcpOpts = wsUtil:mergeOpts(?DefWsOpts, TcpOpts),
LWsOpts = lists:keystore(tcpOpts, 1, T2WsOpts, {tcpOpts, NewTcpOpts}),
@ -40,7 +42,9 @@ openSrv(Port, WsOpts) ->
openSrv(WSrvName, Port, WsOpts) ->
T1WsOpts = lists:keystore(conMod, 1, WsOpts, {conMod, wsHttp}),
WsMod = ?wsGLV(wsMod, WsOpts, wsTPHer),
T2WsOpts = lists:keystore(conArgs, 1, T1WsOpts, {conArgs, WsMod}),
MaxSize = ?wsGLV(maxSize, WsOpts, infinity),
ChunkedSupp = ?wsGLV(chunkedSupp, WsOpts, false),
T2WsOpts = lists:keystore(conArgs, 1, T1WsOpts, {conArgs, {WsMod, MaxSize, ChunkedSupp}}),
TcpOpts = ?wsGLV(tcpOpts, T2WsOpts, []),
NewTcpOpts = wsUtil:mergeOpts(?DefWsOpts, TcpOpts),
LWsOpts = lists:keystore(tcpOpts, 1, T2WsOpts, {tcpOpts, NewTcpOpts}),

+ 6
- 6
src/wsSrv/wsHer.erl 查看文件

@ -7,11 +7,11 @@
]).
-type response() ::
{httpCode() | ok, body()}|
{httpCode() | ok, headers(), body()}|
{httpCode() | ok, headers(), {file, file:name_all()}|
{wsHttpCode() | ok, wsBody()}|
{wsHttpCode() | ok, wsHeaders(), wsBody()}|
{wsHttpCode() | ok, wsHeaders(), {file, file:name_all()}|
{file, file:name_all(), wsUtil:range()}}|
{chunk, headers()}|
{chunk, headers(), body()}.
{chunk, wsHeaders()}|
{chunk, wsHeaders(), wsBody()}.
-callback handle(Method :: method(), Path :: binary(), Req :: wsReq()) -> response().
-callback handle(Method :: wsMethod(), Path :: binary(), Req :: wsReq()) -> response().

+ 10
- 11
src/wsSrv/wsHttp.erl 查看文件

@ -26,13 +26,13 @@
, system_terminate/4
]).
newConn(_Sock, WsMod) ->
?MODULE:start_link(WsMod).
newConn(_Sock, ConnArgs) ->
?MODULE:start_link(ConnArgs).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% genActor start %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-spec(start_link(atom()) -> {ok, pid()} | ignore | {error, term()}).
start_link(WsMod) ->
proc_lib:start_link(?MODULE, init_it, [self(), WsMod], infinity, []).
start_link(ConnArgs) ->
proc_lib:start_link(?MODULE, init_it, [self(), ConnArgs], infinity, []).
init_it(Parent, Args) ->
process_flag(trap_exit, true),
@ -84,13 +84,12 @@ loop(Parent, State) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% genActor end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% ************************************************ API ***************************************************************
init(WsMod) ->
{ok, #wsState{wsMod = WsMod}}.
init({WsMod, MaxSize, ChunkedSupp}) ->
{ok, #wsState{wsMod = WsMod, maxSize = MaxSize, chunkedSupp = ChunkedSupp}}.
handleMsg({tcp, _Socket, Data}, State) ->
?wsWarn("IMY***************tcp data ~p ~n XXXXXXXXXXXX ~p ~n", [Data, State]),
#wsState{stage = Stage, buffer = Buffer, socket = Socket} = State,
case wsHttpProtocol:request(Stage, <<Buffer/binary, Data/binary>>, State) of
case wsHttpProtocol:request(Stage, <<Buffer/binary, Data/binary>>, Socket, State) of
{ok, _NewState} = LRet ->
LRet;
{done, NewState} ->
@ -120,7 +119,7 @@ handleMsg({tcp_error, _Socket, Reason}, _State) ->
handleMsg({ssl, _Socket, Data}, State) ->
#wsState{stage = Stage, buffer = Buffer, socket = Socket} = State,
case wsHttpProtocol:request(Stage, <<Buffer/binary, Data/binary>>, State) of
case wsHttpProtocol:request(Stage, <<Buffer/binary, Data/binary>>, Socket, State) of
{ok, _NewState} = LRet ->
LRet;
{done, NewState} ->
@ -290,8 +289,8 @@ sendResponse(Socket, Method, Code, Headers, UserBody) ->
%% and headers.
-spec sendFile(Req, Code, Headers, Filename, Range) -> ok when
Req :: elli:wsReq(),
Code :: elli:httpCode(),
Headers :: elli:headers(),
Code :: elli:wsHttpCode(),
Headers :: elli:wsHeaders(),
Filename :: file:filename(),
Range :: wsUtil:range().
sendFile(Socket, Code, Headers, Filename, Range) ->

+ 23
- 25
src/wsSrv/wsHttpProtocol.erl 查看文件

@ -5,22 +5,21 @@
-compile(inline).
-compile({inline_size, 128}).
-export([request/3]).
-export([request/4]).
-spec request(Stage :: stage(), Data :: binary(), State :: #wsState{}) -> {ok, NewState :: #wsState{}} | {done, NewState :: #wsState{}} | {error, term()}.
request(reqLine, Data, State) ->
-spec request(Stage :: stage(), Data :: binary(), wsSocket(), State :: #wsState{}) -> {ok, NewState :: #wsState{}} | {done, NewState :: #wsState{}} | {error, term()}.
request(reqLine, Data, Socket, State) ->
case erlang:decode_packet(http_bin, Data, []) of
{more, _} ->
{ok, State#wsState{buffer = Data}};
{ok, {http_request, Method, RawPath, Version}, Rest} ->
?wsErr("IMY**************11111 ~p~n", [{http_request, Method, RawPath, Version}]),
case parsePath(RawPath) of
{ok, Scheme, Host, Port, Path, URLArgs} ->
case Rest of
<<>> ->
{ok, State#wsState{stage = header, buffer = <<>>, method = Method, path = Path, wsReq = #wsReq{method = Method, path = Path, version = Version, scheme = Scheme, host = Host, port = Port, args = URLArgs}}};
{ok, State#wsState{stage = header, buffer = <<>>, method = Method, path = Path, socket = Socket, wsReq = #wsReq{method = Method, path = Path, version = Version, scheme = Scheme, host = Host, port = Port, args = URLArgs}}};
_ ->
request(header, Rest, State#wsState{stage = header, buffer = Rest, method = Method, path = Path, wsReq = #wsReq{method = Method, path = Path, version = Version, scheme = Scheme, host = Host, port = Port, args = URLArgs}})
request(header, Rest, Socket, State#wsState{stage = header, buffer = Rest, method = Method, path = Path, wsReq = #wsReq{method = Method, path = Path, version = Version, scheme = Scheme, host = Host, port = Port, args = URLArgs}})
end;
_Err ->
_Err
@ -32,12 +31,12 @@ request(reqLine, Data, State) ->
{error, _Reason} = Ret ->
Ret
end;
request(header, Data, State) ->
request(header, Data, Socket, State) ->
case erlang:decode_packet(httph_bin, Data, []) of
{more, _} ->
{ok, State#wsState{buffer = Data}};
{ok, {http_header, _, Key, _, Value}, Rest} ->
#wsState{headerCnt = HeaderCnt, temHeader = TemHeader, rn = Rn, maxSize = MaxSize} = State,
#wsState{headerCnt = HeaderCnt, temHeader = TemHeader, rn = Rn, maxSize = MaxSize, chunkedSupp = ChunkedSupp} = State,
NewTemHeader = [{Key, Value} | TemHeader],
NewHeaderCnt = HeaderCnt + 1,
case NewHeaderCnt >= 100 of
@ -51,29 +50,28 @@ request(header, Data, State) ->
true ->
{err_code, 413};
_ ->
request(header, Rest, State#wsState{buffer = Rest, headerCnt = NewHeaderCnt, temHeader = NewTemHeader, contentLength = ContentLength})
request(header, Rest, Socket, State#wsState{buffer = Rest, headerCnt = NewHeaderCnt, temHeader = NewTemHeader, contentLength = ContentLength})
end;
'Transfer-Encoding' ->
case Value of
<<"chunked">> ->
case Rn of
undefined ->
request(header, Rest, State#wsState{buffer = Rest, headerCnt = NewHeaderCnt, temHeader = NewTemHeader, contentLength = chunked, rn = binary:compile_pattern(<<"\r\n">>)});
_ ->
request(header, Rest, State#wsState{buffer = Rest, headerCnt = NewHeaderCnt, temHeader = NewTemHeader, contentLength = chunked})
end;
<<"Chunked">> ->
case Rn of
undefined ->
request(header, Rest, State#wsState{buffer = Rest, headerCnt = NewHeaderCnt, temHeader = NewTemHeader, contentLength = chunked, rn = binary:compile_pattern(<<"\r\n">>)});
IsChunked = ?IIF(Value == <<"chunked">> orelse Value == <<"Chunked">>, true, false),
case IsChunked of
true ->
case ChunkedSupp of
true ->
case Rn of
undefined ->
request(header, Rest, Socket, State#wsState{buffer = Rest, headerCnt = NewHeaderCnt, temHeader = NewTemHeader, contentLength = chunked, rn = binary:compile_pattern(<<"\r\n">>)});
_ ->
request(header, Rest, Socket, State#wsState{buffer = Rest, headerCnt = NewHeaderCnt, temHeader = NewTemHeader, contentLength = chunked})
end;
_ ->
request(header, Rest, State#wsState{buffer = Rest, headerCnt = NewHeaderCnt, temHeader = NewTemHeader, contentLength = chunked})
{error, not_support_chunked}
end;
_ ->
{error, 'Transfer-Encoding'}
end;
_ ->
request(header, Rest, State#wsState{buffer = Rest, headerCnt = NewHeaderCnt, temHeader = NewTemHeader})
request(header, Rest, Socket, State#wsState{buffer = Rest, headerCnt = NewHeaderCnt, temHeader = NewTemHeader})
end
end;
{ok, http_eoh, Rest} ->
@ -89,7 +87,7 @@ request(header, Data, State) ->
<<>> ->
{ok, State#wsState{stage = body, buffer = <<>>, wsReq = NewWsReq}};
_ ->
request(body, Rest, State#wsState{stage = body, buffer = Rest, wsReq = NewWsReq})
request(body, Rest, Socket, State#wsState{stage = body, buffer = Rest, wsReq = NewWsReq})
end
end;
{ok, {http_error, ErrStr}, _Rest} ->
@ -97,7 +95,7 @@ request(header, Data, State) ->
{error, _Reason} = Ret ->
Ret
end;
request(body, Data, State) ->
request(body, Data, _Socket, State) ->
#wsState{contentLength = CLen, wsReq = WsReq, temChunked = TemChunked, rn = Rn} = State,
case CLen of
chunked ->

+ 1
- 1
src/wsSrv/wsTPHer.erl 查看文件

@ -13,7 +13,7 @@
chunk_loop/1
]).
-spec handle(Method :: method(), Path :: path(), WsReq :: wsReq()) -> wsHer:response().
-spec handle(Method :: wsMethod(), Path :: wsPath(), WsReq :: wsReq()) -> wsHer:response().
handle('GET', <<"/hello/world">>, WsReq) ->
io:format("IMY************XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ~n receive WsReq: ~p~n", [WsReq]),
%% Reply with a normal response.

Loading…
取消
儲存