This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088
Fork of libMiMic by
core/net/httpd/mod/NyLPC_cModWebSocket.c@72:c118a7aa37a3, 2014-06-13 (annotated)
- Committer:
- nyatla
- Date:
- Fri Jun 13 11:06:33 2014 +0000
- Revision:
- 72:c118a7aa37a3
- Parent:
- 71:855020258513
- Child:
- 82:03c645af0bb1
mbedAPI???????
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
nyatla | 57:bc4330dfa62f | 1 | /********************************************************************************* |
nyatla | 57:bc4330dfa62f | 2 | * PROJECT: MiMic |
nyatla | 57:bc4330dfa62f | 3 | * -------------------------------------------------------------------------------- |
nyatla | 57:bc4330dfa62f | 4 | * |
nyatla | 57:bc4330dfa62f | 5 | * This file is part of MiMic |
nyatla | 57:bc4330dfa62f | 6 | * Copyright (C)2011 Ryo Iizuka |
nyatla | 57:bc4330dfa62f | 7 | * |
nyatla | 57:bc4330dfa62f | 8 | * MiMic is free software: you can redistribute it and/or modify |
nyatla | 57:bc4330dfa62f | 9 | * it under the terms of the GNU Lesser General Public License as published |
nyatla | 57:bc4330dfa62f | 10 | * by the Free Software Foundation, either version 3 of the License, or |
nyatla | 57:bc4330dfa62f | 11 | * (at your option) any later version. |
nyatla | 57:bc4330dfa62f | 12 | * |
nyatla | 57:bc4330dfa62f | 13 | * This program is distributed in the hope that it will be useful, |
nyatla | 57:bc4330dfa62f | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
nyatla | 57:bc4330dfa62f | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
nyatla | 57:bc4330dfa62f | 16 | * GNU General Public License for more details. |
nyatla | 57:bc4330dfa62f | 17 | * |
nyatla | 57:bc4330dfa62f | 18 | * You should have received a copy of the GNU Lesser General Public License |
nyatla | 57:bc4330dfa62f | 19 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
nyatla | 57:bc4330dfa62f | 20 | * |
nyatla | 57:bc4330dfa62f | 21 | * For further information please contact. |
nyatla | 57:bc4330dfa62f | 22 | * http://nyatla.jp/ |
nyatla | 57:bc4330dfa62f | 23 | * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> |
nyatla | 57:bc4330dfa62f | 24 | * |
nyatla | 57:bc4330dfa62f | 25 | *********************************************************************************/ |
nyatla | 58:03b89038b21a | 26 | #include "NyLPC_cModWebSocket_protected.h" |
nyatla | 57:bc4330dfa62f | 27 | #include "NyLPC_utils.h" |
nyatla | 57:bc4330dfa62f | 28 | |
nyatla | 58:03b89038b21a | 29 | #define HTTP_TIMEOUT NyLPC_TiHttpPtrStream_DEFAULT_HTTP_TIMEOUT |
nyatla | 57:bc4330dfa62f | 30 | |
nyatla | 57:bc4330dfa62f | 31 | #define NyLPC_TcModWebSocket_FRAME_TYPE_BIN 0x01 |
nyatla | 57:bc4330dfa62f | 32 | #define NyLPC_TcModWebSocket_FRAME_TYPE_TXT 0x02 |
nyatla | 57:bc4330dfa62f | 33 | |
nyatla | 57:bc4330dfa62f | 34 | |
nyatla | 57:bc4330dfa62f | 35 | |
nyatla | 57:bc4330dfa62f | 36 | #define STRBUF_MAX 32 |
nyatla | 57:bc4330dfa62f | 37 | struct TModWebSocketHeader |
nyatla | 57:bc4330dfa62f | 38 | { |
nyatla | 57:bc4330dfa62f | 39 | struct NyLPC_THttpBasicHeader super; |
nyatla | 57:bc4330dfa62f | 40 | NyLPC_TcStr_t _tstr; |
nyatla | 57:bc4330dfa62f | 41 | NyLPC_TChar _tstr_buf[STRBUF_MAX]; |
nyatla | 57:bc4330dfa62f | 42 | NyLPC_TChar key[24+4]; |
nyatla | 57:bc4330dfa62f | 43 | NyLPC_TInt16 version; |
nyatla | 57:bc4330dfa62f | 44 | NyLPC_TUInt8 sub_protocol_id; |
nyatla | 57:bc4330dfa62f | 45 | NyLPC_TUInt8 message_id; |
nyatla | 57:bc4330dfa62f | 46 | const NyLPC_TChar* _ref_sub_protocol; |
nyatla | 57:bc4330dfa62f | 47 | }; |
nyatla | 57:bc4330dfa62f | 48 | |
nyatla | 57:bc4330dfa62f | 49 | |
nyatla | 57:bc4330dfa62f | 50 | |
nyatla | 57:bc4330dfa62f | 51 | #define MESSAGE_ID_UNKNOWN 0x00 |
nyatla | 57:bc4330dfa62f | 52 | #define MESSAGE_ID_UPGRADE 0x01 |
nyatla | 57:bc4330dfa62f | 53 | #define MESSAGE_ID_SEC_WEBSOCKET_KEY 0x02 |
nyatla | 57:bc4330dfa62f | 54 | #define MESSAGE_ID_ORIGIN 0x03 |
nyatla | 57:bc4330dfa62f | 55 | #define MESSAGE_ID_SEC_WEBSOCKET_PROTOCL 0x04 |
nyatla | 57:bc4330dfa62f | 56 | #define MESSAGE_ID_SEC_WEBSOCKET_VERSION 0x05 |
nyatla | 57:bc4330dfa62f | 57 | |
nyatla | 57:bc4330dfa62f | 58 | static const struct NyLPC_TTextIdTbl msg_tbl[]= |
nyatla | 57:bc4330dfa62f | 59 | { |
nyatla | 57:bc4330dfa62f | 60 | {"Upgrade",MESSAGE_ID_UPGRADE}, |
nyatla | 57:bc4330dfa62f | 61 | {"Sec-WebSocket-Key",MESSAGE_ID_SEC_WEBSOCKET_KEY}, |
nyatla | 57:bc4330dfa62f | 62 | {"Origin",MESSAGE_ID_ORIGIN}, |
nyatla | 57:bc4330dfa62f | 63 | {"Sec-WebSocket-Protocol",MESSAGE_ID_SEC_WEBSOCKET_PROTOCL}, |
nyatla | 57:bc4330dfa62f | 64 | {"Sec-WebSocket-Version",MESSAGE_ID_SEC_WEBSOCKET_VERSION}, |
nyatla | 57:bc4330dfa62f | 65 | {NULL,MESSAGE_ID_UNKNOWN} |
nyatla | 57:bc4330dfa62f | 66 | }; |
nyatla | 57:bc4330dfa62f | 67 | |
nyatla | 57:bc4330dfa62f | 68 | static NyLPC_TBool messageHandler(NyLPC_TcHttpBasicHeaderParser_t* i_inst,const NyLPC_TChar* i_name,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out) |
nyatla | 57:bc4330dfa62f | 69 | { |
nyatla | 57:bc4330dfa62f | 70 | struct TModWebSocketHeader* out=(struct TModWebSocketHeader*)o_out; |
nyatla | 57:bc4330dfa62f | 71 | if(i_name!=NULL){ |
nyatla | 57:bc4330dfa62f | 72 | out->message_id=NyLPC_TTextIdTbl_getMatchIdIgnoreCase(i_name,msg_tbl); |
nyatla | 57:bc4330dfa62f | 73 | NyLPC_cStr_clear(&(out->_tstr)); |
nyatla | 57:bc4330dfa62f | 74 | }else{ |
nyatla | 57:bc4330dfa62f | 75 | switch(out->message_id) |
nyatla | 57:bc4330dfa62f | 76 | { |
nyatla | 57:bc4330dfa62f | 77 | case MESSAGE_ID_UPGRADE: |
nyatla | 57:bc4330dfa62f | 78 | if(i_c!='\0'){ |
nyatla | 57:bc4330dfa62f | 79 | if(!NyLPC_cStr_put(&(out->_tstr),i_c)){ |
nyatla | 57:bc4330dfa62f | 80 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 57:bc4330dfa62f | 81 | } |
nyatla | 57:bc4330dfa62f | 82 | }else{ |
nyatla | 57:bc4330dfa62f | 83 | //websocketかチェック |
nyatla | 57:bc4330dfa62f | 84 | if(!NyLPC_cStr_isEqualIgnoreCase(&out->_tstr,"websocket")){ |
nyatla | 57:bc4330dfa62f | 85 | return NyLPC_TBool_FALSE;//不一致 |
nyatla | 57:bc4330dfa62f | 86 | } |
nyatla | 57:bc4330dfa62f | 87 | } |
nyatla | 57:bc4330dfa62f | 88 | break; |
nyatla | 57:bc4330dfa62f | 89 | case MESSAGE_ID_SEC_WEBSOCKET_KEY: |
nyatla | 57:bc4330dfa62f | 90 | if(i_c!='\0'){ |
nyatla | 57:bc4330dfa62f | 91 | if(!NyLPC_cStr_put(&(out->_tstr),i_c)){ |
nyatla | 57:bc4330dfa62f | 92 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 57:bc4330dfa62f | 93 | } |
nyatla | 57:bc4330dfa62f | 94 | }else{ |
nyatla | 57:bc4330dfa62f | 95 | //HASH値をコピー |
nyatla | 57:bc4330dfa62f | 96 | strcpy(out->key,NyLPC_cStr_str(&out->_tstr)); |
nyatla | 57:bc4330dfa62f | 97 | } |
nyatla | 57:bc4330dfa62f | 98 | break; |
nyatla | 57:bc4330dfa62f | 99 | case MESSAGE_ID_SEC_WEBSOCKET_PROTOCL: |
nyatla | 57:bc4330dfa62f | 100 | if(i_c!='\0' && i_c!=','){ |
nyatla | 57:bc4330dfa62f | 101 | if(!NyLPC_cStr_put(&(out->_tstr),i_c)){ |
nyatla | 57:bc4330dfa62f | 102 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 57:bc4330dfa62f | 103 | } |
nyatla | 57:bc4330dfa62f | 104 | }else{ |
nyatla | 57:bc4330dfa62f | 105 | //トークン終端 |
nyatla | 57:bc4330dfa62f | 106 | if(out->_ref_sub_protocol!=NULL){ |
nyatla | 57:bc4330dfa62f | 107 | //サブプロトコルが指定されている場合はチェック |
nyatla | 57:bc4330dfa62f | 108 | if(NyLPC_stricmp(NyLPC_cStr_str(&out->_tstr),out->_ref_sub_protocol)==0){ |
nyatla | 57:bc4330dfa62f | 109 | out->sub_protocol_id=1;//SubProtocol一致 |
nyatla | 57:bc4330dfa62f | 110 | } |
nyatla | 57:bc4330dfa62f | 111 | } |
nyatla | 57:bc4330dfa62f | 112 | //','の時はリセット |
nyatla | 57:bc4330dfa62f | 113 | if(i_c!=','){ |
nyatla | 57:bc4330dfa62f | 114 | NyLPC_cStr_clear(&(out->_tstr)); |
nyatla | 57:bc4330dfa62f | 115 | } |
nyatla | 57:bc4330dfa62f | 116 | } |
nyatla | 57:bc4330dfa62f | 117 | break; |
nyatla | 57:bc4330dfa62f | 118 | case MESSAGE_ID_SEC_WEBSOCKET_VERSION: |
nyatla | 57:bc4330dfa62f | 119 | if(i_c!='\0'){ |
nyatla | 57:bc4330dfa62f | 120 | if(!NyLPC_cStr_put(&(out->_tstr),i_c)){ |
nyatla | 57:bc4330dfa62f | 121 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 57:bc4330dfa62f | 122 | } |
nyatla | 57:bc4330dfa62f | 123 | }else{ |
nyatla | 57:bc4330dfa62f | 124 | //VERSION |
nyatla | 57:bc4330dfa62f | 125 | out->version=atoi(NyLPC_cStr_str(&out->_tstr)); |
nyatla | 57:bc4330dfa62f | 126 | if(out->version<0){ |
nyatla | 57:bc4330dfa62f | 127 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 57:bc4330dfa62f | 128 | } |
nyatla | 57:bc4330dfa62f | 129 | } |
nyatla | 57:bc4330dfa62f | 130 | } |
nyatla | 57:bc4330dfa62f | 131 | } |
nyatla | 57:bc4330dfa62f | 132 | return NyLPC_TBool_TRUE; |
nyatla | 57:bc4330dfa62f | 133 | ERROR: |
nyatla | 57:bc4330dfa62f | 134 | return NyLPC_TBool_FALSE; |
nyatla | 57:bc4330dfa62f | 135 | } |
nyatla | 57:bc4330dfa62f | 136 | |
nyatla | 57:bc4330dfa62f | 137 | |
nyatla | 57:bc4330dfa62f | 138 | |
nyatla | 57:bc4330dfa62f | 139 | |
nyatla | 57:bc4330dfa62f | 140 | /** |
nyatla | 57:bc4330dfa62f | 141 | * デフォルトハンドラ |
nyatla | 57:bc4330dfa62f | 142 | */ |
nyatla | 57:bc4330dfa62f | 143 | static const struct NyLPC_TcHttpBasicHeaderParser_Handler handler= |
nyatla | 57:bc4330dfa62f | 144 | { |
nyatla | 57:bc4330dfa62f | 145 | messageHandler, |
nyatla | 57:bc4330dfa62f | 146 | NULL |
nyatla | 57:bc4330dfa62f | 147 | }; |
nyatla | 58:03b89038b21a | 148 | |
nyatla | 57:bc4330dfa62f | 149 | |
nyatla | 57:bc4330dfa62f | 150 | |
nyatla | 57:bc4330dfa62f | 151 | /** |
nyatla | 57:bc4330dfa62f | 152 | * コンストラクタ。 |
nyatla | 57:bc4330dfa62f | 153 | */ |
nyatla | 57:bc4330dfa62f | 154 | void NyLPC_cModWebSocket_initialize(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_ref_root_path) |
nyatla | 57:bc4330dfa62f | 155 | { |
nyatla | 57:bc4330dfa62f | 156 | NyLPC_cModRomFiles_initialize(&i_inst->super,i_ref_root_path,NULL,0); |
nyatla | 57:bc4330dfa62f | 157 | i_inst->_frame_type=NyLPC_TcModWebSocket_FRAME_TYPE_TXT; |
nyatla | 57:bc4330dfa62f | 158 | i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED; |
nyatla | 57:bc4330dfa62f | 159 | } |
nyatla | 57:bc4330dfa62f | 160 | void NyLPC_cModWebSocket_finalize(NyLPC_TcModWebSocket_t* i_inst) |
nyatla | 57:bc4330dfa62f | 161 | { |
nyatla | 57:bc4330dfa62f | 162 | NyLPC_cModRomFiles_finalize(&i_inst->super); |
nyatla | 57:bc4330dfa62f | 163 | } |
nyatla | 57:bc4330dfa62f | 164 | /** |
nyatla | 57:bc4330dfa62f | 165 | * モジュールがコネクションをハンドリングできるかを返します。 |
nyatla | 57:bc4330dfa62f | 166 | */ |
nyatla | 57:bc4330dfa62f | 167 | NyLPC_TBool NyLPC_cModWebSocket_canHandle(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TcHttpdConnection_t* i_connection) |
nyatla | 57:bc4330dfa62f | 168 | { |
nyatla | 57:bc4330dfa62f | 169 | return NyLPC_cModRomFiles_canHandle(&i_inst->super,i_connection); |
nyatla | 57:bc4330dfa62f | 170 | } |
nyatla | 57:bc4330dfa62f | 171 | |
nyatla | 57:bc4330dfa62f | 172 | static union{ |
nyatla | 57:bc4330dfa62f | 173 | struct TModWebSocketHeader header; |
nyatla | 57:bc4330dfa62f | 174 | }work; |
nyatla | 57:bc4330dfa62f | 175 | |
nyatla | 57:bc4330dfa62f | 176 | |
nyatla | 57:bc4330dfa62f | 177 | |
nyatla | 57:bc4330dfa62f | 178 | /** |
nyatla | 57:bc4330dfa62f | 179 | * モジュールを実行します。 |
nyatla | 57:bc4330dfa62f | 180 | */ |
nyatla | 57:bc4330dfa62f | 181 | NyLPC_TBool NyLPC_cModWebSocket_execute(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TcHttpdConnection_t* i_connection) |
nyatla | 57:bc4330dfa62f | 182 | { |
nyatla | 57:bc4330dfa62f | 183 | union{ |
nyatla | 57:bc4330dfa62f | 184 | NyLPC_TcHttpBasicHeaderParser_t parser; |
nyatla | 57:bc4330dfa62f | 185 | SHA1_CTX sh1; |
nyatla | 57:bc4330dfa62f | 186 | }sh; |
nyatla | 57:bc4330dfa62f | 187 | |
nyatla | 57:bc4330dfa62f | 188 | //リクエストParse済へ遷移(この関数の後はModが責任を持ってリクエストを返却) |
nyatla | 57:bc4330dfa62f | 189 | NyLPC_cHttpdConnection_setReqStatusParsed(i_connection); |
nyatla | 57:bc4330dfa62f | 190 | |
nyatla | 57:bc4330dfa62f | 191 | |
nyatla | 57:bc4330dfa62f | 192 | |
nyatla | 57:bc4330dfa62f | 193 | //排他ロック |
nyatla | 57:bc4330dfa62f | 194 | NyLPC_cHttpdConnection_lock(i_connection); |
nyatla | 57:bc4330dfa62f | 195 | {//parser |
nyatla | 57:bc4330dfa62f | 196 | |
nyatla | 57:bc4330dfa62f | 197 | //初期化 |
nyatla | 57:bc4330dfa62f | 198 | work.header.version=0; |
nyatla | 57:bc4330dfa62f | 199 | work.header.sub_protocol_id=0; |
nyatla | 57:bc4330dfa62f | 200 | NyLPC_cStr_initialize(&work.header._tstr,work.header._tstr_buf,STRBUF_MAX); |
nyatla | 57:bc4330dfa62f | 201 | |
nyatla | 57:bc4330dfa62f | 202 | NyLPC_cHttpBasicHeaderParser_initialize(&sh.parser,&handler); |
nyatla | 57:bc4330dfa62f | 203 | |
nyatla | 57:bc4330dfa62f | 204 | //プリフェッチしたデータを流す |
nyatla | 57:bc4330dfa62f | 205 | NyLPC_cHttpBasicHeaderParser_parseInit(&sh.parser,&(work.header.super)); |
nyatla | 57:bc4330dfa62f | 206 | NyLPC_cHttpdConnection_pushPrefetchInfo(i_connection,&sh.parser,&work.header.super); |
nyatla | 57:bc4330dfa62f | 207 | //後続をストリームから取り込む |
nyatla | 57:bc4330dfa62f | 208 | if(!NyLPC_cHttpBasicHeaderParser_parseStream(&sh.parser,NyLPC_cHttpdConnection_refStream(i_connection),&(work.header.super))){ |
nyatla | 57:bc4330dfa62f | 209 | NyLPC_cHttpdUtils_sendErrorResponse(i_connection,500); |
nyatla | 57:bc4330dfa62f | 210 | NyLPC_OnErrorGoto(Error1); |
nyatla | 57:bc4330dfa62f | 211 | } |
nyatla | 57:bc4330dfa62f | 212 | if(!NyLPC_cHttpBasicHeaderParser_parseFinish(&sh.parser,&(work.header.super))){ |
nyatla | 57:bc4330dfa62f | 213 | NyLPC_cHttpdUtils_sendErrorResponse(i_connection,500); |
nyatla | 57:bc4330dfa62f | 214 | NyLPC_OnErrorGoto(Error1); |
nyatla | 57:bc4330dfa62f | 215 | } |
nyatla | 57:bc4330dfa62f | 216 | //HeaderParserはここで破棄(URLEncode,cSTRも) |
nyatla | 57:bc4330dfa62f | 217 | NyLPC_cHttpBasicHeaderParser_finalize(&sh.parser); |
nyatla | 57:bc4330dfa62f | 218 | |
nyatla | 57:bc4330dfa62f | 219 | NyLPC_cStr_finalize(&single_header._tstr); |
nyatla | 57:bc4330dfa62f | 220 | |
nyatla | 57:bc4330dfa62f | 221 | |
nyatla | 57:bc4330dfa62f | 222 | //HTTP/1.1であること。Connection:Upgradeはチェックしない。 |
nyatla | 57:bc4330dfa62f | 223 | if(work.header.super.startline.req.version!=NyLPC_THttpVersion_11) |
nyatla | 57:bc4330dfa62f | 224 | { |
nyatla | 57:bc4330dfa62f | 225 | NyLPC_cHttpdUtils_sendErrorResponse(i_connection,400); |
nyatla | 57:bc4330dfa62f | 226 | NyLPC_OnErrorGoto(Error2); |
nyatla | 57:bc4330dfa62f | 227 | } |
nyatla | 57:bc4330dfa62f | 228 | if(NyLPC_cHttpdConnection_getMethod(i_connection)!=NyLPC_THttpMethodType_GET){ |
nyatla | 57:bc4330dfa62f | 229 | NyLPC_cHttpdUtils_sendErrorResponse(i_connection,400); |
nyatla | 57:bc4330dfa62f | 230 | NyLPC_OnErrorGoto(Error2); |
nyatla | 57:bc4330dfa62f | 231 | } |
nyatla | 57:bc4330dfa62f | 232 | //WebSocket version 13であること |
nyatla | 57:bc4330dfa62f | 233 | if(work.header.version!=13){ |
nyatla | 57:bc4330dfa62f | 234 | NyLPC_cHttpdUtils_sendErrorResponse(i_connection,400); |
nyatla | 57:bc4330dfa62f | 235 | NyLPC_OnErrorGoto(Error2); |
nyatla | 57:bc4330dfa62f | 236 | } |
nyatla | 57:bc4330dfa62f | 237 | |
nyatla | 57:bc4330dfa62f | 238 | //レスポンスの生成(生データを直接ストリームへ書きこむ) |
nyatla | 57:bc4330dfa62f | 239 | if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_connection), |
nyatla | 57:bc4330dfa62f | 240 | "HTTP/1.1 101 Switching Protocols\r\n" //32+2 |
nyatla | 57:bc4330dfa62f | 241 | "Upgrade: websocket\r\n" //18+2 |
nyatla | 57:bc4330dfa62f | 242 | "Connection: Upgrade\r\n" //19+2 |
nyatla | 57:bc4330dfa62f | 243 | "Sec-WebSocket-Accept: " //22 |
nyatla | 57:bc4330dfa62f | 244 | ,32+2+18+2+19+2+22)){ |
nyatla | 57:bc4330dfa62f | 245 | NyLPC_OnErrorGoto(Error3); |
nyatla | 57:bc4330dfa62f | 246 | } |
nyatla | 57:bc4330dfa62f | 247 | //SH1キーの生成 |
nyatla | 57:bc4330dfa62f | 248 | SHA1Init(&sh.sh1); |
nyatla | 57:bc4330dfa62f | 249 | SHA1Update(&sh.sh1,(const unsigned char*)work.header.key,strlen(work.header.key)); |
nyatla | 57:bc4330dfa62f | 250 | SHA1Update(&sh.sh1,(const unsigned char*)"258EAFA5-E914-47DA-95CA-C5AB0DC85B11",36); |
nyatla | 57:bc4330dfa62f | 251 | //ワークメモリ32バイトはstrの使いまわし |
nyatla | 57:bc4330dfa62f | 252 | SHA1Final((unsigned char*)(work.header._tstr_buf),&sh.sh1); |
nyatla | 57:bc4330dfa62f | 253 | //BASE64化(single_header.keyへ出力) |
nyatla | 57:bc4330dfa62f | 254 | NyLPC_cBase64_encode(work.header._tstr_buf,20,work.header.key); |
nyatla | 57:bc4330dfa62f | 255 | if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_connection),work.header.key,28)){ |
nyatla | 57:bc4330dfa62f | 256 | NyLPC_OnErrorGoto(Error3); |
nyatla | 57:bc4330dfa62f | 257 | } |
nyatla | 57:bc4330dfa62f | 258 | //SubProtocolの認証が有る場合 |
nyatla | 57:bc4330dfa62f | 259 | if(work.header.sub_protocol_id!=0){ |
nyatla | 57:bc4330dfa62f | 260 | if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_connection) |
nyatla | 57:bc4330dfa62f | 261 | ,"\r\nSec-WebSocket-Protocol: " //24 |
nyatla | 57:bc4330dfa62f | 262 | ,24)){ |
nyatla | 57:bc4330dfa62f | 263 | NyLPC_OnErrorGoto(Error3); |
nyatla | 57:bc4330dfa62f | 264 | } |
nyatla | 57:bc4330dfa62f | 265 | if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_connection) |
nyatla | 57:bc4330dfa62f | 266 | ,work.header._ref_sub_protocol |
nyatla | 57:bc4330dfa62f | 267 | ,strlen(work.header._ref_sub_protocol))) |
nyatla | 57:bc4330dfa62f | 268 | { |
nyatla | 57:bc4330dfa62f | 269 | NyLPC_OnErrorGoto(Error3); |
nyatla | 57:bc4330dfa62f | 270 | } |
nyatla | 57:bc4330dfa62f | 271 | } |
nyatla | 57:bc4330dfa62f | 272 | //Sec-WebSocket-Protocol |
nyatla | 57:bc4330dfa62f | 273 | if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_connection),"\r\n\r\n",4)){ |
nyatla | 57:bc4330dfa62f | 274 | NyLPC_OnErrorGoto(Error3); |
nyatla | 57:bc4330dfa62f | 275 | } |
nyatla | 58:03b89038b21a | 276 | //connection phase |
nyatla | 57:bc4330dfa62f | 277 | i_inst->_payload_st=NyLPC_TcModWebSocket_ST_START_PAYLOAD; |
nyatla | 57:bc4330dfa62f | 278 | } |
nyatla | 57:bc4330dfa62f | 279 | //占有解除 |
nyatla | 57:bc4330dfa62f | 280 | NyLPC_cHttpdConnection_unlock(i_connection); |
nyatla | 57:bc4330dfa62f | 281 | //参照コネクションの設定 |
nyatla | 57:bc4330dfa62f | 282 | i_inst->_ref_connection=i_connection; |
nyatla | 57:bc4330dfa62f | 283 | NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection)); |
nyatla | 57:bc4330dfa62f | 284 | return NyLPC_TBool_TRUE; |
nyatla | 57:bc4330dfa62f | 285 | Error3: |
nyatla | 57:bc4330dfa62f | 286 | Error2: |
nyatla | 57:bc4330dfa62f | 287 | //VM排他ロックの解除 |
nyatla | 57:bc4330dfa62f | 288 | NyLPC_cHttpdConnection_unlock(i_connection); |
nyatla | 57:bc4330dfa62f | 289 | return NyLPC_TBool_FALSE; |
nyatla | 57:bc4330dfa62f | 290 | Error1: |
nyatla | 57:bc4330dfa62f | 291 | NyLPC_cHttpBasicHeaderParser_finalize(&parser); |
nyatla | 57:bc4330dfa62f | 292 | NyLPC_cStr_finalize(&single_header._tstr); |
nyatla | 57:bc4330dfa62f | 293 | //VM排他ロックの解除 |
nyatla | 57:bc4330dfa62f | 294 | NyLPC_cHttpdConnection_unlock(i_connection); |
nyatla | 57:bc4330dfa62f | 295 | return NyLPC_TBool_FALSE; |
nyatla | 57:bc4330dfa62f | 296 | } |
nyatla | 57:bc4330dfa62f | 297 | |
nyatla | 57:bc4330dfa62f | 298 | |
nyatla | 57:bc4330dfa62f | 299 | |
nyatla | 57:bc4330dfa62f | 300 | static void writeClosePacket(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TUInt16 i_code) |
nyatla | 57:bc4330dfa62f | 301 | { |
nyatla | 57:bc4330dfa62f | 302 | char w[4]; |
nyatla | 57:bc4330dfa62f | 303 | w[0]=0x88; |
nyatla | 57:bc4330dfa62f | 304 | w[1]=0x02; |
nyatla | 57:bc4330dfa62f | 305 | *((NyLPC_TUInt16*)(&w[2]))=NyLPC_htons(i_code); //REASON |
nyatla | 57:bc4330dfa62f | 306 | //CloseFrame送信 |
nyatla | 57:bc4330dfa62f | 307 | NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),w,4); |
nyatla | 57:bc4330dfa62f | 308 | NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection)); |
nyatla | 57:bc4330dfa62f | 309 | } |
nyatla | 57:bc4330dfa62f | 310 | |
nyatla | 57:bc4330dfa62f | 311 | |
nyatla | 58:03b89038b21a | 312 | NyLPC_TBool NyLPC_cModWebSocket_canRead(const NyLPC_TcModWebSocket_t* i_inst) |
nyatla | 57:bc4330dfa62f | 313 | { |
nyatla | 57:bc4330dfa62f | 314 | const NyLPC_TUInt8* rx; |
nyatla | 58:03b89038b21a | 315 | return NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx,0)>0; |
nyatla | 58:03b89038b21a | 316 | } |
nyatla | 58:03b89038b21a | 317 | |
nyatla | 58:03b89038b21a | 318 | #define FLAGS_MASK_BIT 7 |
nyatla | 58:03b89038b21a | 319 | |
nyatla | 58:03b89038b21a | 320 | /** |
nyatla | 58:03b89038b21a | 321 | * Websocketの状態を更新します。 |
nyatla | 58:03b89038b21a | 322 | * @return |
nyatla | 58:03b89038b21a | 323 | */ |
nyatla | 58:03b89038b21a | 324 | void NyLPC_cModWebSocket_update(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TUInt32 i_time_out) |
nyatla | 58:03b89038b21a | 325 | { |
nyatla | 58:03b89038b21a | 326 | const NyLPC_TUInt8* rx; |
nyatla | 58:03b89038b21a | 327 | NyLPC_TInt32 rs; |
nyatla | 57:bc4330dfa62f | 328 | NyLPC_TUInt16 header_size; |
nyatla | 57:bc4330dfa62f | 329 | NyLPC_TUInt8 w8[2]; |
nyatla | 57:bc4330dfa62f | 330 | if(i_inst->_payload_st==NyLPC_TcModWebSocket_ST_CLOSED){ |
nyatla | 58:03b89038b21a | 331 | return; |
nyatla | 57:bc4330dfa62f | 332 | } |
nyatla | 57:bc4330dfa62f | 333 | START: |
nyatla | 58:03b89038b21a | 334 | rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx,i_time_out); |
nyatla | 58:03b89038b21a | 335 | |
nyatla | 57:bc4330dfa62f | 336 | //Error? |
nyatla | 57:bc4330dfa62f | 337 | if(rs<0){ |
nyatla | 57:bc4330dfa62f | 338 | NyLPC_OnErrorGoto(Error); |
nyatla | 57:bc4330dfa62f | 339 | } |
nyatla | 57:bc4330dfa62f | 340 | //Timeout? |
nyatla | 57:bc4330dfa62f | 341 | if(rs==0){ |
nyatla | 57:bc4330dfa62f | 342 | goto Timeout; |
nyatla | 57:bc4330dfa62f | 343 | } |
nyatla | 57:bc4330dfa62f | 344 | switch(i_inst->_payload_st){ |
nyatla | 58:03b89038b21a | 345 | case NyLPC_TcModWebSocket_ST_READ_PAYLOAD: |
nyatla | 58:03b89038b21a | 346 | //ペイロード読み出し中破何もしない |
nyatla | 58:03b89038b21a | 347 | return; |
nyatla | 57:bc4330dfa62f | 348 | case NyLPC_TcModWebSocket_ST_START_PAYLOAD: |
nyatla | 57:bc4330dfa62f | 349 | //ペイロード |
nyatla | 57:bc4330dfa62f | 350 | //2バイト溜まるまで待つ |
nyatla | 57:bc4330dfa62f | 351 | if(rs<2){ |
nyatla | 57:bc4330dfa62f | 352 | //Timeout? |
nyatla | 57:bc4330dfa62f | 353 | goto Timeout; |
nyatla | 57:bc4330dfa62f | 354 | } |
nyatla | 57:bc4330dfa62f | 355 | //ペイロードサイズの分析 |
nyatla | 57:bc4330dfa62f | 356 | if((0x7f&rx[1])<=125){ |
nyatla | 57:bc4330dfa62f | 357 | header_size=2+(((rx[1]&0x80)==0x80)?4:0); |
nyatla | 57:bc4330dfa62f | 358 | i_inst->payload_size=(0x7f&rx[1]); |
nyatla | 57:bc4330dfa62f | 359 | }else if((0x7f&rx[1])==126){ |
nyatla | 57:bc4330dfa62f | 360 | if(rs<4){ |
nyatla | 57:bc4330dfa62f | 361 | //Timeout? |
nyatla | 57:bc4330dfa62f | 362 | goto Timeout; |
nyatla | 57:bc4330dfa62f | 363 | } |
nyatla | 57:bc4330dfa62f | 364 | header_size=2+2+(((rx[1]&0x80)==0x80)?4:0); |
nyatla | 57:bc4330dfa62f | 365 | i_inst->payload_size=(rx[2]<<8)|rx[3]; |
nyatla | 57:bc4330dfa62f | 366 | }else{ |
nyatla | 57:bc4330dfa62f | 367 | //CLOSEの送信 |
nyatla | 57:bc4330dfa62f | 368 | writeClosePacket(i_inst,1009); |
nyatla | 57:bc4330dfa62f | 369 | NyLPC_OnErrorGoto(Error); |
nyatla | 57:bc4330dfa62f | 370 | } |
nyatla | 57:bc4330dfa62f | 371 | //十分なヘッダが集まったかチェック |
nyatla | 57:bc4330dfa62f | 372 | if(rs<header_size){ |
nyatla | 57:bc4330dfa62f | 373 | goto Timeout; |
nyatla | 57:bc4330dfa62f | 374 | } |
nyatla | 57:bc4330dfa62f | 375 | i_inst->_frame_flags_bits=0; |
nyatla | 57:bc4330dfa62f | 376 | //FINがセットされていること.断片化禁止! |
nyatla | 57:bc4330dfa62f | 377 | if((rx[0]&0x80)!=0x80){ |
nyatla | 57:bc4330dfa62f | 378 | NyLPC_OnErrorGoto(Error); |
nyatla | 57:bc4330dfa62f | 379 | } |
nyatla | 57:bc4330dfa62f | 380 | //必要ならMaskをコピー |
nyatla | 57:bc4330dfa62f | 381 | if((rx[1]&0x80)==0x80){ |
nyatla | 57:bc4330dfa62f | 382 | memcpy(i_inst->_frame_mask,(rx+header_size-4),4); |
nyatla | 57:bc4330dfa62f | 383 | NyLPC_TUInt8_setBit(i_inst->_frame_flags_bits,FLAGS_MASK_BIT); |
nyatla | 57:bc4330dfa62f | 384 | } |
nyatla | 57:bc4330dfa62f | 385 | i_inst->payload_ptr=0; |
nyatla | 57:bc4330dfa62f | 386 | |
nyatla | 57:bc4330dfa62f | 387 | //パケットサイズの確定(基本ヘッダ+マスク) |
nyatla | 57:bc4330dfa62f | 388 | switch(rx[0]&0x0f){ |
nyatla | 57:bc4330dfa62f | 389 | case 0x00: |
nyatla | 57:bc4330dfa62f | 390 | //継続パケットは扱わない |
nyatla | 57:bc4330dfa62f | 391 | NyLPC_OnErrorGoto(Error); |
nyatla | 57:bc4330dfa62f | 392 | case 0x01: |
nyatla | 57:bc4330dfa62f | 393 | if(i_inst->_frame_type!=NyLPC_TcModWebSocket_FRAME_TYPE_TXT){ |
nyatla | 57:bc4330dfa62f | 394 | NyLPC_OnErrorGoto(Error); |
nyatla | 57:bc4330dfa62f | 395 | } |
nyatla | 57:bc4330dfa62f | 396 | break; |
nyatla | 57:bc4330dfa62f | 397 | case 0x02: |
nyatla | 57:bc4330dfa62f | 398 | if(i_inst->_frame_type==NyLPC_TcModWebSocket_FRAME_TYPE_BIN){ |
nyatla | 57:bc4330dfa62f | 399 | NyLPC_OnErrorGoto(Error); |
nyatla | 57:bc4330dfa62f | 400 | } |
nyatla | 57:bc4330dfa62f | 401 | break; |
nyatla | 57:bc4330dfa62f | 402 | case 0x08://close(非断片) |
nyatla | 57:bc4330dfa62f | 403 | //CloseFrame送信 |
nyatla | 57:bc4330dfa62f | 404 | writeClosePacket(i_inst,1009); |
nyatla | 57:bc4330dfa62f | 405 | //Errorとして処理 |
nyatla | 57:bc4330dfa62f | 406 | NyLPC_OnErrorGoto(Error); |
nyatla | 57:bc4330dfa62f | 407 | case 0x09://ping(非断片) |
nyatla | 57:bc4330dfa62f | 408 | //PONGを送信 |
nyatla | 57:bc4330dfa62f | 409 | w8[0]=0x0a; |
nyatla | 57:bc4330dfa62f | 410 | NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),w8,1); |
nyatla | 57:bc4330dfa62f | 411 | NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rx+1,header_size-1); |
nyatla | 57:bc4330dfa62f | 412 | NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection)); |
nyatla | 57:bc4330dfa62f | 413 | NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),header_size); |
nyatla | 57:bc4330dfa62f | 414 | while(i_inst->payload_size!=i_inst->payload_ptr){ |
nyatla | 58:03b89038b21a | 415 | rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx,HTTP_TIMEOUT); |
nyatla | 57:bc4330dfa62f | 416 | if(rs<=0){ |
nyatla | 57:bc4330dfa62f | 417 | if(rs<0){ |
nyatla | 57:bc4330dfa62f | 418 | //Error |
nyatla | 57:bc4330dfa62f | 419 | NyLPC_OnErrorGoto(Error); |
nyatla | 57:bc4330dfa62f | 420 | } |
nyatla | 57:bc4330dfa62f | 421 | //Timeout |
nyatla | 57:bc4330dfa62f | 422 | goto Timeout; |
nyatla | 57:bc4330dfa62f | 423 | } |
nyatla | 57:bc4330dfa62f | 424 | //読み込みサイズを決定 |
nyatla | 57:bc4330dfa62f | 425 | NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rx,rs); |
nyatla | 57:bc4330dfa62f | 426 | NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rs); |
nyatla | 57:bc4330dfa62f | 427 | i_inst->payload_ptr+=rs; |
nyatla | 57:bc4330dfa62f | 428 | } |
nyatla | 57:bc4330dfa62f | 429 | //Timeout(パケットスタートに戻る?) |
nyatla | 57:bc4330dfa62f | 430 | goto START; |
nyatla | 57:bc4330dfa62f | 431 | case 0x0a://pong(非断片) |
nyatla | 57:bc4330dfa62f | 432 | //パケットの読み捨て |
nyatla | 57:bc4330dfa62f | 433 | NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),header_size); |
nyatla | 57:bc4330dfa62f | 434 | while(i_inst->payload_size!=i_inst->payload_ptr){ |
nyatla | 58:03b89038b21a | 435 | rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx,HTTP_TIMEOUT); |
nyatla | 57:bc4330dfa62f | 436 | if(rs<=0){ |
nyatla | 57:bc4330dfa62f | 437 | if(rs<0){ |
nyatla | 57:bc4330dfa62f | 438 | //Error |
nyatla | 57:bc4330dfa62f | 439 | NyLPC_OnErrorGoto(Error); |
nyatla | 57:bc4330dfa62f | 440 | } |
nyatla | 57:bc4330dfa62f | 441 | //Timeout |
nyatla | 57:bc4330dfa62f | 442 | goto Timeout; |
nyatla | 57:bc4330dfa62f | 443 | } |
nyatla | 57:bc4330dfa62f | 444 | //読み込みサイズを決定 |
nyatla | 57:bc4330dfa62f | 445 | NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rs); |
nyatla | 57:bc4330dfa62f | 446 | i_inst->payload_ptr+=rs; |
nyatla | 57:bc4330dfa62f | 447 | } |
nyatla | 57:bc4330dfa62f | 448 | //Timeout(パケットスタートに戻る?) |
nyatla | 57:bc4330dfa62f | 449 | goto START; |
nyatla | 57:bc4330dfa62f | 450 | default: |
nyatla | 57:bc4330dfa62f | 451 | //知らないコードはエラー |
nyatla | 57:bc4330dfa62f | 452 | NyLPC_OnErrorGoto(Error); |
nyatla | 57:bc4330dfa62f | 453 | } |
nyatla | 57:bc4330dfa62f | 454 | //読み出し位置のシーク(Header部) |
nyatla | 57:bc4330dfa62f | 455 | NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),header_size); |
nyatla | 57:bc4330dfa62f | 456 | //ペイロード読み出しへ |
nyatla | 57:bc4330dfa62f | 457 | i_inst->_payload_st=NyLPC_TcModWebSocket_ST_READ_PAYLOAD; |
nyatla | 57:bc4330dfa62f | 458 | //継続してペイロード受信処理 |
nyatla | 58:03b89038b21a | 459 | return; |
nyatla | 58:03b89038b21a | 460 | } |
nyatla | 58:03b89038b21a | 461 | //処理されなければエラー |
nyatla | 58:03b89038b21a | 462 | Error: |
nyatla | 58:03b89038b21a | 463 | NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection); |
nyatla | 58:03b89038b21a | 464 | i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED; |
nyatla | 58:03b89038b21a | 465 | return; |
nyatla | 58:03b89038b21a | 466 | Timeout: |
nyatla | 58:03b89038b21a | 467 | return; |
nyatla | 58:03b89038b21a | 468 | } |
nyatla | 58:03b89038b21a | 469 | |
nyatla | 71:855020258513 | 470 | |
nyatla | 71:855020258513 | 471 | /** |
nyatla | 71:855020258513 | 472 | * 受信データをコールバック関数に通知するNyLPC_cModWebSocket_readです。 |
nyatla | 71:855020258513 | 473 | * @return |
nyatla | 71:855020258513 | 474 | * n>0:データ受信 |
nyatla | 71:855020258513 | 475 | * 0 :タイムアウト。コネクションの状態は変化しない。 |
nyatla | 71:855020258513 | 476 | * -1 :エラー コネクションはNyLPC_TcModWebSocket_ST_CLOSEDへ遷移する。 |
nyatla | 71:855020258513 | 477 | */ |
nyatla | 71:855020258513 | 478 | NyLPC_TInt16 NyLPC_cModWebSocket_readCB(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TcModWebSocket_onRreadCB i_cb,void* i_cb_param) |
nyatla | 71:855020258513 | 479 | { |
nyatla | 71:855020258513 | 480 | const NyLPC_TUInt8* rx; |
nyatla | 71:855020258513 | 481 | NyLPC_TInt32 rs,rd,i; |
nyatla | 71:855020258513 | 482 | //ストリームの状態を更新する。 |
nyatla | 71:855020258513 | 483 | NyLPC_cModWebSocket_update(i_inst,HTTP_TIMEOUT); |
nyatla | 71:855020258513 | 484 | |
nyatla | 71:855020258513 | 485 | switch(i_inst->_payload_st) |
nyatla | 71:855020258513 | 486 | { |
nyatla | 71:855020258513 | 487 | case NyLPC_TcModWebSocket_ST_READ_PAYLOAD: |
nyatla | 71:855020258513 | 488 | break;//処理継続 |
nyatla | 71:855020258513 | 489 | case NyLPC_TcModWebSocket_ST_START_PAYLOAD: |
nyatla | 71:855020258513 | 490 | //タイムアウト扱い |
nyatla | 71:855020258513 | 491 | return 0; |
nyatla | 71:855020258513 | 492 | default: |
nyatla | 71:855020258513 | 493 | return -1; |
nyatla | 71:855020258513 | 494 | } |
nyatla | 71:855020258513 | 495 | //読み出し可能なデータをパース |
nyatla | 71:855020258513 | 496 | rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx,HTTP_TIMEOUT); |
nyatla | 71:855020258513 | 497 | if(rs<=0){ |
nyatla | 71:855020258513 | 498 | if(rs<0){ |
nyatla | 71:855020258513 | 499 | //Error |
nyatla | 71:855020258513 | 500 | NyLPC_OnErrorGoto(Error); |
nyatla | 71:855020258513 | 501 | } |
nyatla | 71:855020258513 | 502 | //Timeout |
nyatla | 71:855020258513 | 503 | goto Timeout; |
nyatla | 71:855020258513 | 504 | } |
nyatla | 71:855020258513 | 505 | rd=0;//読みだしたバイト数 |
nyatla | 71:855020258513 | 506 | //アンマスク |
nyatla | 71:855020258513 | 507 | if(NyLPC_TUInt8_isBitOn(i_inst->_frame_flags_bits,FLAGS_MASK_BIT)){ |
nyatla | 71:855020258513 | 508 | //マスク有の時 |
nyatla | 71:855020258513 | 509 | for(i=0;i<rs;i++){ |
nyatla | 71:855020258513 | 510 | rd++; |
nyatla | 71:855020258513 | 511 | switch(i_cb(i_cb_param,rx[i]^i_inst->_frame_mask[(i_inst->payload_ptr+i)%4])){ |
nyatla | 71:855020258513 | 512 | case 1: |
nyatla | 71:855020258513 | 513 | continue; |
nyatla | 71:855020258513 | 514 | case 0: |
nyatla | 71:855020258513 | 515 | break; |
nyatla | 71:855020258513 | 516 | default: |
nyatla | 71:855020258513 | 517 | NyLPC_OnErrorGoto(Error); |
nyatla | 71:855020258513 | 518 | } |
nyatla | 71:855020258513 | 519 | } |
nyatla | 71:855020258513 | 520 | }else{ |
nyatla | 71:855020258513 | 521 | //マスクなしの時 |
nyatla | 71:855020258513 | 522 | for(i=0;i<rs;i++){ |
nyatla | 71:855020258513 | 523 | rd++; |
nyatla | 71:855020258513 | 524 | switch(i_cb(i_cb_param,rx[i])){ |
nyatla | 71:855020258513 | 525 | case 1: |
nyatla | 71:855020258513 | 526 | continue; |
nyatla | 71:855020258513 | 527 | case 0: |
nyatla | 71:855020258513 | 528 | break; |
nyatla | 71:855020258513 | 529 | default: |
nyatla | 71:855020258513 | 530 | NyLPC_OnErrorGoto(Error); |
nyatla | 71:855020258513 | 531 | } |
nyatla | 71:855020258513 | 532 | } |
nyatla | 71:855020258513 | 533 | } |
nyatla | 71:855020258513 | 534 | //読取位置を移動 |
nyatla | 71:855020258513 | 535 | NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rd); |
nyatla | 71:855020258513 | 536 | i_inst->payload_ptr+=rd; |
nyatla | 71:855020258513 | 537 | if(i_inst->payload_size==i_inst->payload_ptr){ |
nyatla | 71:855020258513 | 538 | i_inst->_payload_st=NyLPC_TcModWebSocket_ST_START_PAYLOAD; |
nyatla | 71:855020258513 | 539 | } |
nyatla | 71:855020258513 | 540 | return rd; |
nyatla | 71:855020258513 | 541 | //処理されなければエラー |
nyatla | 71:855020258513 | 542 | Error: |
nyatla | 71:855020258513 | 543 | NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection); |
nyatla | 71:855020258513 | 544 | i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED; |
nyatla | 71:855020258513 | 545 | return -1; |
nyatla | 71:855020258513 | 546 | Timeout: |
nyatla | 71:855020258513 | 547 | return 0; |
nyatla | 71:855020258513 | 548 | } |
nyatla | 71:855020258513 | 549 | |
nyatla | 58:03b89038b21a | 550 | /** |
nyatla | 58:03b89038b21a | 551 | * @return |
nyatla | 58:03b89038b21a | 552 | * n>0:データ受信 |
nyatla | 58:03b89038b21a | 553 | * 0 :タイムアウト。コネクションの状態は変化しない。 |
nyatla | 58:03b89038b21a | 554 | * -1 :エラー コネクションはNyLPC_TcModWebSocket_ST_CLOSEDへ遷移する。 |
nyatla | 58:03b89038b21a | 555 | */ |
nyatla | 58:03b89038b21a | 556 | NyLPC_TInt16 NyLPC_cModWebSocket_read(NyLPC_TcModWebSocket_t* i_inst,void* i_buf,NyLPC_TInt16 i_buf_len) |
nyatla | 58:03b89038b21a | 557 | { |
nyatla | 58:03b89038b21a | 558 | const NyLPC_TUInt8* rx; |
nyatla | 58:03b89038b21a | 559 | NyLPC_TInt32 rs,i; |
nyatla | 58:03b89038b21a | 560 | //ストリームの状態を更新する。 |
nyatla | 58:03b89038b21a | 561 | NyLPC_cModWebSocket_update(i_inst,HTTP_TIMEOUT); |
nyatla | 58:03b89038b21a | 562 | |
nyatla | 58:03b89038b21a | 563 | switch(i_inst->_payload_st) |
nyatla | 58:03b89038b21a | 564 | { |
nyatla | 57:bc4330dfa62f | 565 | case NyLPC_TcModWebSocket_ST_READ_PAYLOAD: |
nyatla | 58:03b89038b21a | 566 | break;//処理継続 |
nyatla | 58:03b89038b21a | 567 | case NyLPC_TcModWebSocket_ST_START_PAYLOAD: |
nyatla | 58:03b89038b21a | 568 | //タイムアウト扱い |
nyatla | 58:03b89038b21a | 569 | return 0; |
nyatla | 58:03b89038b21a | 570 | default: |
nyatla | 58:03b89038b21a | 571 | return -1; |
nyatla | 58:03b89038b21a | 572 | } |
nyatla | 58:03b89038b21a | 573 | //読み出し可能なデータをパース |
nyatla | 58:03b89038b21a | 574 | rs=NyLPC_iHttpPtrStream_pread(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),(const void**)&rx,HTTP_TIMEOUT); |
nyatla | 58:03b89038b21a | 575 | if(rs<=0){ |
nyatla | 58:03b89038b21a | 576 | if(rs<0){ |
nyatla | 58:03b89038b21a | 577 | //Error |
nyatla | 58:03b89038b21a | 578 | NyLPC_OnErrorGoto(Error); |
nyatla | 57:bc4330dfa62f | 579 | } |
nyatla | 58:03b89038b21a | 580 | //Timeout |
nyatla | 58:03b89038b21a | 581 | goto Timeout; |
nyatla | 58:03b89038b21a | 582 | } |
nyatla | 58:03b89038b21a | 583 | //読み込みサイズを決定 |
nyatla | 58:03b89038b21a | 584 | rs=(rs<i_buf_len)?rs:i_buf_len; |
nyatla | 58:03b89038b21a | 585 | //アンマスク |
nyatla | 58:03b89038b21a | 586 | if(NyLPC_TUInt8_isBitOn(i_inst->_frame_flags_bits,FLAGS_MASK_BIT)){ |
nyatla | 58:03b89038b21a | 587 | for(i=0;i<rs;i++){ |
nyatla | 58:03b89038b21a | 588 | *(((NyLPC_TUInt8*)i_buf)+i)=rx[i]^i_inst->_frame_mask[(i_inst->payload_ptr+i)%4]; |
nyatla | 57:bc4330dfa62f | 589 | } |
nyatla | 58:03b89038b21a | 590 | }else{ |
nyatla | 58:03b89038b21a | 591 | memcpy(i_buf,rx,rs); |
nyatla | 57:bc4330dfa62f | 592 | } |
nyatla | 58:03b89038b21a | 593 | //読取位置を移動 |
nyatla | 58:03b89038b21a | 594 | NyLPC_iHttpPtrStream_rseek(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),rs); |
nyatla | 58:03b89038b21a | 595 | i_inst->payload_ptr+=rs; |
nyatla | 58:03b89038b21a | 596 | if(i_inst->payload_size==i_inst->payload_ptr){ |
nyatla | 58:03b89038b21a | 597 | i_inst->_payload_st=NyLPC_TcModWebSocket_ST_START_PAYLOAD; |
nyatla | 58:03b89038b21a | 598 | } |
nyatla | 58:03b89038b21a | 599 | return rs; |
nyatla | 57:bc4330dfa62f | 600 | //処理されなければエラー |
nyatla | 57:bc4330dfa62f | 601 | Error: |
nyatla | 57:bc4330dfa62f | 602 | NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection); |
nyatla | 57:bc4330dfa62f | 603 | i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED; |
nyatla | 57:bc4330dfa62f | 604 | return -1; |
nyatla | 57:bc4330dfa62f | 605 | Timeout: |
nyatla | 57:bc4330dfa62f | 606 | return 0; |
nyatla | 57:bc4330dfa62f | 607 | } |
nyatla | 57:bc4330dfa62f | 608 | |
nyatla | 58:03b89038b21a | 609 | |
nyatla | 58:03b89038b21a | 610 | |
nyatla | 58:03b89038b21a | 611 | |
nyatla | 57:bc4330dfa62f | 612 | static NyLPC_TBool fmt_handler(void* i_inst,const void* i_buf,NyLPC_TUInt32 i_len) |
nyatla | 57:bc4330dfa62f | 613 | { |
nyatla | 57:bc4330dfa62f | 614 | return NyLPC_iHttpPtrStream_write((NyLPC_TiHttpPtrStream_t*)i_inst,i_buf,i_len); |
nyatla | 57:bc4330dfa62f | 615 | } |
nyatla | 57:bc4330dfa62f | 616 | |
nyatla | 58:03b89038b21a | 617 | |
nyatla | 58:03b89038b21a | 618 | /** |
nyatla | 58:03b89038b21a | 619 | * Payloadヘッダを書く。 |
nyatla | 58:03b89038b21a | 620 | */ |
nyatla | 58:03b89038b21a | 621 | NyLPC_TBool NyLPC_cModWebSocket_writePayloadHeader(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TInt16 i_len) |
nyatla | 57:bc4330dfa62f | 622 | { |
nyatla | 57:bc4330dfa62f | 623 | NyLPC_TUInt16 s; |
nyatla | 57:bc4330dfa62f | 624 | NyLPC_TChar w[4]; |
nyatla | 58:03b89038b21a | 625 | //CLOSED,CONNECTの時は使用不可 |
nyatla | 58:03b89038b21a | 626 | switch(i_inst->_payload_st){ |
nyatla | 58:03b89038b21a | 627 | case NyLPC_TcModWebSocket_ST_CLOSED: |
nyatla | 57:bc4330dfa62f | 628 | return NyLPC_TBool_FALSE; |
nyatla | 58:03b89038b21a | 629 | default: |
nyatla | 57:bc4330dfa62f | 630 | break; |
nyatla | 57:bc4330dfa62f | 631 | } |
nyatla | 57:bc4330dfa62f | 632 | //データサイズで切り分け |
nyatla | 57:bc4330dfa62f | 633 | switch(i_inst->_frame_type) |
nyatla | 57:bc4330dfa62f | 634 | { |
nyatla | 57:bc4330dfa62f | 635 | case NyLPC_TcModWebSocket_FRAME_TYPE_TXT: |
nyatla | 57:bc4330dfa62f | 636 | w[0]=0x80|0x01; |
nyatla | 57:bc4330dfa62f | 637 | break; |
nyatla | 57:bc4330dfa62f | 638 | case NyLPC_TcModWebSocket_FRAME_TYPE_BIN: |
nyatla | 57:bc4330dfa62f | 639 | w[0]=0x80|0x02; |
nyatla | 57:bc4330dfa62f | 640 | break; |
nyatla | 57:bc4330dfa62f | 641 | default: |
nyatla | 57:bc4330dfa62f | 642 | NyLPC_OnErrorGoto(Error); |
nyatla | 57:bc4330dfa62f | 643 | } |
nyatla | 57:bc4330dfa62f | 644 | if(i_len<126){ |
nyatla | 57:bc4330dfa62f | 645 | w[1]=(NyLPC_TUInt8)i_len; |
nyatla | 57:bc4330dfa62f | 646 | s=2; |
nyatla | 57:bc4330dfa62f | 647 | }else{ |
nyatla | 57:bc4330dfa62f | 648 | w[1]=126; |
nyatla | 57:bc4330dfa62f | 649 | s=3; |
nyatla | 57:bc4330dfa62f | 650 | *((NyLPC_TUInt16*)(&(w[2])))=NyLPC_htons(i_len); |
nyatla | 57:bc4330dfa62f | 651 | } |
nyatla | 57:bc4330dfa62f | 652 | if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),w,s)){ |
nyatla | 57:bc4330dfa62f | 653 | //CLOSE |
nyatla | 57:bc4330dfa62f | 654 | NyLPC_OnErrorGoto(Error); |
nyatla | 57:bc4330dfa62f | 655 | } |
nyatla | 58:03b89038b21a | 656 | return NyLPC_TBool_TRUE; |
nyatla | 58:03b89038b21a | 657 | Error: |
nyatla | 58:03b89038b21a | 658 | return NyLPC_TBool_FALSE; |
nyatla | 58:03b89038b21a | 659 | } |
nyatla | 58:03b89038b21a | 660 | |
nyatla | 72:c118a7aa37a3 | 661 | |
nyatla | 58:03b89038b21a | 662 | |
nyatla | 71:855020258513 | 663 | NyLPC_TBool NyLPC_cModWebSocket_writeFormatV(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,va_list args) |
nyatla | 58:03b89038b21a | 664 | { |
nyatla | 58:03b89038b21a | 665 | NyLPC_TInt16 l; |
nyatla | 58:03b89038b21a | 666 | va_list a; |
nyatla | 58:03b89038b21a | 667 | //ストリームの状態を更新する。 |
nyatla | 58:03b89038b21a | 668 | NyLPC_cModWebSocket_update(i_inst,0); |
nyatla | 58:03b89038b21a | 669 | |
nyatla | 58:03b89038b21a | 670 | //書式文字列の長さを計算 |
nyatla | 72:c118a7aa37a3 | 671 | NyLPC_va_copy(a,args); |
nyatla | 58:03b89038b21a | 672 | l=NyLPC_cFormatWriter_length(i_fmt,a); |
nyatla | 58:03b89038b21a | 673 | va_end(a); |
nyatla | 58:03b89038b21a | 674 | if(!NyLPC_cModWebSocket_writePayloadHeader(i_inst,l)){ |
nyatla | 58:03b89038b21a | 675 | //CLOSE |
nyatla | 58:03b89038b21a | 676 | NyLPC_OnErrorGoto(Error); |
nyatla | 58:03b89038b21a | 677 | } |
nyatla | 71:855020258513 | 678 | if(!NyLPC_cFormatWriter_print(fmt_handler,NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),i_fmt,args)){ |
nyatla | 58:03b89038b21a | 679 | NyLPC_OnErrorGoto(Error); |
nyatla | 58:03b89038b21a | 680 | } |
nyatla | 58:03b89038b21a | 681 | NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection)); |
nyatla | 58:03b89038b21a | 682 | return NyLPC_TBool_TRUE; |
nyatla | 58:03b89038b21a | 683 | Error: |
nyatla | 58:03b89038b21a | 684 | NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection); |
nyatla | 58:03b89038b21a | 685 | i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED; |
nyatla | 58:03b89038b21a | 686 | return NyLPC_TBool_FALSE; |
nyatla | 58:03b89038b21a | 687 | } |
nyatla | 58:03b89038b21a | 688 | |
nyatla | 71:855020258513 | 689 | NyLPC_TBool NyLPC_cModWebSocket_writeFormat(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,...) |
nyatla | 71:855020258513 | 690 | { |
nyatla | 71:855020258513 | 691 | NyLPC_TBool r; |
nyatla | 71:855020258513 | 692 | va_list a; |
nyatla | 71:855020258513 | 693 | va_start(a,i_fmt); |
nyatla | 71:855020258513 | 694 | r=NyLPC_cModWebSocket_writeFormatV(i_inst,i_fmt,a); |
nyatla | 71:855020258513 | 695 | va_end(a); |
nyatla | 71:855020258513 | 696 | return r; |
nyatla | 71:855020258513 | 697 | } |
nyatla | 71:855020258513 | 698 | |
nyatla | 58:03b89038b21a | 699 | |
nyatla | 58:03b89038b21a | 700 | |
nyatla | 58:03b89038b21a | 701 | |
nyatla | 58:03b89038b21a | 702 | NyLPC_TBool NyLPC_cModWebSocket_write(NyLPC_TcModWebSocket_t* i_inst,const void* i_buf,NyLPC_TInt16 i_len) |
nyatla | 58:03b89038b21a | 703 | { |
nyatla | 58:03b89038b21a | 704 | //ストリームの状態を更新する。 |
nyatla | 58:03b89038b21a | 705 | NyLPC_cModWebSocket_update(i_inst,0); |
nyatla | 58:03b89038b21a | 706 | if(!NyLPC_cModWebSocket_writePayloadHeader(i_inst,i_len)){ |
nyatla | 58:03b89038b21a | 707 | //CLOSE |
nyatla | 58:03b89038b21a | 708 | NyLPC_OnErrorGoto(Error); |
nyatla | 58:03b89038b21a | 709 | } |
nyatla | 57:bc4330dfa62f | 710 | if(!NyLPC_iHttpPtrStream_write(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),i_buf,i_len)){ |
nyatla | 57:bc4330dfa62f | 711 | //CLOSE |
nyatla | 57:bc4330dfa62f | 712 | NyLPC_OnErrorGoto(Error); |
nyatla | 57:bc4330dfa62f | 713 | } |
nyatla | 57:bc4330dfa62f | 714 | NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection)); |
nyatla | 57:bc4330dfa62f | 715 | return NyLPC_TBool_TRUE; |
nyatla | 57:bc4330dfa62f | 716 | Error: |
nyatla | 57:bc4330dfa62f | 717 | NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection); |
nyatla | 57:bc4330dfa62f | 718 | i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED; |
nyatla | 57:bc4330dfa62f | 719 | return NyLPC_TBool_FALSE; |
nyatla | 57:bc4330dfa62f | 720 | } |
nyatla | 57:bc4330dfa62f | 721 | |
nyatla | 57:bc4330dfa62f | 722 | void NyLPC_cModWebSocket_close(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TUInt16 i_code) |
nyatla | 57:bc4330dfa62f | 723 | { |
nyatla | 58:03b89038b21a | 724 | //ストリームの状態を更新する。 |
nyatla | 58:03b89038b21a | 725 | NyLPC_cModWebSocket_update(i_inst,0); |
nyatla | 58:03b89038b21a | 726 | |
nyatla | 57:bc4330dfa62f | 727 | if(i_inst->_payload_st==NyLPC_TcModWebSocket_ST_CLOSED){ |
nyatla | 57:bc4330dfa62f | 728 | return; |
nyatla | 57:bc4330dfa62f | 729 | } |
nyatla | 57:bc4330dfa62f | 730 | //CLOSE送信 |
nyatla | 57:bc4330dfa62f | 731 | writeClosePacket(i_inst,i_code); |
nyatla | 57:bc4330dfa62f | 732 | i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED; |
nyatla | 57:bc4330dfa62f | 733 | //切断 |
nyatla | 57:bc4330dfa62f | 734 | NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection); |
nyatla | 57:bc4330dfa62f | 735 | } |
nyatla | 71:855020258513 | 736 | |
nyatla | 71:855020258513 | 737 | |
nyatla | 71:855020258513 | 738 | NyLPC_TInt16 NyLPC_cModWebSocket_testFormatV(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,va_list args) |
nyatla | 71:855020258513 | 739 | { |
nyatla | 71:855020258513 | 740 | return NyLPC_cFormatWriter_length(i_fmt,args); |
nyatla | 71:855020258513 | 741 | } |
nyatla | 71:855020258513 | 742 | NyLPC_TInt16 NyLPC_cModWebSocket_testFormat(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,...) |
nyatla | 71:855020258513 | 743 | { |
nyatla | 71:855020258513 | 744 | NyLPC_TInt16 r; |
nyatla | 71:855020258513 | 745 | va_list a; |
nyatla | 71:855020258513 | 746 | va_start(a,i_fmt); |
nyatla | 71:855020258513 | 747 | r=NyLPC_cFormatWriter_length(i_fmt,a); |
nyatla | 71:855020258513 | 748 | va_end(a); |
nyatla | 71:855020258513 | 749 | return r; |
nyatla | 71:855020258513 | 750 | } |
nyatla | 71:855020258513 | 751 | |
nyatla | 71:855020258513 | 752 | |
nyatla | 71:855020258513 | 753 | NyLPC_TBool NyLPC_cModWebSocket_startBulkWrite(NyLPC_TcModWebSocket_t* i_inst,NyLPC_TInt16 i_len) |
nyatla | 71:855020258513 | 754 | { |
nyatla | 71:855020258513 | 755 | //ストリームの状態を更新する。 |
nyatla | 71:855020258513 | 756 | NyLPC_cModWebSocket_update(i_inst,0); |
nyatla | 71:855020258513 | 757 | //ペイロードヘッダの出力 |
nyatla | 71:855020258513 | 758 | if(!NyLPC_cModWebSocket_writePayloadHeader(i_inst,i_len)){ |
nyatla | 71:855020258513 | 759 | //CLOSE |
nyatla | 71:855020258513 | 760 | NyLPC_OnErrorGoto(Error); |
nyatla | 71:855020258513 | 761 | } |
nyatla | 71:855020258513 | 762 | return NyLPC_TBool_TRUE; |
nyatla | 71:855020258513 | 763 | Error: |
nyatla | 71:855020258513 | 764 | NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection); |
nyatla | 71:855020258513 | 765 | i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED; |
nyatla | 71:855020258513 | 766 | return NyLPC_TBool_FALSE; |
nyatla | 71:855020258513 | 767 | } |
nyatla | 71:855020258513 | 768 | /** |
nyatla | 71:855020258513 | 769 | * バルク書き込みを終了します。 |
nyatla | 71:855020258513 | 770 | * この関数をコールする前に、startBulkWrite関数のi_lenで指定した大きさのデータを入力し終えている必要があります。 |
nyatla | 71:855020258513 | 771 | * 過不足があった場合、関数は失敗するか、WebSocketセッションが破壊されます。 |
nyatla | 71:855020258513 | 772 | */ |
nyatla | 71:855020258513 | 773 | NyLPC_TBool NyLPC_cModWebSocket_endBulkWrite(NyLPC_TcModWebSocket_t* i_inst) |
nyatla | 71:855020258513 | 774 | { |
nyatla | 71:855020258513 | 775 | if(i_inst->_payload_st==NyLPC_TcModWebSocket_ST_CLOSED){ |
nyatla | 71:855020258513 | 776 | return NyLPC_TBool_FALSE; |
nyatla | 71:855020258513 | 777 | } |
nyatla | 71:855020258513 | 778 | //送信サイズ確認? |
nyatla | 71:855020258513 | 779 | NyLPC_iHttpPtrStream_flush(NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection)); |
nyatla | 71:855020258513 | 780 | return NyLPC_TBool_TRUE; |
nyatla | 71:855020258513 | 781 | } |
nyatla | 71:855020258513 | 782 | |
nyatla | 71:855020258513 | 783 | NyLPC_TBool NyLPC_cModWebSocket_writeBulkFormatV(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,va_list args) |
nyatla | 71:855020258513 | 784 | { |
nyatla | 71:855020258513 | 785 | if(i_inst->_payload_st==NyLPC_TcModWebSocket_ST_CLOSED){ |
nyatla | 71:855020258513 | 786 | return NyLPC_TBool_FALSE; |
nyatla | 71:855020258513 | 787 | } |
nyatla | 71:855020258513 | 788 | if(!NyLPC_cFormatWriter_print(fmt_handler,NyLPC_cHttpdConnection_refStream(i_inst->_ref_connection),i_fmt,args)){ |
nyatla | 71:855020258513 | 789 | NyLPC_OnErrorGoto(Error); |
nyatla | 71:855020258513 | 790 | } |
nyatla | 71:855020258513 | 791 | return NyLPC_TBool_TRUE; |
nyatla | 71:855020258513 | 792 | Error: |
nyatla | 71:855020258513 | 793 | NyLPC_cHttpdConnection_closeSocket(i_inst->_ref_connection); |
nyatla | 71:855020258513 | 794 | i_inst->_payload_st=NyLPC_TcModWebSocket_ST_CLOSED; |
nyatla | 71:855020258513 | 795 | return NyLPC_TBool_FALSE; |
nyatla | 71:855020258513 | 796 | } |
nyatla | 71:855020258513 | 797 | NyLPC_TBool NyLPC_cModWebSocket_writeBulkFormat(NyLPC_TcModWebSocket_t* i_inst,const NyLPC_TChar* i_fmt,...) |
nyatla | 71:855020258513 | 798 | { |
nyatla | 71:855020258513 | 799 | NyLPC_TBool ret; |
nyatla | 71:855020258513 | 800 | va_list a; |
nyatla | 71:855020258513 | 801 | va_start(a,i_fmt); |
nyatla | 71:855020258513 | 802 | ret=NyLPC_cModWebSocket_writeBulkFormatV(i_inst,i_fmt,a); |
nyatla | 71:855020258513 | 803 | va_end(a); |
nyatla | 71:855020258513 | 804 | return ret; |
nyatla | 71:855020258513 | 805 | } |