1 /*********************************************************************************
\r
3 * --------------------------------------------------------------------------------
\r
5 * This file is part of MiMic
\r
6 * Copyright (C)2011 Ryo Iizuka
\r
8 * MiMic is free software: you can redistribute it and/or modify
\r
9 * it under the terms of the GNU Lesser General Public License as published
\r
10 * by the Free Software Foundation, either version 3 of the License, or
\r
11 * (at your option) any later version.
\r
13 * This program is distributed in the hope that it will be useful,
\r
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
16 * GNU General Public License for more details.
\r
18 * You should have received a copy of the GNU Lesser General Public License
\r
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
\r
21 * For further information please contact.
\r
23 * <airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
\r
25 *********************************************************************************/
\r
29 #include "NyLPC_cHttpBodyWriter.h"
\r
36 static NyLPC_TBool print(void* i_inst,const char* i_fmt,va_list args);
\r
39 void NyLPC_cHttpBodyWriter_initialize(NyLPC_TcHttpBodyWriter_t* i_inst,NyLPC_TcHttpStream_t* i_stream)
\r
41 i_inst->_ref_stream=i_stream;
\r
42 i_inst->_is_chunked=NyLPC_TUInt8_FALSE;
\r
43 i_inst->_is_error=NyLPC_TUInt8_FALSE;
\r
44 i_inst->_size_of_sent=0;
\r
45 i_inst->_content_length=0;
\r
46 NyLPC_iHttpPtrStream_setWriteEncoding(i_inst->_ref_stream,NyLPC_TiHttpPtrStream_ET_NONE);
\r
49 void NyLPC_cHttpBodyWriter_setChunked(NyLPC_TcHttpBodyWriter_t* i_inst)
\r
51 i_inst->_is_chunked=NyLPC_TUInt8_TRUE;
\r
52 NyLPC_iHttpPtrStream_setWriteEncoding(i_inst->_ref_stream,NyLPC_TiHttpPtrStream_ET_CHUNKED);
\r
54 void NyLPC_cHttpBodyWriter_setContentLength(NyLPC_TcHttpBodyWriter_t* i_inst,NyLPC_TUInt32 i_content_length)
\r
56 i_inst->_is_chunked=NyLPC_TUInt8_FALSE;
\r
57 i_inst->_content_length=i_content_length;
\r
58 NyLPC_iHttpPtrStream_setWriteEncoding(i_inst->_ref_stream,NyLPC_TiHttpPtrStream_ET_NONE);
\r
65 * 偽を返した場合は、コネクションを切断してください。
\r
67 NyLPC_TBool NyLPC_cHttpBodyWriter_write(NyLPC_TcHttpBodyWriter_t* i_inst,const void* i_buf,NyLPC_TUInt32 i_len)
\r
70 if(i_inst->_is_error){
\r
71 return NyLPC_TBool_FALSE;
\r
73 i_inst->_size_of_sent+=i_len;
\r
74 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,i_buf,i_len)){
\r
75 i_inst->_is_error=NyLPC_TUInt8_TRUE;
\r
76 return NyLPC_TBool_FALSE;
\r
78 return NyLPC_TBool_TRUE;
\r
81 * HttpBodyの書き込みを完了します。
\r
84 NyLPC_TBool NyLPC_cHttpBodyWriter_close(NyLPC_TcHttpBodyWriter_t* i_inst)
\r
87 if(i_inst->_is_error){
\r
88 return NyLPC_TBool_FALSE;
\r
90 //chunkedの場合、フッタを書き込む
\r
91 if(i_inst->_is_chunked){
\r
93 NyLPC_iHttpPtrStream_setWriteEncoding(i_inst->_ref_stream,NyLPC_TiHttpPtrStream_ET_NONE);
\r
95 if(!NyLPC_iHttpPtrStream_write(i_inst->_ref_stream,"0\r\n\r\n",5)){
\r
96 i_inst->_is_error=NyLPC_TUInt8_TRUE;
\r
97 return NyLPC_TBool_FALSE;
\r
100 //エラーでないときはストリームをフラッシュ
\r
101 NyLPC_iHttpPtrStream_flush(i_inst->_ref_stream);
\r
102 //クローズのステータスで状態を変える。
\r
103 return NyLPC_TBool_TRUE;
\r
107 * printfライクな書式出力を提供します。
\r
109 * 書式文字列です。%d,%x,%s,%c,%%をサポートします。
\r
111 NyLPC_TBool NyLPC_cHttpBodyWriter_format(NyLPC_TcHttpBodyWriter_t* i_inst,const NyLPC_TChar* i_fmt,...)
\r
116 if(i_inst->_is_error){
\r
117 return NyLPC_TBool_FALSE;
\r
120 ret=print(i_inst,i_fmt,a);
\r
125 NyLPC_TBool NyLPC_cHttpBodyWriter_formatV(NyLPC_TcHttpBodyWriter_t* i_inst,const NyLPC_TChar* i_fmt,va_list i_args)
\r
129 if(i_inst->_is_error){
\r
130 return NyLPC_TBool_FALSE;
\r
132 ret=print(i_inst,i_fmt,i_args);
\r
136 #define NUM_OF_WORK 16
\r
138 static NyLPC_TBool print(void* i_inst,const char* i_fmt,va_list args)
\r
140 const char* rp=i_fmt;
\r
142 char wk[NUM_OF_WORK];
\r
150 sp=va_arg(args,const char*);
\r
156 if(ol>=NUM_OF_WORK){
\r
157 NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,wk,NUM_OF_WORK);
\r
164 wk[ol]=(char)va_arg(args,int);
\r
171 NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,wk,ol);
\r
174 NyLPC_itoa((va_arg(args,int)),wk,10);
\r
176 NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,wk,strlen(wk));
\r
182 NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,wk,ol);
\r
184 ut=va_arg(args,NyLPC_TUInt32);
\r
188 wk[ol--]='0'+(ut%10);
\r
191 NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,(wk+ol+1),14-ol);
\r
198 NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,wk,ol);
\r
201 NyLPC_itoa((va_arg(args,int)),wk,16);
\r
203 NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,wk,strlen(wk));
\r
213 //オワタ(ループ抜けるためにrpはそのまま。)
\r
220 if(ol>=NUM_OF_WORK){
\r
221 NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,wk,NUM_OF_WORK);
\r
231 if(ol>=NUM_OF_WORK){
\r
232 NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,wk,NUM_OF_WORK);
\r
237 //どこかでエラーが起こってればFALSE返す。
\r
238 return NyLPC_cHttpBodyWriter_write((NyLPC_TcHttpBodyWriter_t*)i_inst,wk,ol);
\r
249 #include "NyLPC_cHttpHeaderWriter.h"
\r
252 "HTTP/0.9 200 OK\r\n"
\r
253 "HOST: 127.0.0.0.0.0.1\r\n"
\r
254 "CONTENt-LENGTH: 1285\r\n"
\r
255 "CONNECTION: CloSe\r\n"
\r
256 "ETAG: nyatla.jp\r\n"
\r
257 "ETAG: nyatla.jp\r\n"
\r
258 "Transfer-Encoding:chunked\r\n"
\r
261 "GET /nyanyanya!/nyoronnnnnnnnnnnn?m,fpeofjregnoegnr HTTP/1.1\r\n"
\r
262 "HOST: 127.0.0.0.0.0.1\r\n"
\r
263 "CONTENt-LENGTH: 1285\r\n"
\r
264 "CONNECTION: Keep\r\n"
\r
265 "ETAG: nyatla.jp\r\n"
\r
266 "ETAG: nyatla.jp\r\n"
\r
268 const char* DT="0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
\r
277 NyLPC_TcHttpStream_t st;
\r
278 NyLPC_TcHttpBasicHeaderParser_t hp;
\r
279 struct NyLPC_THttpBasicHeader reqheader;
\r
280 NyLPC_TcHttpHeaderWriter_t hw;
\r
281 NyLPC_TcHttpBodyWriter_t bw;
\r
282 NyLPC_TcTcpSocket_t ts;
\r
284 NyLPC_cTcpSocket_initialized(NULL,TP2,strlen(TP2));
\r
287 if(!NyLPC_cHttpStream_initialize(&st,&ts)){
\r
292 NyLPC_cHttpBasicHeaderParser_initialize(&hp);
\r
293 if(!NyLPC_cHttpShortRequestHeaderParser_parse(&hp,&st,&reqheader)){
\r
298 if(reqheader.type!=NyLPC_THttpHeaderType_REQUEST){
\r
302 if(reqheader.startline.req.method!=NyLPC_THttpMethodType_GET){
\r
307 NyLPC_cHttpHeaderWriter_initialize(&hw,&st,&reqheader);
\r
308 // NyLPC_cHttpResponseWriter_setClose(&hw);
\r
310 NyLPC_cHttpHeaderWriter_setContentLength(&hw,body_len);
\r
311 NyLPC_cHttpHeaderWriter_writeHeader(&hw,500);
\r
312 NyLPC_cHttpHeaderWriter_close(&hw);
\r
314 NyLPC_cHttpBodyWriter_initialize(&bw,&st);
\r
315 NyLPC_cHttpBodyWriter_setChunked(&bw);
\r
316 NyLPC_cHttpBodyWriter_write(&bw,"TEST",4);
\r
317 NyLPC_cHttpBodyWriter_printf(&bw,"TEST");
\r
318 NyLPC_cHttpBodyWriter_printf(&bw,"TEST[%s][%d][%c],%%,[%x]","abcde",123,'s',0xff0011);
\r
319 NyLPC_cHttpBodyWriter_close(&bw);
\r
320 NyLPC_cHttpHttpWriter_finalize(&hw);
\r
322 NyLPC_cHttpStream_finalize(&st);
\r