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
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 16:22:57 by
