Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of libMiMic by
core/http/NyLPC_cHttpBasicBodyParser.c@110:257739f9b31e, 2015-03-15 (annotated)
- Committer:
- nyatla
- Date:
- Sun Mar 15 09:33:38 2015 +0000
- Revision:
- 110:257739f9b31e
- Parent:
- 109:18f12ac01097
51d1c88c8a56d6295311cfd20aa197a9cd650b2d; ????; NetworkInterface???????
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
nyatla | 41:2389bd6b6f74 | 1 | #include "NyLPC_cHttpBasicBodyParser.h" |
nyatla | 41:2389bd6b6f74 | 2 | #include <ctype.h> |
nyatla | 41:2389bd6b6f74 | 3 | |
nyatla | 41:2389bd6b6f74 | 4 | void NyLPC_cHttpBasicBodyParser_initialize(NyLPC_TcHttpBasicBodyParser_t* i_inst,struct NyLPC_TcHttpBasicBodyParser_Handler* i_handler) |
nyatla | 41:2389bd6b6f74 | 5 | { |
nyatla | 41:2389bd6b6f74 | 6 | i_inst->_handler=i_handler; |
nyatla | 41:2389bd6b6f74 | 7 | i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_NULL; |
nyatla | 41:2389bd6b6f74 | 8 | } |
nyatla | 41:2389bd6b6f74 | 9 | #define NyLPC_cHttpBasicBodyParser_finalize(i_inst) |
nyatla | 41:2389bd6b6f74 | 10 | |
nyatla | 41:2389bd6b6f74 | 11 | /** |
nyatla | 41:2389bd6b6f74 | 12 | * パーサの開始処理をします。 |
nyatla | 41:2389bd6b6f74 | 13 | * 関数は、parseInit->parseChar[n回]->(parseStream)->parseFinishの順でコールします。 |
nyatla | 41:2389bd6b6f74 | 14 | * parseChar、又はparseStreamでエラーが発生した場合は、後続の関数を呼び出すことは出来ません。 |
nyatla | 41:2389bd6b6f74 | 15 | * parseCharでEOHに達した場合、parseCharまたはparseStreamを続けて呼ぶことは出来ません。 |
nyatla | 41:2389bd6b6f74 | 16 | * parseFinishはparseCharまたはparseStreamでEOHに達した場合のみ呼び出すことが出来ます。 |
nyatla | 41:2389bd6b6f74 | 17 | */ |
nyatla | 41:2389bd6b6f74 | 18 | void NyLPC_cHttpBasicBodyParser_parseInit(NyLPC_TcHttpBasicBodyParser_t* i_inst,const struct NyLPC_THttpBasicHeader* i_info) |
nyatla | 41:2389bd6b6f74 | 19 | { |
nyatla | 41:2389bd6b6f74 | 20 | switch(i_info->transfer_encoding) |
nyatla | 41:2389bd6b6f74 | 21 | { |
nyatla | 41:2389bd6b6f74 | 22 | case NyLPC_THttpMessgeHeader_TransferEncoding_CHUNKED: |
nyatla | 41:2389bd6b6f74 | 23 | i_inst->_encode_type=NyLPC_THttpMessgeHeader_TransferEncoding_CHUNKED; |
nyatla | 41:2389bd6b6f74 | 24 | i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_CHUNK_HEADER_START; |
nyatla | 41:2389bd6b6f74 | 25 | i_inst->_data.chunked.recv_len=0; |
nyatla | 41:2389bd6b6f74 | 26 | break; |
nyatla | 41:2389bd6b6f74 | 27 | default: |
nyatla | 41:2389bd6b6f74 | 28 | i_inst->_encode_type=NyLPC_THttpMessgeHeader_TransferEncoding_NONE; |
nyatla | 41:2389bd6b6f74 | 29 | i_inst->_data.normal.content_length=i_info->content_length; |
nyatla | 41:2389bd6b6f74 | 30 | i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_BODY; |
nyatla | 41:2389bd6b6f74 | 31 | break; |
nyatla | 41:2389bd6b6f74 | 32 | } |
nyatla | 41:2389bd6b6f74 | 33 | } |
nyatla | 41:2389bd6b6f74 | 34 | |
nyatla | 41:2389bd6b6f74 | 35 | /** |
nyatla | 41:2389bd6b6f74 | 36 | * パーサの処理を閉じます。 |
nyatla | 41:2389bd6b6f74 | 37 | * @return |
nyatla | 41:2389bd6b6f74 | 38 | * パース処理が正常に終了したかの真偽値 |
nyatla | 41:2389bd6b6f74 | 39 | */ |
nyatla | 41:2389bd6b6f74 | 40 | NyLPC_TBool NyLPC_cHttpBasicBodyParser_parseFinish(NyLPC_TcHttpBasicBodyParser_t* i_inst) |
nyatla | 41:2389bd6b6f74 | 41 | { |
nyatla | 41:2389bd6b6f74 | 42 | NyLPC_TBool ret=(i_inst->_status==NyLPC_TcHttpBasicBodyParser_ST_EOB); |
nyatla | 41:2389bd6b6f74 | 43 | i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_NULL; |
nyatla | 41:2389bd6b6f74 | 44 | return ret; |
nyatla | 41:2389bd6b6f74 | 45 | } |
nyatla | 41:2389bd6b6f74 | 46 | #define HTTP_CR 0x0D |
nyatla | 41:2389bd6b6f74 | 47 | #define HTTP_LF 0x0A |
nyatla | 41:2389bd6b6f74 | 48 | #define HTTP_SP 0x20 |
nyatla | 41:2389bd6b6f74 | 49 | /** |
nyatla | 41:2389bd6b6f74 | 50 | * HTTPストリームをパースします。 |
nyatla | 41:2389bd6b6f74 | 51 | * @return |
nyatla | 41:2389bd6b6f74 | 52 | * 処理した文字列の長さ。-1の場合エラーである。 |
nyatla | 41:2389bd6b6f74 | 53 | * それ以外の場合ステータスをチェックすること。 |
nyatla | 41:2389bd6b6f74 | 54 | * NyLPC_TcHttpBasicBodyParser_ST_ERROR |
nyatla | 41:2389bd6b6f74 | 55 | */ |
nyatla | 41:2389bd6b6f74 | 56 | NyLPC_TInt32 NyLPC_cHttpBasicBodyParser_parseChar(NyLPC_TcHttpBasicBodyParser_t* i_inst,const NyLPC_TChar* i_c,NyLPC_TInt32 i_size) |
nyatla | 41:2389bd6b6f74 | 57 | { |
nyatla | 41:2389bd6b6f74 | 58 | NyLPC_TInt32 i; |
nyatla | 41:2389bd6b6f74 | 59 | NyLPC_TChar c; |
nyatla | 41:2389bd6b6f74 | 60 | switch(i_inst->_encode_type){ |
nyatla | 41:2389bd6b6f74 | 61 | case NyLPC_THttpMessgeHeader_TransferEncoding_CHUNKED: |
nyatla | 41:2389bd6b6f74 | 62 | for(i=0;i<i_size;) |
nyatla | 41:2389bd6b6f74 | 63 | { |
nyatla | 41:2389bd6b6f74 | 64 | c=*(i_c+i); |
nyatla | 41:2389bd6b6f74 | 65 | //[:START:][:SP:][:EXT:][:BODY:][:END:] |
nyatla | 41:2389bd6b6f74 | 66 | switch(i_inst->_status) |
nyatla | 41:2389bd6b6f74 | 67 | { |
nyatla | 41:2389bd6b6f74 | 68 | case NyLPC_TcHttpBasicBodyParser_ST_CHUNK_BODY: |
nyatla | 41:2389bd6b6f74 | 69 | //OnRecv |
nyatla | 41:2389bd6b6f74 | 70 | if(!i_inst->_handler->bodyHandler(i_inst,c)){ |
nyatla | 41:2389bd6b6f74 | 71 | i_inst->_data.chunked.recv_len--; |
nyatla | 41:2389bd6b6f74 | 72 | //中断 |
nyatla | 41:2389bd6b6f74 | 73 | if(i_inst->_data.chunked.recv_len==0){ |
nyatla | 41:2389bd6b6f74 | 74 | //content length分だけ読み取った |
nyatla | 41:2389bd6b6f74 | 75 | i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_CHUNK_FOOTER; |
nyatla | 41:2389bd6b6f74 | 76 | } |
nyatla | 41:2389bd6b6f74 | 77 | return i+1; |
nyatla | 41:2389bd6b6f74 | 78 | } |
nyatla | 41:2389bd6b6f74 | 79 | i_inst->_data.chunked.recv_len--; |
nyatla | 41:2389bd6b6f74 | 80 | if(i_inst->_data.chunked.recv_len==0){ |
nyatla | 41:2389bd6b6f74 | 81 | //content length分だけ読み取った |
nyatla | 41:2389bd6b6f74 | 82 | i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_CHUNK_FOOTER; |
nyatla | 41:2389bd6b6f74 | 83 | } |
nyatla | 41:2389bd6b6f74 | 84 | i++;//次の文字へ |
nyatla | 41:2389bd6b6f74 | 85 | break; |
nyatla | 41:2389bd6b6f74 | 86 | // HEX |
nyatla | 41:2389bd6b6f74 | 87 | case NyLPC_TcHttpBasicBodyParser_ST_CHUNK_HEADER_START: |
nyatla | 109:18f12ac01097 | 88 | if(isxdigit((int)c)){ |
nyatla | 41:2389bd6b6f74 | 89 | i_inst->_data.chunked.recv_len=i_inst->_data.chunked.recv_len*16+NyLPC_ctox(c); |
nyatla | 41:2389bd6b6f74 | 90 | //一応最大チャンクサイズは決めておこうか。 |
nyatla | 41:2389bd6b6f74 | 91 | if(i_inst->_data.chunked.recv_len>0x0fffffff){ |
nyatla | 41:2389bd6b6f74 | 92 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 41:2389bd6b6f74 | 93 | } |
nyatla | 41:2389bd6b6f74 | 94 | i++;//次の文字へ |
nyatla | 41:2389bd6b6f74 | 95 | }else if(c==HTTP_SP){ |
nyatla | 41:2389bd6b6f74 | 96 | i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_CHUNK_HEADER_SP; |
nyatla | 41:2389bd6b6f74 | 97 | i++;//次の文字へ |
nyatla | 41:2389bd6b6f74 | 98 | }else if(c==HTTP_CR || c==HTTP_LF){ |
nyatla | 41:2389bd6b6f74 | 99 | i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_CHUNK_HEADER_EXT; |
nyatla | 41:2389bd6b6f74 | 100 | //読取位置を変化させずにEXTへ |
nyatla | 41:2389bd6b6f74 | 101 | }else{ |
nyatla | 41:2389bd6b6f74 | 102 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 41:2389bd6b6f74 | 103 | } |
nyatla | 41:2389bd6b6f74 | 104 | break; |
nyatla | 41:2389bd6b6f74 | 105 | case NyLPC_TcHttpBasicBodyParser_ST_CHUNK_HEADER_SP: |
nyatla | 41:2389bd6b6f74 | 106 | if(c==HTTP_SP){ |
nyatla | 41:2389bd6b6f74 | 107 | i++;//次の文字へ |
nyatla | 41:2389bd6b6f74 | 108 | }else{ |
nyatla | 41:2389bd6b6f74 | 109 | //ext |
nyatla | 41:2389bd6b6f74 | 110 | i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_CHUNK_HEADER_EXT; |
nyatla | 41:2389bd6b6f74 | 111 | } |
nyatla | 41:2389bd6b6f74 | 112 | break; |
nyatla | 41:2389bd6b6f74 | 113 | case NyLPC_TcHttpBasicBodyParser_ST_CHUNK_HEADER_EXT: |
nyatla | 41:2389bd6b6f74 | 114 | //EXTの内容は読まない。 |
nyatla | 41:2389bd6b6f74 | 115 | if(c==HTTP_LF){ |
nyatla | 41:2389bd6b6f74 | 116 | if(i_inst->_data.chunked.recv_len==0){ |
nyatla | 41:2389bd6b6f74 | 117 | //chunksize=0でCRLFを検出したらend-chunk |
nyatla | 41:2389bd6b6f74 | 118 | i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_CHUNK_END; |
nyatla | 41:2389bd6b6f74 | 119 | }else{ |
nyatla | 41:2389bd6b6f74 | 120 | //chunksize>0でCRLFを検出したらBODY検出 |
nyatla | 41:2389bd6b6f74 | 121 | i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_CHUNK_BODY; |
nyatla | 41:2389bd6b6f74 | 122 | } |
nyatla | 41:2389bd6b6f74 | 123 | }else{ |
nyatla | 41:2389bd6b6f74 | 124 | //nothing to do |
nyatla | 41:2389bd6b6f74 | 125 | } |
nyatla | 41:2389bd6b6f74 | 126 | i++;//次の文字へ |
nyatla | 41:2389bd6b6f74 | 127 | break; |
nyatla | 41:2389bd6b6f74 | 128 | case NyLPC_TcHttpBasicBodyParser_ST_CHUNK_FOOTER: |
nyatla | 41:2389bd6b6f74 | 129 | //CRLF待ち |
nyatla | 41:2389bd6b6f74 | 130 | if(c==HTTP_CR){ |
nyatla | 41:2389bd6b6f74 | 131 | //無視 |
nyatla | 41:2389bd6b6f74 | 132 | }else if(c==HTTP_LF){ |
nyatla | 41:2389bd6b6f74 | 133 | //確定 |
nyatla | 41:2389bd6b6f74 | 134 | i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_CHUNK_HEADER_START; |
nyatla | 41:2389bd6b6f74 | 135 | }else{ |
nyatla | 41:2389bd6b6f74 | 136 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 41:2389bd6b6f74 | 137 | } |
nyatla | 41:2389bd6b6f74 | 138 | i++; |
nyatla | 41:2389bd6b6f74 | 139 | break; |
nyatla | 41:2389bd6b6f74 | 140 | case NyLPC_TcHttpBasicBodyParser_ST_CHUNK_END: |
nyatla | 41:2389bd6b6f74 | 141 | //CRLF待ち |
nyatla | 41:2389bd6b6f74 | 142 | if(c==HTTP_CR){ |
nyatla | 41:2389bd6b6f74 | 143 | //無視 |
nyatla | 41:2389bd6b6f74 | 144 | }else if(c==HTTP_LF){ |
nyatla | 41:2389bd6b6f74 | 145 | //確定 |
nyatla | 41:2389bd6b6f74 | 146 | i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_EOB; |
nyatla | 41:2389bd6b6f74 | 147 | return i+1; |
nyatla | 41:2389bd6b6f74 | 148 | }else{ |
nyatla | 41:2389bd6b6f74 | 149 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 41:2389bd6b6f74 | 150 | } |
nyatla | 41:2389bd6b6f74 | 151 | i++; |
nyatla | 41:2389bd6b6f74 | 152 | break; |
nyatla | 41:2389bd6b6f74 | 153 | default: |
nyatla | 41:2389bd6b6f74 | 154 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 41:2389bd6b6f74 | 155 | } |
nyatla | 41:2389bd6b6f74 | 156 | } |
nyatla | 41:2389bd6b6f74 | 157 | return i_size; |
nyatla | 41:2389bd6b6f74 | 158 | case NyLPC_THttpMessgeHeader_TransferEncoding_NONE: |
nyatla | 41:2389bd6b6f74 | 159 | if(i_inst->_status!=NyLPC_TcHttpBasicBodyParser_ST_BODY){ |
nyatla | 41:2389bd6b6f74 | 160 | NyLPC_OnErrorGoto(ERROR); |
nyatla | 41:2389bd6b6f74 | 161 | } |
nyatla | 41:2389bd6b6f74 | 162 | for(i=0;i<i_size;i++) |
nyatla | 41:2389bd6b6f74 | 163 | { |
nyatla | 41:2389bd6b6f74 | 164 | if(i_inst->_data.normal.content_length>0){ |
nyatla | 41:2389bd6b6f74 | 165 | //OnRecv |
nyatla | 41:2389bd6b6f74 | 166 | if(!i_inst->_handler->bodyHandler(i_inst,*(i_c+i))){ |
nyatla | 41:2389bd6b6f74 | 167 | i++; |
nyatla | 41:2389bd6b6f74 | 168 | i_inst->_data.normal.content_length--; |
nyatla | 41:2389bd6b6f74 | 169 | break;//中断(遷移無し) |
nyatla | 41:2389bd6b6f74 | 170 | } |
nyatla | 41:2389bd6b6f74 | 171 | i_inst->_data.normal.content_length--; |
nyatla | 41:2389bd6b6f74 | 172 | }else{ |
nyatla | 41:2389bd6b6f74 | 173 | //content-length==0;全て受信 |
nyatla | 41:2389bd6b6f74 | 174 | break; |
nyatla | 41:2389bd6b6f74 | 175 | } |
nyatla | 41:2389bd6b6f74 | 176 | } |
nyatla | 41:2389bd6b6f74 | 177 | if(i_inst->_data.normal.content_length==0){ |
nyatla | 41:2389bd6b6f74 | 178 | //content length分だけ読み取った |
nyatla | 41:2389bd6b6f74 | 179 | i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_EOB; |
nyatla | 41:2389bd6b6f74 | 180 | return i; |
nyatla | 41:2389bd6b6f74 | 181 | } |
nyatla | 41:2389bd6b6f74 | 182 | return i; |
nyatla | 41:2389bd6b6f74 | 183 | } |
nyatla | 41:2389bd6b6f74 | 184 | ERROR: |
nyatla | 41:2389bd6b6f74 | 185 | //ERROR |
nyatla | 41:2389bd6b6f74 | 186 | i_inst->_status=NyLPC_TcHttpBasicBodyParser_ST_ERROR; |
nyatla | 41:2389bd6b6f74 | 187 | return -1; |
nyatla | 41:2389bd6b6f74 | 188 | } |
nyatla | 41:2389bd6b6f74 | 189 | |
nyatla | 41:2389bd6b6f74 | 190 |