This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088

Dependents:   MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers NyLPC_cHttpBasicHeaderParser.c Source File

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