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_cHttpHeaderWriter.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 <stdlib.h> 00027 00028 #include "NyLPC_cHttpHeaderWriter.h" 00029 #include "NyLPC_cHttpdConfig.h" 00030 00031 00032 /** 00033 * Httpリクエストヘッダに対応したHttpヘッダライタを構築します。 00034 */ 00035 NyLPC_TBool NyLPC_cHttpHeaderWriter_initialize(NyLPC_TcHttpHeaderWriter_t* i_inst,NyLPC_TiHttpPtrStream_t* i_ref_stream,const struct NyLPC_THttpBasicHeader* i_req_header) 00036 { 00037 i_inst->_is_chunked=NyLPC_TUInt8_FALSE; 00038 i_inst->_content_length=0; 00039 i_inst->_ref_stream=i_ref_stream; 00040 i_inst->_is_error=NyLPC_TUInt8_FALSE; 00041 //書込エンコーディングをなしにセット 00042 NyLPC_iHttpPtrStream_setWriteEncoding(i_inst->_ref_stream,NyLPC_TiHttpPtrStream_ET_NONE); 00043 //必要に応じてリクエストの内容をパース 00044 if(i_req_header!=NULL){ 00045 if(i_req_header->type!=NyLPC_THttpHeaderType_REQUEST){ 00046 return NyLPC_TBool_FALSE; 00047 } 00048 //コネクションの持続性を決定 00049 if((i_req_header->connection==NyLPC_THttpMessgeHeader_Connection_CLOSE)|| 00050 (i_req_header->startline.req.version!=NyLPC_THttpVersion_11)) 00051 { 00052 i_inst->_is_close=NyLPC_TUInt8_TRUE; 00053 }else{ 00054 i_inst->_is_close=NyLPC_TUInt8_FALSE; 00055 } 00056 }else{ 00057 i_inst->_is_close=NyLPC_TUInt8_TRUE; 00058 } 00059 return NyLPC_TBool_TRUE; 00060 } 00061 00062 #define NyLPC_cHttpHttpWriter_finalize(i) 00063 00064 00065 void NyLPC_cHttpHeaderWriter_setChunked(NyLPC_TcHttpHeaderWriter_t* i_inst) 00066 { 00067 i_inst->_is_chunked=NyLPC_TUInt8_TRUE; 00068 return; 00069 } 00070 void NyLPC_cHttpHeaderWriter_setContentLength(NyLPC_TcHttpHeaderWriter_t* i_inst,NyLPC_TUInt32 i_content_length) 00071 { 00072 i_inst->_content_length=i_content_length; 00073 return; 00074 } 00075 void NyLPC_cHttpHeaderWriter_setConnectionClose(NyLPC_TcHttpHeaderWriter_t* i_inst,NyLPC_TBool i_is_close) 00076 { 00077 i_inst->_is_close=i_is_close; 00078 return; 00079 } 00080 00081 00082 00083 const static struct{ 00084 NyLPC_TUInt16 code; 00085 const NyLPC_TChar* message; 00086 }status_line_tbl[]={ 00087 {200,"OK"}, 00088 {301,"Moved Permanently"}, 00089 {302,"Moved Temporarily"}, 00090 {400,"Bad Request"}, 00091 {403,"Forbidden"}, 00092 {404,"Not Found"}, 00093 {405,"Method Not Allowed"}, 00094 {500,"Internal Server Error"}, 00095 {0,NULL}//これ最後にしてね。 00096 }; 00097 const static char* getStatusMessage(NyLPC_TUInt16 i_status) 00098 { 00099 int i=0; 00100 while(status_line_tbl[i].code!=0){ 00101 if(i_status==status_line_tbl[i].code){ 00102 return status_line_tbl[i].message; 00103 } 00104 i++; 00105 } 00106 return NULL; 00107 } 00108 00109 static NyLPC_TBool writeln(NyLPC_TiHttpPtrStream_t* i_inst,const void* i_data,NyLPC_TInt16 i_length) 00110 { 00111 if(NyLPC_iHttpPtrStream_write(i_inst,i_data,i_length)){ 00112 if(NyLPC_iHttpPtrStream_write(i_inst,"\r\n",2)){ 00113 return NyLPC_TBool_TRUE; 00114 } 00115 } 00116 return NyLPC_TBool_FALSE; 00117 } 00118 00119 00120 NyLPC_TBool NyLPC_cHttpHeaderWriter_writeRequestHeader(NyLPC_TcHttpHeaderWriter_t* i_inst,NyLPC_THttpMethodType i_method,const struct NyLPC_TIPv4Addr* i_host,NyLPC_TUInt16 i_port,const NyLPC_TChar* i_path) 00121 { 00122 const NyLPC_TChar* t; 00123 NyLPC_TChar v[16]; 00124 //エラー状態ならなにもしない。 00125 if(i_inst->_is_error){ 00126 return NyLPC_TBool_FALSE; 00127 } 00128 00129 t=NyLPC_THttpMethodType_toString(i_method); 00130 if(t==NULL){ 00131 return NyLPC_TBool_FALSE; 00132 } 00133 //リクエストラインの記述 00134 //Method 00135 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,t,-1)){ 00136 NyLPC_OnErrorGoto(Error); 00137 } 00138 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream," ",1)){ 00139 NyLPC_OnErrorGoto(Error); 00140 } 00141 //Path 00142 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,i_path,-1)){ 00143 NyLPC_OnErrorGoto(Error); 00144 } 00145 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream," HTTP/1.1\r\n",11)){ 00146 NyLPC_OnErrorGoto(Error); 00147 } 00148 //HOSTの記述 00149 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,"Host: ",6)){ 00150 NyLPC_OnErrorGoto(Error); 00151 } 00152 NyLPC_TIPv4Addr_toString(i_host,v); 00153 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,v,-1)){ 00154 NyLPC_OnErrorGoto(Error); 00155 } 00156 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,":",1)){ 00157 NyLPC_OnErrorGoto(Error); 00158 } 00159 NyLPC_uitoa (i_port,v,10); 00160 if(!writeln(i_inst->_ref_stream,v,-1)){ 00161 NyLPC_OnErrorGoto(Error); 00162 } 00163 00164 //close 00165 if(i_inst->_is_close){ 00166 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,"Connection: CLOSE\r\n",-1)){ 00167 NyLPC_OnErrorGoto(Error); 00168 } 00169 } 00170 00171 //chunked 00172 if(i_inst->_is_chunked){ 00173 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,"Transfer-Encoding: chunked\r\n",-1)){ 00174 NyLPC_OnErrorGoto(Error); 00175 } 00176 }else{ 00177 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,"Content-Length: ",-1)){ 00178 NyLPC_OnErrorGoto(Error); 00179 } 00180 NyLPC_uitoa (i_inst->_content_length,v,10); 00181 if(!writeln(i_inst->_ref_stream,v,-1)){ 00182 NyLPC_OnErrorGoto(Error); 00183 } 00184 } 00185 //送信サイズをリセット 00186 i_inst->_size_of_sent=0; 00187 return NyLPC_TBool_TRUE; 00188 Error: 00189 i_inst->_is_error=NyLPC_TUInt8_FALSE; 00190 return NyLPC_TBool_FALSE; 00191 00192 } 00193 00194 /** 00195 * ステータスラインと、標準メッセージヘッダを出力します。 00196 */ 00197 NyLPC_TBool NyLPC_cHttpHeaderWriter_writeResponseHeader(NyLPC_TcHttpHeaderWriter_t* i_inst,NyLPC_TUInt16 i_status) 00198 { 00199 NyLPC_TChar v[12]; 00200 const char* m=getStatusMessage(i_status); 00201 //エラー状態ならなにもしない。 00202 if(i_inst->_is_error){ 00203 return NyLPC_TBool_FALSE; 00204 } 00205 //検索に失敗したら500番に変更 00206 if(m==NULL){ 00207 i_status=500; 00208 m=getStatusMessage(500); 00209 } 00210 //ステータスラインの記述 00211 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,"HTTP/1.1 ",9)){ 00212 NyLPC_OnErrorGoto(Error); 00213 } 00214 NyLPC_itoa(i_status,v,10); 00215 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,v,-1)){ 00216 NyLPC_OnErrorGoto(Error); 00217 } 00218 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream," ",1)){ 00219 NyLPC_OnErrorGoto(Error); 00220 } 00221 if(!writeln(i_inst->_ref_stream,m,-1)){ 00222 NyLPC_OnErrorGoto(Error); 00223 } 00224 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,"Server: " NyLPC_cHttpdConfig_SERVER "\r\n",-1)){ 00225 NyLPC_OnErrorGoto(Error); 00226 } 00227 if(i_inst->_is_close){ 00228 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,"Connection: CLOSE\r\n",-1)){ 00229 NyLPC_OnErrorGoto(Error); 00230 } 00231 } 00232 //ヘッダの記述 00233 if(i_inst->_is_chunked){ 00234 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,"Transfer-Encoding: chunked\r\n",-1)){ 00235 NyLPC_OnErrorGoto(Error); 00236 } 00237 }else{ 00238 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,"Content-Length: ",-1)){ 00239 NyLPC_OnErrorGoto(Error); 00240 } 00241 NyLPC_uitoa (i_inst->_content_length,v,10); 00242 if(!writeln(i_inst->_ref_stream,v,-1)){ 00243 NyLPC_OnErrorGoto(Error); 00244 } 00245 } 00246 //送信サイズをリセット 00247 i_inst->_size_of_sent=0; 00248 return NyLPC_TBool_TRUE; 00249 Error: 00250 i_inst->_is_error=NyLPC_TUInt8_FALSE; 00251 return NyLPC_TBool_FALSE; 00252 } 00253 00254 /** 00255 * 独自定義のメッセージヘッダを記述します。 00256 */ 00257 NyLPC_TBool NyLPC_cHttpHeaderWriter_writeMessage(NyLPC_TcHttpHeaderWriter_t* i_inst,const NyLPC_TChar* i_name,const NyLPC_TChar* i_field) 00258 { 00259 //エラー状態ならなにもしない。 00260 if(i_inst->_is_error){ 00261 return NyLPC_TBool_FALSE; 00262 } 00263 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,i_name,-1)){ 00264 NyLPC_OnErrorGoto(Error); 00265 } 00266 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,": ",2)){ 00267 NyLPC_OnErrorGoto(Error); 00268 } 00269 if(!writeln(i_inst->_ref_stream,i_field,-1)){ 00270 NyLPC_OnErrorGoto(Error); 00271 } 00272 return NyLPC_TBool_TRUE; 00273 Error: 00274 i_inst->_is_error=NyLPC_TUInt8_FALSE; 00275 return NyLPC_TBool_FALSE; 00276 } 00277 00278 00279 NyLPC_TBool NyLPC_cHttpHeaderWriter_writeRawMessage(NyLPC_TcHttpHeaderWriter_t* i_inst,const NyLPC_TChar* i_additional_header) 00280 { 00281 //エラー状態ならなにもしない。 00282 if(i_inst->_is_error){ 00283 return NyLPC_TBool_FALSE; 00284 } 00285 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,i_additional_header,strlen(i_additional_header))){ 00286 NyLPC_OnErrorGoto(Error); 00287 } 00288 return NyLPC_TBool_TRUE; 00289 Error: 00290 i_inst->_is_error=NyLPC_TUInt8_FALSE; 00291 return NyLPC_TBool_FALSE; 00292 } 00293 00294 /** 00295 * Httpヘッダの書き込みを完了します。 00296 * 続けてbody転送が可能な場合は、必要に応じてエンコーディングモードを更新します。 00297 * @return 00298 * 現在のストリームのステータスを返します。 00299 */ 00300 NyLPC_TBool NyLPC_cHttpHeaderWriter_close(NyLPC_TcHttpHeaderWriter_t* i_inst) 00301 { 00302 //エラー状態ならなにもしない。 00303 if(i_inst->_is_error){ 00304 return NyLPC_TBool_FALSE; 00305 } 00306 if(NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,"\r\n",2)){ 00307 if( NyLPC_iHttpPtrStream_flush(i_inst->_ref_stream)){ 00308 return NyLPC_TBool_TRUE; 00309 } 00310 } 00311 return NyLPC_TBool_FALSE; 00312 } 00313 00314 00315
Generated on Tue Jul 12 2022 16:22:57 by
