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_cModUrl.c Source File

NyLPC_cModUrl.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_cModUrl.h"
00027 #include "NyLPC_stdlib.h"
00028 #include "NyLPC_http.h"
00029 #include "../NyLPC_cHttpdUtils.h"
00030 #include "../NyLPC_cHttpdConnection_protected.h"
00031 
00032 typedef struct TcHeaderParser
00033 {
00034     NyLPC_TcHttpBasicHeaderParser_t super;
00035     char* url_buf;
00036     NyLPC_TInt16 length_of_buf;
00037     NyLPC_TInt16 length_of_url;
00038     NyLPC_TInt16 reason;
00039     NyLPC_TUInt8 skip;
00040     NyLPC_TUInt8 mode;
00041 }TcHeaderParser_t;
00042 
00043 
00044 
00045 static NyLPC_TBool NyLPC_cModUrl_urlHandler(NyLPC_TcHttpBasicHeaderParser_t* i_inst,NyLPC_TChar i_c,struct NyLPC_THttpBasicHeader* o_out)
00046 {
00047     TcHeaderParser_t* inst=(TcHeaderParser_t*)i_inst;
00048     if(inst->skip){
00049         //SKIPが有効な場合
00050         if(inst->length_of_url<0){
00051             inst->length_of_url++;
00052             if(inst->length_of_url==0){
00053                 inst->skip=NyLPC_TUInt8_FALSE;
00054             }
00055         }
00056         return NyLPC_TBool_TRUE;
00057     }
00058     if((inst->mode & NyLPC_cModUrl_ParseMode_PATH_ONLY)==NyLPC_cModUrl_ParseMode_PATH_ONLY){
00059         if(strchr("?#",i_c)){
00060             inst->url_buf[inst->length_of_url]='\0';
00061             inst->skip=NyLPC_TUInt8_TRUE;
00062             return NyLPC_TBool_TRUE;//Terminate
00063         }
00064     }
00065     inst->url_buf[inst->length_of_url]=i_c;
00066     if(i_c=='\0'){
00067         return NyLPC_TBool_TRUE;//Terminate
00068     }
00069     inst->length_of_url++;
00070     if(inst->length_of_url==inst->length_of_buf){
00071         inst->reason=414;
00072         return NyLPC_TBool_FALSE;//長すぎる。
00073     }
00074 
00075     return NyLPC_TBool_TRUE;
00076 }
00077 /**
00078  * デフォルトハンドラ
00079  */
00080 static const struct NyLPC_TcHttpBasicHeaderParser_Handler _handler=
00081 {
00082     NULL,
00083     NyLPC_cModUrl_urlHandler
00084 };
00085 
00086 
00087 
00088 void NyLPC_cModUrl_initialize(NyLPC_TcModUrl_t* i_inst)
00089 {
00090     NyLPC_cHttpBodyParser_initialize(&i_inst->_body_parser);
00091 }
00092 void NyLPC_cModUrl_finalize(NyLPC_TcModUrl_t* i_inst)
00093 {
00094     NyLPC_cHttpBodyParser_finalize(&i_inst->_body_parser);
00095 }
00096 
00097 const struct NyLPC_THttpBasicHeader* NyLPC_cModUrl_getHeader(const NyLPC_TcModUrl_t* i_inst)
00098 {
00099     return &(i_inst->_header);
00100 }
00101 
00102 /**
00103  * Methodタイプを返します。
00104  */
00105 NyLPC_THttpMethodType NyLPC_cModUrl_getMethod(const NyLPC_TcModUrl_t* i_inst)
00106 {
00107     return i_inst->_header.startline.req.method;
00108 }
00109 
00110 
00111 
00112 NyLPC_TBool NyLPC_cModUrl_execute2(NyLPC_TcModUrl_t* i_inst,NyLPC_TcHttpdConnection_t* i_connection,char* o_url_buf,NyLPC_TInt16 i_length_buf,NyLPC_TInt16 i_pass_prefix_len,NyLPC_cModUrl_ParseMode i_mode)
00113 {
00114     TcHeaderParser_t parser;
00115     NyLPC_Assert(i_length_buf>0);
00116     NyLPC_Assert(i_pass_prefix_len>=0);
00117     //コネクションのステータスチェック
00118     if(!NyLPC_cHttpdConnection_getReqStatus(i_connection)==NyLPC_cHttpdConnection_ReqStatus_REQPARSE)
00119     {
00120         NyLPC_OnErrorGoto(Error1);
00121     }
00122     //リクエストParse済へ遷移
00123     NyLPC_cHttpdConnection_setReqStatusParsed(i_connection);
00124 
00125     NyLPC_cHttpBasicHeaderParser_initialize(&parser.super,&_handler);
00126     parser.length_of_buf=i_length_buf;
00127     parser.length_of_url=-i_pass_prefix_len;//無視するPrefix長
00128     parser.skip=(parser.length_of_url<0)?NyLPC_TUInt8_TRUE:NyLPC_TUInt8_FALSE;//スキップの初期値の設定
00129     parser.url_buf=o_url_buf;
00130     parser.url_buf[0]='\0';//URL長<=prefix長に備えてNULLターミネイト
00131     parser.reason=400;
00132     parser.mode=i_mode;
00133     //プリフェッチしたデータを流す
00134     NyLPC_cHttpBasicHeaderParser_parseInit(&parser.super,&(i_inst->_header));
00135     NyLPC_cHttpdConnection_pushPrefetchInfo(i_connection,&parser.super,&(i_inst->_header));
00136     //後続をストリームから取り込む
00137     if(!NyLPC_cHttpBasicHeaderParser_parseStream(&parser.super,NyLPC_cHttpdConnection_refStream(i_connection),&(i_inst->_header))){
00138         NyLPC_OnErrorGoto(Error2);
00139     }
00140     if(!NyLPC_cHttpBasicHeaderParser_parseFinish(&parser.super,&(i_inst->_header))){
00141         NyLPC_OnErrorGoto(Error2);
00142     }
00143     //@todo http/1.1 && POSTの場合はcontinueを送る。
00144     if(i_inst->_header.startline.req.version==NyLPC_THttpVersion_11){
00145         if(i_inst->_header.startline.req.method==NyLPC_THttpMethodType_POST)
00146         {
00147             NyLPC_cHttpdConnection_send100Continue(i_connection);
00148         }
00149     }
00150     //Request::ConnectionがClose設定,又はHTTP1.1では無い場合,CLOSE
00151     if(i_inst->_header.connection==NyLPC_THttpMessgeHeader_Connection_CLOSE || i_inst->_header.startline.req.version!=NyLPC_THttpVersion_11)
00152     {
00153         NyLPC_cHttpdConnection_setConnectionMode(i_connection,NyLPC_TcHttpdConnection_CONNECTION_MODE_CLOSE);
00154     }
00155 
00156     NyLPC_cHttpBasicHeaderParser_finalize(&parser);
00157     //BodyParserの初期化
00158     if(NyLPC_cHttpBodyParser_getState(&i_inst->_body_parser)!=NyLPC_TcHttpBasicBodyParser_ST_NULL){
00159         NyLPC_cHttpBodyParser_parseFinish(&i_inst->_body_parser);
00160     }
00161     NyLPC_cHttpBodyParser_parseInit(&i_inst->_body_parser,&i_inst->_header);
00162     return NyLPC_TBool_TRUE;
00163 Error2:
00164     //400Error
00165     NyLPC_cHttpdUtils_sendErrorResponse(i_connection,parser.reason);
00166     NyLPC_cHttpBasicHeaderParser_finalize(&parser);
00167 Error1:
00168     return NyLPC_TBool_FALSE;
00169 }
00170 
00171 
00172 
00173 
00174 
00175 NyLPC_TInt16 NyLPC_cModUrl_readBody(NyLPC_TcModUrl_t* i_inst,NyLPC_TcHttpdConnection_t* i_connection,void* i_buf,NyLPC_TInt16 i_buf_size)
00176 {
00177     NyLPC_TInt16 l;
00178     //リクエストは解析済であること
00179     if(!NyLPC_cHttpdConnection_getReqStatus(i_connection)==NyLPC_cHttpdConnection_ReqStatus_END)
00180     {
00181         return -1;
00182     }
00183     if(!NyLPC_cHttpBodyParser_parseStream(&i_inst->_body_parser,NyLPC_cHttpdConnection_refStream(i_connection),i_buf,i_buf_size,&l)){
00184         return -1;
00185     }
00186     return l;
00187 }
00188