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