This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088
Dependents: MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more
NyLPC_cHttpClient.c
00001 /* 00002 * NyLPC_cHttpClient.c 00003 * 00004 * Created on: 2013/08/24 00005 * Author: nyatla 00006 */ 00007 #include "NyLPC_cHttpClient.h" 00008 typedef NyLPC_TUInt8 NyLPC_TcHttpClient_ST; 00009 #define NyLPC_TcHttpClient_ST_CLOSED 0x00 //ソケット切断 00010 #define NyLPC_TcHttpClient_ST_IDLE 0x01 //メソッド選択待ち 00011 00012 #define NyLPC_TcHttpClient_ST_SEND_REQ_BODY 0x21 //POSTリクエスト送信中 00013 #define NyLPC_TcHttpClient_ST_RECV_RES_HEAD 0x23 00014 #define NyLPC_TcHttpClient_ST_RECV_RES_BODY 0x24 00015 00016 00017 00018 NyLPC_TBool NyLPC_cHttpClient_initialize(NyLPC_TcHttpClient_t* i_inst,void* i_rx_buf,NyLPC_TUInt16 i_rx_size) 00019 { 00020 i_inst->_sock=NyLPC_cNet_createTcpSocketEx(NyLPC_TSocketType_TCP_NORMAL); 00021 if(i_inst->_sock==NULL){ 00022 return NyLPC_TBool_FALSE; 00023 } 00024 i_inst->_state=NyLPC_TcHttpClient_ST_CLOSED; 00025 return NyLPC_TBool_TRUE; 00026 } 00027 void NyLPC_cHttpClient_finalize(NyLPC_TcHttpClient_t* i_inst) 00028 { 00029 NyLPC_cHttpClient_close(i_inst); 00030 NyLPC_iTcpSocket_finalize(i_inst->_sock); 00031 } 00032 00033 void NyLPC_cHttpClient_close(NyLPC_TcHttpClient_t* i_inst) 00034 { 00035 //ステータスをclosedへ遷移 00036 switch(i_inst->_state){ 00037 case NyLPC_TcHttpClient_ST_RECV_RES_BODY: 00038 NyLPC_cHttpBodyParser_finalize(&i_inst->pw.body_parser); 00039 break; 00040 case NyLPC_TcHttpClient_ST_SEND_REQ_BODY: 00041 NyLPC_cHttpBodyWriter_finalize(&(i_inst->pw.body_writer)); 00042 break; 00043 case NyLPC_TcHttpClient_ST_RECV_RES_HEAD: 00044 //開放するものとくにない 00045 break; 00046 case NyLPC_TcHttpClient_ST_IDLE: 00047 break; 00048 case NyLPC_TcHttpClient_ST_CLOSED: 00049 return; 00050 } 00051 NyLPC_iTcpSocket_close(i_inst->_sock,1000); 00052 i_inst->_state=NyLPC_TcHttpClient_ST_CLOSED; 00053 } 00054 00055 /** 00056 * サーバに接続する。 00057 * 関数はステータスをIDLEへ遷移する。 00058 * インスタンスのステータスは何でも構わない。 00059 * @return 00060 * TRUE - ステータスはIDLEへ遷移する。 00061 * FALSE - ステータスはCLOSEDへ遷移する。 00062 */ 00063 NyLPC_TBool NyLPC_cHttpClient_connect(NyLPC_TcHttpClient_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port) 00064 { 00065 //ステータスをclosedへ遷移 00066 NyLPC_cHttpClient_close(i_inst); 00067 //接続 00068 if(!NyLPC_iTcpSocket_connect(i_inst->_sock,i_addr,i_port,3000)){ 00069 return NyLPC_TBool_FALSE; 00070 } 00071 //streamの生成 00072 if(!NyLPC_cHttpStream_initialize(&i_inst->_stream,i_inst->_sock)){ 00073 NyLPC_OnErrorGoto(ERROR); 00074 } 00075 //ステータス遷移 00076 i_inst->_state=NyLPC_TcHttpClient_ST_IDLE; 00077 return NyLPC_TBool_TRUE; 00078 ERROR: 00079 return NyLPC_TBool_FALSE; 00080 } 00081 00082 00083 00084 /** 00085 * POSTリクエストを送信する。 00086 * @return 00087 * 引き続き処理が可能かを返す。 00088 */ 00089 NyLPC_TBool NyLPC_cHttpClient_sendMethod( 00090 NyLPC_TcHttpClient_t* i_inst, 00091 NyLPC_THttpMethodType i_method, 00092 const NyLPC_TChar* i_path, 00093 NyLPC_TUInt32 i_content_length, 00094 const NyLPC_TChar* i_mime_type, 00095 const NyLPC_TChar* i_additional_header) 00096 { 00097 //ステータスチェック 00098 if(i_inst->_state!=NyLPC_TcHttpClient_ST_IDLE){ 00099 NyLPC_OnErrorGoto(Error_0); 00100 } 00101 //POSTリクエストの送信 00102 if(!NyLPC_cHttpHeaderWriter_initialize(&i_inst->pw.head_writer,&i_inst->_stream.super,NULL)){ 00103 NyLPC_OnErrorGoto(Error_0); 00104 } 00105 //ヘッダを送信 00106 NyLPC_cHttpHeaderWriter_setConnectionClose(&i_inst->pw.head_writer,NyLPC_TBool_TRUE);//Connection closeを強制 00107 if(i_content_length==NyLPC_cHttpHeaderWriter_CONTENT_LENGTH_UNLIMITED){ 00108 NyLPC_cHttpHeaderWriter_setChunked(&i_inst->pw.head_writer); 00109 }else{ 00110 NyLPC_cHttpHeaderWriter_setContentLength(&i_inst->pw.head_writer,i_content_length); 00111 } 00112 if(!NyLPC_cHttpHeaderWriter_writeRequestHeader( 00113 &i_inst->pw.head_writer, 00114 i_method, 00115 NyLPC_iTcpSocket_getPeerAddr((i_inst->_sock)), 00116 NyLPC_iTcpSocket_getPeerPort((i_inst->_sock)),i_path)){ 00117 NyLPC_OnErrorGoto(Error_1); 00118 } 00119 //MimeType 00120 if(i_mime_type!=NULL){ 00121 if(!NyLPC_cHttpHeaderWriter_writeMessage(&i_inst->pw.head_writer,"Content-type",i_mime_type)){ 00122 NyLPC_OnErrorGoto(Error_1); 00123 } 00124 } 00125 if(i_additional_header!=NULL){ 00126 if(!NyLPC_cHttpHeaderWriter_writeRawMessage(&i_inst->pw.head_writer,i_additional_header)){ 00127 NyLPC_OnErrorGoto(Error_1); 00128 } 00129 } 00130 NyLPC_cHttpHeaderWriter_close(&i_inst->pw.head_writer); 00131 NyLPC_cHttpHeaderWriter_finalize(&i_inst->pw.head_writer); 00132 00133 //BodyWriter生成 00134 NyLPC_cHttpBodyWriter_initialize(&(i_inst->pw.body_writer),&(i_inst->_stream)); 00135 //bodyのchunkedもセット 00136 if(i_content_length==0xffffffff){ 00137 NyLPC_cHttpBodyWriter_setChunked(&(i_inst->pw.body_writer)); 00138 }else{ 00139 NyLPC_cHttpBodyWriter_setContentLength(&(i_inst->pw.body_writer),i_content_length); 00140 } 00141 i_inst->_state=NyLPC_TcHttpClient_ST_SEND_REQ_BODY; 00142 return NyLPC_TBool_TRUE; 00143 Error_0: 00144 return NyLPC_TBool_FALSE; 00145 Error_1: 00146 NyLPC_cHttpHeaderWriter_finalize(&i_inst->pw.head_writer); 00147 return NyLPC_TBool_FALSE; 00148 } 00149 00150 /** 00151 * POSTリクエストのデータを送信する。 00152 * @return 00153 * 0:EOF 00154 */ 00155 NyLPC_TBool NyLPC_cHttpClient_write(NyLPC_TcHttpClient_t* i_inst,const void* i_buf,NyLPC_TUInt32 i_buf_size) 00156 { 00157 if(i_inst->_state!=NyLPC_TcHttpClient_ST_SEND_REQ_BODY){ 00158 return NyLPC_TBool_FALSE; 00159 } 00160 if(!NyLPC_cHttpBodyWriter_write(&i_inst->pw.body_writer,i_buf,i_buf_size)){ 00161 //ERROR 00162 NyLPC_cHttpClient_close(i_inst); 00163 NyLPC_OnErrorGoto(Error); 00164 } 00165 return NyLPC_TBool_TRUE; 00166 Error: 00167 return NyLPC_TBool_FALSE; 00168 } 00169 00170 NyLPC_TBool NyLPC_cHttpClient_writeFormat(NyLPC_TcHttpClient_t* i_inst,const NyLPC_TChar* i_fmt,...) 00171 { 00172 NyLPC_TBool ret; 00173 va_list a; 00174 if(i_inst->_state!=NyLPC_TcHttpClient_ST_SEND_REQ_BODY){ 00175 return NyLPC_TBool_FALSE; 00176 } 00177 va_start(a,i_fmt); 00178 ret=NyLPC_cHttpBodyWriter_formatV(&i_inst->pw.body_writer,i_fmt,a); 00179 va_end(a); 00180 if(!ret){ 00181 NyLPC_cHttpClient_close(i_inst); 00182 } 00183 return ret; 00184 } 00185 NyLPC_TBool NyLPC_cHttpClient_writeFormatV(NyLPC_TcHttpClient_t* i_inst,const NyLPC_TChar* i_fmt,va_list i_args) 00186 { 00187 NyLPC_TBool ret; 00188 if(i_inst->_state!=NyLPC_TcHttpClient_ST_SEND_REQ_BODY){ 00189 return NyLPC_TBool_FALSE; 00190 } 00191 ret=NyLPC_cHttpBodyWriter_formatV(&i_inst->pw.body_writer,i_fmt,i_args); 00192 if(!ret){ 00193 NyLPC_cHttpClient_close(i_inst); 00194 } 00195 return ret; 00196 } 00197 00198 00199 /** 00200 * ステータスコードを返す。 00201 * @return 00202 * ステータスコード 00203 */ 00204 NyLPC_TUInt16 NyLPC_cHttpClient_getStatus(NyLPC_TcHttpClient_t* i_inst) 00205 { 00206 struct NyLPC_THttpBasicHeader header; 00207 if(i_inst->_state!=NyLPC_TcHttpClient_ST_SEND_REQ_BODY){ 00208 return 0; 00209 } 00210 // 00211 if(!NyLPC_cHttpBodyWriter_close(&i_inst->pw.body_writer)){ 00212 NyLPC_OnErrorGoto(Error_1); 00213 } 00214 i_inst->_state=NyLPC_TcHttpClient_ST_RECV_RES_HEAD; 00215 //100を無視してHTTPヘッダをパース 00216 //@todo POSTの時だけに制限したら? 00217 do{ 00218 NyLPC_cHttpBasicHeaderParser_initialize(&i_inst->pw.head_parser,NULL); 00219 NyLPC_cHttpBasicHeaderParser_parseInit(&i_inst->pw.head_parser,&header); 00220 if(!NyLPC_cHttpBasicHeaderParser_parseStream(&i_inst->pw.head_parser,&i_inst->_stream.super,&header)){ 00221 NyLPC_OnErrorGoto(Error_2); 00222 } 00223 if(!NyLPC_cHttpBasicHeaderParser_parseFinish(&i_inst->pw.head_parser,&header)){ 00224 NyLPC_OnErrorGoto(Error_2); 00225 } 00226 NyLPC_cHttpBasicHeaderParser_finalize(&i_inst->pw.head_parser); 00227 //レスポンスヘッダか確認 00228 if(header.type!=NyLPC_THttpHeaderType_RESPONSE){ 00229 NyLPC_OnErrorGoto(Error_1); 00230 } 00231 }while(header.startline.res.status==100); 00232 //BodyParserを起動 00233 NyLPC_cHttpBodyParser_initialize(&i_inst->pw.body_parser); 00234 NyLPC_cHttpBodyParser_parseInit(&i_inst->pw.body_parser,&header); 00235 i_inst->_state=NyLPC_TcHttpClient_ST_RECV_RES_BODY; 00236 return header.startline.res.status; 00237 Error_1: 00238 NyLPC_cHttpClient_close(i_inst); 00239 return 0; 00240 Error_2: 00241 NyLPC_cHttpBasicHeaderParser_finalize(&i_inst->pw.head_parser); 00242 NyLPC_cHttpClient_close(i_inst); 00243 return 0; 00244 } 00245 00246 00247 /** 00248 * GET/POSTリクエストで受信したデータを読み出す。 00249 * @param o_read_len 00250 * 戻り値TRUEの場合のみ有効。 00251 * 終端の場合は0 00252 * @return 00253 * TRUE:正常読み出し。o_read_lenの値で終端判定 00254 * FALSE:失敗。コネクションはクローズされる。 00255 */ 00256 NyLPC_TBool NyLPC_cHttpClient_read(NyLPC_TcHttpClient_t* i_inst,void* i_buf,NyLPC_TUInt32 i_buf_size,NyLPC_TInt16* o_read_len) 00257 { 00258 if(i_inst->_state!=NyLPC_TcHttpClient_ST_RECV_RES_BODY){ 00259 return NyLPC_TBool_FALSE; 00260 } 00261 if(!NyLPC_cHttpBodyParser_parseStream(&i_inst->pw.body_parser,&i_inst->_stream.super,i_buf,i_buf_size,o_read_len)){ 00262 NyLPC_cHttpClient_close(i_inst); 00263 return NyLPC_TBool_FALSE; 00264 } 00265 return NyLPC_TBool_TRUE; 00266 } 00267
Generated on Tue Jul 12 2022 15:46:15 by 1.7.2