This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088
Dependents: MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more
NyLPC_cHttpBasicHeaderParser.c
00001 /********************************************************************************* 00002 * PROJECT: MiMic 00003 * -------------------------------------------------------------------------------- 00004 * 00005 * This file is part of MiMic 00006 * Copyright (C)2011 Ryo Iizuka 00007 * 00008 * MiMic is free software: you can redistribute it and/or modify 00009 * it under the terms of the GNU Lesser General Public License as published 00010 * by the Free Software Foundation, either version 3 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public License 00019 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00020 * 00021 * For further information please contact. 00022 * http://nyatla.jp/ 00023 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp> 00024 * 00025 *********************************************************************************/ 00026 #include "NyLPC_cHttpBasicHeaderParser_protected.h" 00027 #include <stdlib.h> 00028 00029 #define HTTP_TIMEOUT NyLPC_TiHttpPtrStream_DEFAULT_HTTP_TIMEOUT 00030 00031 static const struct NyLPC_TTextIdTbl method_id_table[]= 00032 { 00033 //HTTP STANDARD 00034 {"GET",NyLPC_THttpMethodType_GET}, 00035 {"POST",NyLPC_THttpMethodType_POST}, 00036 {"HEAD",NyLPC_THttpMethodType_HEAD}, 00037 //SSDP 00038 {"M-SEARCH",NyLPC_THttpMethodType_M_SEARCH}, 00039 {"NOTIFY",NyLPC_THttpMethodType_NOTIFY}, 00040 {NULL,NyLPC_THttpMethodType_NULL} 00041 }; 00042 /*-------------------------------------------------------------------------------- 00043 * 00044 * NyLPC_THttpMethodType 00045 * 00046 --------------------------------------------------------------------------------*/ 00047 const char* NyLPC_THttpMethodType_toString(NyLPC_THttpMethodType i_method) 00048 { 00049 const char* ret=NyLPC_TTextIdTbl_getTextById(i_method,method_id_table); 00050 if(ret==NULL){ 00051 NyLPC_Abort(); 00052 } 00053 return ret; 00054 } 00055 00056 static NyLPC_TBool parseRequestMethodStr(NyLPC_TcStr_t* i_str,NyLPC_THttpMethodType* o_out) 00057 { 00058 //解析処理 00059 *o_out=NyLPC_TTextIdTbl_getMatchIdIgnoreCase(NyLPC_cStr_str(i_str),method_id_table); 00060 if(*o_out==NyLPC_THttpMethodType_NULL){ 00061 NyLPC_OnErrorGoto(ERROR); 00062 } 00063 return NyLPC_TBool_TRUE; 00064 ERROR: 00065 return NyLPC_TBool_FALSE; 00066 } 00067 /*-------------------------------------------------------------------------------- 00068 * 00069 * NyLPC_THttpBasicHeader 00070 * 00071 --------------------------------------------------------------------------------*/ 00072 00073 NyLPC_TBool NyLPC_THttpBasicHeader_isPersistent(const struct NyLPC_THttpBasicHeader* i_struct) 00074 { 00075 switch(i_struct->type) 00076 { 00077 case NyLPC_THttpHeaderType_REQUEST: 00078 return (i_struct->connection!=NyLPC_THttpMessgeHeader_Connection_CLOSE)&&(i_struct->startline.req.version==NyLPC_THttpVersion_11); 00079 case NyLPC_THttpHeaderType_RESPONSE: 00080 default: 00081 break; 00082 } 00083 return NyLPC_TBool_FALSE; 00084 } 00085 00086 00087 00088 00089 00090 00091 00092 00093 /* 00094 文字コードの定義 00095 */ 00096 #define HTTP_SP 0x20 00097 #define HTTP_LF 0x0A 00098 #define HTTP_CR 0x0D 00099 #define HTTP_DM ':' 00100 00101 00102 00103 00104 static NyLPC_TcHttpBasicHeaderParser_ST parseMessage_Connection(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out); 00105 static NyLPC_TcHttpBasicHeaderParser_ST parseMessage_ContentLength(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out); 00106 static NyLPC_TcHttpBasicHeaderParser_ST parseMessage1(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out); 00107 static NyLPC_TcHttpBasicHeaderParser_ST parseVersion(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,NyLPC_TcHttpBasicHeaderParser_ST i_next,struct NyLPC_THttpBasicHeader* o_out); 00108 static NyLPC_TcHttpBasicHeaderParser_ST parseRequestUrl(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out); 00109 static NyLPC_TcHttpBasicHeaderParser_ST parseMessageParam(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out); 00110 static NyLPC_TcHttpBasicHeaderParser_ST parseStartLine(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out); 00111 static NyLPC_TcHttpBasicHeaderParser_ST parseStatusCode(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out); 00112 static NyLPC_TcHttpBasicHeaderParser_ST parseReason(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c); 00113 static NyLPC_TcHttpBasicHeaderParser_ST parseMessage_TransferEncoding(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out); 00114 00115 00116 static NyLPC_TBool parseHttpVersionStr(NyLPC_TcStr_t* i_str,NyLPC_THttpVersion* o_out); 00117 static NyLPC_TBool parseRequestMethodStr(NyLPC_TcStr_t* i_str,NyLPC_THttpMethodType* o_out); 00118 00119 static NyLPC_TBool testHeader(struct NyLPC_THttpBasicHeader* i_header,NyLPC_TUInt16* o_error); 00120 00121 00122 /** 00123 * デフォルトハンドラ 00124 */ 00125 static const struct NyLPC_TcHttpBasicHeaderParser_Handler _default_handler= 00126 { 00127 NULL,NULL 00128 }; 00129 00130 00131 00132 /*---------------------------------------- 00133 Public/Protected関数 00134 ----------------------------------------*/ 00135 00136 00137 void NyLPC_cHttpBasicHeaderParser_initialize(NyLPC_TcHttpBasicHeaderParser_t* i_inst,const struct NyLPC_TcHttpBasicHeaderParser_Handler* i_handler) 00138 { 00139 NyLPC_cStr_initialize(&(i_inst->_wsb),i_inst->_wsb_buf,NyLPC_cHttpBasicHeaderParser_SIZE_OF_WBS); 00140 i_inst->_handler=((i_handler==NULL)?&_default_handler:i_handler); 00141 } 00142 00143 /** 00144 * parserの初期化 00145 */ 00146 void NyLPC_cHttpBasicHeaderParser_parseInit(NyLPC_TcHttpBasicHeaderParser_t* i_inst,struct NyLPC_THttpBasicHeader* o_out) 00147 { 00148 //出力構造体を初期化 00149 o_out->connection=NyLPC_THttpMessgeHeader_Connection_NONE; 00150 o_out->content_length=NyLPC_THttpContentLength_INVALID_LENGTH; 00151 o_out->transfer_encoding=NyLPC_THttpMessgeHeader_TransferEncoding_NONE; 00152 i_inst->_st=NyLPC_TcHttpBasicHeaderParser_ST_START; 00153 } 00154 /** 00155 * parseCharがNyLPC_TcHttpBasicHeaderParser_ST_EOHを返却したらコールすること。 00156 */ 00157 NyLPC_TBool NyLPC_cHttpBasicHeaderParser_parseFinish(NyLPC_TcHttpBasicHeaderParser_t* i_inst,struct NyLPC_THttpBasicHeader* o_out) 00158 { 00159 if(i_inst->_st!=NyLPC_TcHttpBasicHeaderParser_ST_EOH) 00160 { 00161 return NyLPC_TBool_FALSE; 00162 } 00163 //整合性チェック 00164 if(!testHeader(o_out,&i_inst->_rcode)){ 00165 i_inst->_st=NyLPC_TcHttpBasicHeaderParser_ST_ERROR; 00166 return NyLPC_TBool_FALSE; 00167 } 00168 return NyLPC_TBool_TRUE; 00169 } 00170 /** 00171 * 文字列をパースします。 00172 * コール前にNyLPC_cHttpBasicHeaderParser_parseInitでパーサを開始してください。 00173 * @return 00174 * パースした文字列の長さ。-1の場合はエラー。 00175 * TRUEの場合、NyLPC_cHttpBasicHeaderParser_getParseStatus関数で状態をチェックして、後続の処理を選択してください。 00176 */ 00177 NyLPC_TInt32 NyLPC_cHttpBasicHeaderParser_parseChar(NyLPC_TcHttpBasicHeaderParser_t* i_inst,const NyLPC_TChar* i_c,NyLPC_TInt32 i_size,struct NyLPC_THttpBasicHeader* o_out) 00178 { 00179 int i; 00180 NyLPC_TChar c; 00181 //Errorチェック 00182 if(NyLPC_TcHttpBasicHeaderParser_ST_ERROR==i_inst->_st) 00183 { 00184 return 0; 00185 } 00186 for(i=0;i<i_size;i++){ 00187 c=*(i_c+i); 00188 switch(i_inst->_st) 00189 { 00190 case NyLPC_TcHttpBasicHeaderParser_ST_START: 00191 i_inst->_st=parseStartLine(i_inst,c,o_out); 00192 break; 00193 case NyLPC_TcHttpBasicHeaderParser_ST_MSGPARAM: 00194 i_inst->_st=parseMessageParam(i_inst,c,o_out); 00195 break; 00196 case NyLPC_TcHttpBasicHeaderParser_ST_MSGHEAD: 00197 i_inst->_st=parseMessage1(i_inst,c,o_out); 00198 break; 00199 case NyLPC_TcHttpBasicHeaderParser_ST_RL_URL: 00200 i_inst->_st=parseRequestUrl(i_inst,c,o_out); 00201 break; 00202 case NyLPC_TcHttpBasicHeaderParser_ST_RL_VERSION: 00203 i_inst->_st=parseVersion(i_inst,c,NyLPC_TcHttpBasicHeaderParser_ST_MSGHEAD,o_out); 00204 break; 00205 case NyLPC_TcHttpBasicHeaderParser_ST_SL_STATUSCODE: 00206 i_inst->_st=parseStatusCode(i_inst,c,o_out); 00207 break; 00208 case NyLPC_TcHttpBasicHeaderParser_ST_SL_REASON: 00209 i_inst->_st=parseReason(i_inst,c); 00210 break; 00211 case NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONTENTLENGTH: 00212 i_inst->_st=parseMessage_ContentLength(i_inst,c,o_out); 00213 break; 00214 case NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONNECTION: 00215 i_inst->_st=parseMessage_Connection(i_inst,c,o_out); 00216 break; 00217 case NyLPC_TcHttpBasicHeaderParser_ST_MSG_TRANSFERENCODING: 00218 i_inst->_st=parseMessage_TransferEncoding(i_inst,c,o_out); 00219 break; 00220 default: 00221 i_inst->_rcode=500; 00222 i_inst->_st=NyLPC_TcHttpBasicHeaderParser_ST_ERROR; 00223 } 00224 if(NyLPC_TcHttpBasicHeaderParser_ST_isError(i_inst->_st)){ 00225 //エラー起こしたら終了。 00226 return i; 00227 }else if(i_inst->_st==NyLPC_TcHttpBasicHeaderParser_ST_EOH){ 00228 //ヘッダ終端なら終了。 00229 return i+1; 00230 } 00231 } 00232 return i_size; 00233 } 00234 00235 00236 00237 /** 00238 * ストリームから読み出して、パースします。 00239 * コール前にNyLPC_cHttpBasicHeaderParser_parseInitでパーサを開始してください。 00240 * @return 00241 * FALSE-失敗/TRUE-成功 00242 * 関数が成功した場合、NyLPC_cHttpBasicHeaderParser_parseFinishでパーサを閉じることが出来ます。 00243 */ 00244 NyLPC_TBool NyLPC_cHttpBasicHeaderParser_parseStream(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TiHttpPtrStream_t* i_stream,struct NyLPC_THttpBasicHeader* o_out) 00245 { 00246 const char* rp_base; 00247 NyLPC_TInt32 rsize; 00248 for(;;){ 00249 //タイムアウト付でストリームから読み出し。 00250 rsize=NyLPC_iHttpPtrStream_pread(i_stream,(const void**)(&rp_base),HTTP_TIMEOUT); 00251 if(rsize<=0){ 00252 return NyLPC_TBool_FALSE; 00253 } 00254 rsize=NyLPC_cHttpBasicHeaderParser_parseChar(i_inst,rp_base,rsize,o_out); 00255 if(i_inst->_st==NyLPC_TcHttpBasicHeaderParser_ST_ERROR){ 00256 //パース失敗 00257 NyLPC_iHttpPtrStream_rseek(i_stream,rsize); 00258 return NyLPC_TBool_FALSE; 00259 } 00260 if(i_inst->_st==NyLPC_TcHttpBasicHeaderParser_ST_EOH){ 00261 //パース成功 00262 NyLPC_iHttpPtrStream_rseek(i_stream,rsize); 00263 return NyLPC_TBool_TRUE; 00264 } 00265 NyLPC_iHttpPtrStream_rseek(i_stream,(NyLPC_TUInt16)rsize); 00266 } 00267 return NyLPC_TBool_FALSE; 00268 } 00269 00270 00271 ///** 00272 // * ストリームから読み出して、パースします。 00273 // */ 00274 //NyLPC_TBool NyLPC_cHttpBasicHeaderParser_parse(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TcHttpStream_t* i_stream,struct NyLPC_THttpBasicHeader* o_out) 00275 //{ 00276 // NyLPC_TcHttpBasicHeaderParser_ST st; 00277 // const char* rp_base; 00278 // NyLPC_TInt32 rsize; 00279 // char c; 00280 // int i; 00281 // 00282 // //出力構造体を初期化 00283 // st=NyLPC_TcHttpBasicHeaderParser_ST_START; 00284 // o_out->connection=NyLPC_THttpMessgeHeader_Connection_NONE; 00285 // o_out->content_length=NyLPC_THttpContentLength_INVALID_LENGTH; 00286 // o_out->transfer_encoding=NyLPC_THttpMessgeHeader_TransferEncoding_NONE; 00287 // 00288 // for(;;){ 00289 // //タイムアウト付でストリームから読み出し。 00290 // rsize=NyLPC_iHttpPtrStream_pread(i_stream,(const void**)(&rp_base)); 00291 // if(rsize<=0){ 00292 // return NyLPC_TBool_FALSE; 00293 // } 00294 // for(i=0;i<rsize;i++){ 00295 // c=*(rp_base+i); 00296 // switch(st) 00297 // { 00298 // case NyLPC_TcHttpBasicHeaderParser_ST_START: 00299 // st=parseStartLine(i_inst,c,o_out); 00300 // break; 00301 // case NyLPC_TcHttpBasicHeaderParser_ST_MSGPARAM: 00302 // st=parseMessageParam(i_inst,c,o_out); 00303 // break; 00304 // case NyLPC_TcHttpBasicHeaderParser_ST_MSGHEAD: 00305 // st=parseMessage1(i_inst,c,o_out); 00306 // break; 00307 // case NyLPC_TcHttpBasicHeaderParser_ST_RL_URL: 00308 // st=parseRequestUrl(i_inst,c,o_out); 00309 // break; 00310 // case NyLPC_TcHttpBasicHeaderParser_ST_RL_VERSION: 00311 // st=parseVersion(i_inst,c,NyLPC_TcHttpBasicHeaderParser_ST_MSGHEAD,o_out); 00312 // break; 00313 // case NyLPC_TcHttpBasicHeaderParser_ST_SL_STATUSCODE: 00314 // st=parseStatusCode(i_inst,c,o_out); 00315 // break; 00316 // case NyLPC_TcHttpBasicHeaderParser_ST_SL_REASON: 00317 // st=parseReason(i_inst,c); 00318 // break; 00319 // case NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONTENTLENGTH: 00320 // st=parseMessage_ContentLength(i_inst,c,o_out); 00321 // break; 00322 // case NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONNECTION: 00323 // st=parseMessage_Connection(i_inst,c,o_out); 00324 // break; 00325 // case NyLPC_TcHttpBasicHeaderParser_ST_MSG_TRANSFERENCODING: 00326 // st=parseMessage_TransferEncoding(i_inst,c,o_out); 00327 // break; 00328 // default: 00329 // i_inst->_rcode=500; 00330 // st=NyLPC_TcHttpBasicHeaderParser_ST_ERROR; 00331 // } 00332 // //エラー起こしたら終了。 00333 // if(NyLPC_TcHttpBasicHeaderParser_ST_isError(st)){ 00334 // return NyLPC_TBool_FALSE; 00335 // } 00336 // //パース成功 00337 // if(st==NyLPC_TcHttpBasicHeaderParser_ST_EOH){ 00338 // //整合性チェック 00339 // if(!testHeader(o_out,&i_inst->_rcode)){ 00340 // st=NyLPC_TcHttpBasicHeaderParser_ST_ERROR; 00341 // return NyLPC_TBool_FALSE; 00342 // } 00343 // //シーク 00344 // NyLPC_iHttpPtrStream_rseek(i_stream,i+1); 00345 // return NyLPC_TBool_TRUE; 00346 // } 00347 // } 00348 // //シーク 00349 // NyLPC_iHttpPtrStream_rseek(i_stream,(NyLPC_TUInt16)rsize); 00350 // } 00351 // return NyLPC_TBool_FALSE; 00352 //} 00353 00354 00355 00356 /*---------------------------------------- 00357 private関数 00358 ----------------------------------------*/ 00359 /** 00360 ヘッダの整合性をとる。 00361 */ 00362 static NyLPC_TBool testHeader(struct NyLPC_THttpBasicHeader* i_header,NyLPC_TUInt16* o_error) 00363 { 00364 switch(i_header->startline.req.version){ 00365 case NyLPC_THttpVersion_09: 00366 if(i_header->type==NyLPC_THttpHeaderType_REQUEST){ 00367 //Requestの時だけmethodチェック 00368 //GETだけ 00369 if(i_header->startline.req.method!=NyLPC_THttpMethodType_GET){ 00370 *o_error=400; 00371 break; 00372 } 00373 } 00374 //TEは受け付けない。 00375 if(i_header->transfer_encoding!=NyLPC_THttpMessgeHeader_TransferEncoding_NONE){ 00376 *o_error=400; 00377 break; 00378 } 00379 //ContentLength=0,Connection=Closedに修正。 00380 i_header->content_length=0; 00381 i_header->connection=NyLPC_THttpMessgeHeader_Connection_CLOSE; 00382 return NyLPC_TBool_TRUE; 00383 case NyLPC_THttpVersion_10: 00384 //TEは受け付けない。 00385 if(i_header->transfer_encoding!=NyLPC_THttpMessgeHeader_TransferEncoding_NONE){ 00386 *o_error=406; 00387 break; 00388 } 00389 //ContentLengthが無いときは0 00390 if(i_header->content_length==NyLPC_THttpContentLength_INVALID_LENGTH){ 00391 i_header->content_length=0; 00392 } 00393 //Connection=Closedに修正。(1.0のKeepaliveは難しいから無視) 00394 i_header->connection=NyLPC_THttpMessgeHeader_Connection_CLOSE; 00395 return NyLPC_TBool_TRUE; 00396 case NyLPC_THttpVersion_11: 00397 if(i_header->content_length==NyLPC_THttpContentLength_INVALID_LENGTH){ 00398 //Contentlength無しのChunked指定はOK 00399 if(i_header->transfer_encoding!=NyLPC_THttpMessgeHeader_TransferEncoding_CHUNKED){ 00400 //Chunkedが無い場合はContent-Lengthは0と仮定 00401 i_header->content_length=0; 00402 }else{ 00403 //content-length無し && Chunked有 00404 //OK 00405 } 00406 }else if(i_header->transfer_encoding!=NyLPC_THttpMessgeHeader_TransferEncoding_NONE){ 00407 //ContentLengthあるのにChunkedとは何事 00408 *o_error=400; 00409 break; 00410 } 00411 return NyLPC_TBool_TRUE; 00412 case NyLPC_THttpVersion_UNKNOWN: 00413 //おい馬鹿やめろ 00414 *o_error=505; 00415 break; 00416 default: 00417 *o_error=500; 00418 break; 00419 } 00420 return NyLPC_TBool_FALSE; 00421 } 00422 00423 static NyLPC_TcHttpBasicHeaderParser_ST parseMessage_TransferEncoding(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out) 00424 { 00425 00426 //先頭のスペース除外 00427 if(NyLPC_cStr_len(&(i_inst->_wsb))==0){ 00428 if(i_c==HTTP_SP){ 00429 return NyLPC_TcHttpBasicHeaderParser_ST_MSG_TRANSFERENCODING;//変化なし 00430 } 00431 } 00432 if(i_c==HTTP_CR){ 00433 //CRの無視 00434 return NyLPC_TcHttpBasicHeaderParser_ST_MSG_TRANSFERENCODING;//変化なし 00435 }else if(i_c==HTTP_LF){ 00436 //大文字化 00437 NyLPC_cStr_toUpper(&(i_inst->_wsb)); 00438 //close? 00439 o_out->transfer_encoding=NyLPC_cStr_isEqual(&(i_inst->_wsb),"CHUNKED")?NyLPC_THttpMessgeHeader_TransferEncoding_CHUNKED:NyLPC_THttpMessgeHeader_TransferEncoding_UNKNOWN; 00440 NyLPC_cStr_clear(&(i_inst->_wsb)); 00441 return NyLPC_TcHttpBasicHeaderParser_ST_MSGHEAD; 00442 } 00443 if(!NyLPC_cStr_put(&(i_inst->_wsb),i_c)){ 00444 i_inst->_rcode=500; 00445 NyLPC_OnErrorGoto(Error); 00446 } 00447 return NyLPC_TcHttpBasicHeaderParser_ST_MSG_TRANSFERENCODING;//変化なし; 00448 Error: 00449 return NyLPC_TcHttpBasicHeaderParser_ST_ERROR; 00450 } 00451 00452 00453 static NyLPC_TcHttpBasicHeaderParser_ST parseMessage_Connection(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out) 00454 { 00455 const static NyLPC_TUInt8 id[]={ 00456 NyLPC_THttpMessgeHeader_Connection_CLOSE, 00457 NyLPC_THttpMessgeHeader_Connection_KEEPALIVE, 00458 NyLPC_THttpMessgeHeader_Connection_UPGRADE, 00459 NyLPC_THttpMessgeHeader_Connection_UNKNOWN 00460 }; 00461 const static NyLPC_TChar* str[]={ 00462 "CLOSE", 00463 "KEEP-ALIVE", 00464 "UPGRADE" 00465 }; 00466 NyLPC_TUInt8 i; 00467 //先頭のスペース除外 00468 if(NyLPC_cStr_len(&(i_inst->_wsb))==0){ 00469 if(i_c==HTTP_SP){ 00470 return NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONNECTION;//変化なし 00471 } 00472 } 00473 if(i_c==HTTP_CR){ 00474 //CRの無視 00475 return NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONNECTION;//変化なし 00476 }else if(i_c==HTTP_LF){ 00477 //大文字化 00478 NyLPC_cStr_toUpper(&(i_inst->_wsb)); 00479 //Convert to ID 00480 o_out->connection=NyLPC_THttpMessgeHeader_Connection_UNKNOWN; 00481 for(i=0;id[i]!=NyLPC_THttpMessgeHeader_Connection_UNKNOWN;i++){ 00482 if(NyLPC_cStr_isEqual(&(i_inst->_wsb),str[i])){ 00483 o_out->connection=id[i]; 00484 break; 00485 } 00486 } 00487 NyLPC_cStr_clear(&(i_inst->_wsb)); 00488 return NyLPC_TcHttpBasicHeaderParser_ST_MSGHEAD; 00489 } 00490 if(!NyLPC_cStr_put(&(i_inst->_wsb),i_c)){ 00491 i_inst->_rcode=500; 00492 NyLPC_OnErrorGoto(Error); 00493 } 00494 return NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONNECTION;//変化なし; 00495 Error: 00496 return NyLPC_TcHttpBasicHeaderParser_ST_ERROR; 00497 } 00498 00499 00500 static NyLPC_TcHttpBasicHeaderParser_ST parseMessage_ContentLength(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out) 00501 { 00502 char* e; 00503 char* p; 00504 00505 //先頭のスペース除外 00506 if(NyLPC_cStr_len(&(i_inst->_wsb))==0) 00507 { 00508 if(i_c==HTTP_SP){ 00509 return NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONTENTLENGTH;//変化なし 00510 } 00511 } 00512 if(i_c==HTTP_CR){ 00513 //CRの無視 00514 return NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONTENTLENGTH;//変化なし 00515 }else if(i_c==HTTP_LF){ 00516 p=NyLPC_cStr_str(&(i_inst->_wsb)); 00517 o_out->content_length=strtol(p,&e,10); 00518 if(e==p){ 00519 i_inst->_rcode=400; 00520 NyLPC_OnErrorGoto(Error);//ギャー 00521 } 00522 NyLPC_cStr_clear(&(i_inst->_wsb)); 00523 return NyLPC_TcHttpBasicHeaderParser_ST_MSGHEAD; 00524 } 00525 if(!NyLPC_cStr_put(&(i_inst->_wsb),i_c)){ 00526 i_inst->_rcode=500; 00527 NyLPC_OnErrorGoto(Error); 00528 } 00529 return NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONTENTLENGTH;//変化なし; 00530 Error: 00531 return NyLPC_TcHttpBasicHeaderParser_ST_ERROR; 00532 } 00533 00534 static NyLPC_TcHttpBasicHeaderParser_ST parseStatusCode(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out) 00535 { 00536 NyLPC_TcStr_t* ws=&(i_inst->_wsb); 00537 char* e; 00538 char* p; 00539 00540 //先頭のスペース除外 00541 if(NyLPC_cStr_len(ws)==0) 00542 { 00543 if(i_c==HTTP_SP){ 00544 return NyLPC_TcHttpBasicHeaderParser_ST_SL_STATUSCODE;//変化なし 00545 } 00546 } 00547 if(i_c==HTTP_SP){ 00548 //SPで終了 00549 p=NyLPC_cStr_str(ws); 00550 o_out->startline.res.status=(strtol(p,&e,10)); 00551 if(e==p){ 00552 i_inst->_rcode=400; 00553 NyLPC_OnErrorGoto(Error);//ギャー 00554 } 00555 NyLPC_cStr_clear(ws); 00556 return NyLPC_TcHttpBasicHeaderParser_ST_SL_REASON; 00557 } 00558 if(!NyLPC_cStr_put(ws,i_c)){ 00559 i_inst->_rcode=500; 00560 NyLPC_OnErrorGoto(Error); 00561 } 00562 return NyLPC_TcHttpBasicHeaderParser_ST_SL_STATUSCODE;//変化なし; 00563 Error: 00564 return NyLPC_TcHttpBasicHeaderParser_ST_ERROR; 00565 } 00566 static NyLPC_TcHttpBasicHeaderParser_ST parseReason(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c) 00567 { 00568 NyLPC_TcStr_t* ws=&(i_inst->_wsb); 00569 //LFくるまで飛ばす。 00570 switch(i_c){ 00571 case HTTP_LF: 00572 NyLPC_cStr_clear(ws); 00573 return NyLPC_TcHttpBasicHeaderParser_ST_MSGHEAD; 00574 default: 00575 break; 00576 } 00577 //URLパーサへ通知 00578 return NyLPC_TcHttpBasicHeaderParser_ST_SL_REASON;//変化なし 00579 } 00580 static NyLPC_TcHttpBasicHeaderParser_ST parseMessageParam(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out) 00581 { 00582 NyLPC_TcStr_t* ws=&(i_inst->_wsb); 00583 //先頭のスペース除外 00584 if(NyLPC_cStr_len(ws)==0){ 00585 if(i_c==HTTP_SP){ 00586 return NyLPC_TcHttpBasicHeaderParser_ST_MSGPARAM;//変化なし 00587 }else{ 00588 NyLPC_cStr_put(ws,'C');//開始フラグ 00589 } 00590 } 00591 switch(i_c){ 00592 case HTTP_CR: 00593 return NyLPC_TcHttpBasicHeaderParser_ST_MSGPARAM;//変化なし 00594 case HTTP_LF: 00595 //メッセージフィールドの終端を通知 00596 if(i_inst->_handler->messageHandler!=NULL){ 00597 if(!i_inst->_handler->messageHandler(i_inst,NULL,0,o_out)){ 00598 i_inst->_rcode=500; 00599 NyLPC_OnErrorGoto(Error); 00600 } 00601 } 00602 NyLPC_cStr_clear(ws); 00603 return NyLPC_TcHttpBasicHeaderParser_ST_MSGHEAD; 00604 default: 00605 //メッセージフィールドの追記 00606 if(i_inst->_handler->messageHandler!=NULL){ 00607 if(!i_inst->_handler->messageHandler(i_inst,NULL,i_c,o_out)){ 00608 i_inst->_rcode=500; 00609 NyLPC_OnErrorGoto(Error); 00610 } 00611 } 00612 break; 00613 } 00614 //URLパーサへ通知 00615 return NyLPC_TcHttpBasicHeaderParser_ST_MSGPARAM;//変化なし 00616 Error: 00617 return NyLPC_TcHttpBasicHeaderParser_ST_ERROR; 00618 } 00619 00620 static NyLPC_TcHttpBasicHeaderParser_ST parseMessage1(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out) 00621 { 00622 const static char* KNOWN_MSG[]={"CONNECTION","CONTENT-LENGTH","TRANSFER-ENCODING",NULL}; 00623 int i; 00624 00625 switch(i_c){ 00626 case HTTP_DM: 00627 //メッセージの名前確定。遷移先判定 00628 //ヘッダ名を大文字にする。 00629 NyLPC_cStr_toUpper(&(i_inst->_wsb)); 00630 for(i=0;KNOWN_MSG[i]!=NULL;i++){ 00631 if(NyLPC_cStr_isEqual(&(i_inst->_wsb),KNOWN_MSG[i])){ 00632 //確定。 00633 NyLPC_cStr_clear(&(i_inst->_wsb)); 00634 switch(i){ 00635 case 0://CONNECTION 00636 return NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONNECTION; 00637 case 1://CONTENT-LENGTH 00638 return NyLPC_TcHttpBasicHeaderParser_ST_MSG_CONTENTLENGTH; 00639 case 2://TRANSFER-ENCODING 00640 return NyLPC_TcHttpBasicHeaderParser_ST_MSG_TRANSFERENCODING; 00641 default://エラー 00642 break; 00643 } 00644 i_inst->_rcode=500; 00645 NyLPC_OnErrorGoto(Error); 00646 } 00647 } 00648 //メッセージフィールドの名前を通知 00649 if(i_inst->_handler->messageHandler!=NULL){ 00650 if(!i_inst->_handler->messageHandler(i_inst,NyLPC_cStr_str(&(i_inst->_wsb)),0,o_out)){ 00651 i_inst->_rcode=500; 00652 NyLPC_OnErrorGoto(Error); 00653 } 00654 NyLPC_cStr_clear(&(i_inst->_wsb)); 00655 } 00656 //カスタムヘッダ解析へ。 00657 return NyLPC_TcHttpBasicHeaderParser_ST_MSGPARAM; 00658 case HTTP_CR: 00659 return NyLPC_TcHttpBasicHeaderParser_ST_MSGHEAD;//変化なし 00660 case HTTP_LF: 00661 //1文字で終了ならパースエンド。バリデーションチェックへ 00662 if(NyLPC_cStr_len(&(i_inst->_wsb))==0){ 00663 NyLPC_cStr_clear(&(i_inst->_wsb)); 00664 return NyLPC_TcHttpBasicHeaderParser_ST_EOH; 00665 } 00666 //これはひどい。 00667 i_inst->_rcode=400; 00668 NyLPC_OnErrorGoto(Error); 00669 default: 00670 break; 00671 } 00672 if(!NyLPC_cStr_put(&(i_inst->_wsb),i_c)){ 00673 i_inst->_rcode=500; 00674 NyLPC_OnErrorGoto(Error); 00675 } 00676 return NyLPC_TcHttpBasicHeaderParser_ST_MSGHEAD;//変化なし; 00677 Error: 00678 return NyLPC_TcHttpBasicHeaderParser_ST_ERROR; 00679 } 00680 00681 static NyLPC_TcHttpBasicHeaderParser_ST parseVersion(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,NyLPC_TcHttpBasicHeaderParser_ST i_next,struct NyLPC_THttpBasicHeader* o_out) 00682 { 00683 //先頭のスペース除外 00684 if(NyLPC_cStr_len(&(i_inst->_wsb))==0){ 00685 if(i_c==HTTP_SP){ 00686 return NyLPC_TcHttpBasicHeaderParser_ST_RL_VERSION;//変化なし 00687 } 00688 } 00689 if(i_c==HTTP_CR){ 00690 //CRの無視 00691 return NyLPC_TcHttpBasicHeaderParser_ST_RL_VERSION;//変化なし 00692 }else if(i_c==HTTP_LF){ 00693 //LFで確定 00694 if(!parseHttpVersionStr(&(i_inst->_wsb),&(o_out->startline.req.version))){ 00695 i_inst->_rcode=505; 00696 NyLPC_cStr_clear(&(i_inst->_wsb)); 00697 NyLPC_OnErrorGoto(Error); 00698 } 00699 NyLPC_cStr_clear(&(i_inst->_wsb)); 00700 return i_next;//遷移(エラーの時はそのままエラーコードが渡る。) 00701 } 00702 if(!NyLPC_cStr_put(&(i_inst->_wsb),i_c)){ 00703 //追記処理しっぱい 00704 i_inst->_rcode=500; 00705 NyLPC_OnErrorGoto(Error); 00706 } 00707 return NyLPC_TcHttpBasicHeaderParser_ST_RL_VERSION;//変化なし 00708 Error: 00709 return NyLPC_TcHttpBasicHeaderParser_ST_ERROR; 00710 } 00711 00712 /** 00713 URLパーサ。登録した関数に転送する? 00714 */ 00715 static NyLPC_TcHttpBasicHeaderParser_ST parseRequestUrl(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out) 00716 { 00717 //先頭のスペース除外 00718 if(NyLPC_cStr_len(&(i_inst->_wsb))==0){ 00719 if(i_c==HTTP_SP){ 00720 return NyLPC_TcHttpBasicHeaderParser_ST_RL_URL;//変化なし 00721 }else{ 00722 NyLPC_cStr_put(&(i_inst->_wsb),'C');//開始フラグ 00723 } 00724 } 00725 //次のスペースがくるまで。 00726 if(i_c==HTTP_SP){ 00727 NyLPC_cStr_clear(&(i_inst->_wsb)); 00728 //URLハンドラへ通知 00729 if(i_inst->_handler->urlHandler!=NULL){ 00730 if(!i_inst->_handler->urlHandler(i_inst,0,o_out)){ 00731 i_inst->_rcode=500; 00732 NyLPC_OnErrorGoto(Error); 00733 } 00734 } 00735 return NyLPC_TcHttpBasicHeaderParser_ST_RL_VERSION; 00736 } 00737 //URLパーサへ通知 00738 if(i_inst->_handler->urlHandler!=NULL){ 00739 if(!i_inst->_handler->urlHandler(i_inst,i_c,o_out)){ 00740 i_inst->_rcode=500; 00741 NyLPC_OnErrorGoto(Error); 00742 } 00743 } 00744 return NyLPC_TcHttpBasicHeaderParser_ST_RL_URL;//変化なし 00745 Error: 00746 return NyLPC_TcHttpBasicHeaderParser_ST_ERROR; 00747 } 00748 00749 /** 00750 Methodパーサ 00751 [:HTTPMETHOD:]を得る。 00752 */ 00753 static NyLPC_TcHttpBasicHeaderParser_ST parseStartLine(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out) 00754 { 00755 if(i_c==HTTP_SP){ 00756 //SPがデリミタ 00757 //HTTPステータスを試す。 00758 if(parseHttpVersionStr(&(i_inst->_wsb),&(o_out->startline.res.version))){ 00759 //これはHTTPステータス 00760 o_out->type=NyLPC_THttpHeaderType_RESPONSE; 00761 NyLPC_cStr_clear(&(i_inst->_wsb)); 00762 return NyLPC_TcHttpBasicHeaderParser_ST_SL_STATUSCODE; 00763 } 00764 //HTTPリクエストを試す。 00765 if(!parseRequestMethodStr(&(i_inst->_wsb),&(o_out->startline.req.method))){ 00766 i_inst->_rcode=400; 00767 NyLPC_OnErrorGoto(ERROR); 00768 } 00769 //これはHTTPリクエスト 00770 o_out->type=NyLPC_THttpHeaderType_REQUEST; 00771 NyLPC_cStr_clear(&(i_inst->_wsb)); 00772 return NyLPC_TcHttpBasicHeaderParser_ST_RL_URL; 00773 } 00774 if(!NyLPC_cStr_put(&(i_inst->_wsb),i_c)){ 00775 i_inst->_rcode=500; 00776 NyLPC_OnErrorGoto(ERROR); 00777 } 00778 return NyLPC_TcHttpBasicHeaderParser_ST_START;//変化なし 00779 ERROR: 00780 return NyLPC_TcHttpBasicHeaderParser_ST_ERROR; 00781 } 00782 00783 00784 00785 00786 00787 static NyLPC_TBool parseHttpVersionStr(NyLPC_TcStr_t* i_str,NyLPC_THttpVersion* o_out) 00788 { 00789 NyLPC_TChar* p; 00790 char* e; 00791 long ma,mi; 00792 00793 p=NyLPC_cStr_str(i_str); 00794 if(NyLPC_cStr_len(i_str)<6){ 00795 NyLPC_OnErrorGoto(Error); 00796 } 00797 if(strncmp(p,"HTTP/",5)!=0){ 00798 NyLPC_OnErrorGoto(Error); 00799 } 00800 p+=5; 00801 ma=strtol(p,&e,10); 00802 if(p==e){ 00803 NyLPC_OnErrorGoto(Error); 00804 } 00805 p=e;//.をチェック 00806 if(*p!='.'){ 00807 NyLPC_OnErrorGoto(Error); 00808 } 00809 p++; 00810 mi=strtoul(p,&e,10); 00811 if(p==e){ 00812 NyLPC_OnErrorGoto(Error); 00813 } 00814 if(ma<0 ||mi<0){ 00815 NyLPC_OnErrorGoto(Error); 00816 } 00817 switch(ma){ 00818 case 0: 00819 if(mi>=9){ 00820 //HTTP0.9相当 00821 *o_out=NyLPC_THttpVersion_09; 00822 } 00823 break; 00824 case 1: 00825 if(mi==0){ 00826 //HTTP1.0 00827 *o_out=NyLPC_THttpVersion_10; 00828 }else if(mi>=1){ 00829 //HTTP1.1 00830 *o_out=NyLPC_THttpVersion_11; 00831 }else{ 00832 *o_out=NyLPC_THttpVersion_UNKNOWN; 00833 } 00834 break; 00835 default: 00836 //お前など知らん 00837 *o_out=NyLPC_THttpVersion_UNKNOWN; 00838 break; 00839 } 00840 return NyLPC_TBool_TRUE;//変化なし 00841 Error: 00842 return NyLPC_TBool_FALSE; 00843 } 00844
Generated on Tue Jul 12 2022 15:46:15 by 1.7.2