Jun Furutani / libMiMic

Fork of libMiMic by Ryo Iizuka

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?

UserRevisionLine numberNew 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