3 * ROMにある定義済みファイルの入出力と、クロスドメインRESTが確認できます。
\r
5 #include "boot/sketch.h"
\r
6 #include "NyLPC_uipService.h"
\r
7 #include "NyLPC_httpService.h"
\r
8 #include "NyLPC_utils.h"
\r
11 #include "../api/NyLPC_cNet.h"
\r
14 NyLPC_TcNet_t httpd;
\r
17 NyLPC_cNet_initialize(&net);
\r
21 NyLPC_TcNetConfig_t config;
\r
22 NyLPC_cNetConfig_initialize(&config);
\r
23 NyLPC_cNet_start(&net,&config);
\r
24 NyLPC_cHttpd_loop(&httpd);
\r
32 const struct NyLPC_TEthAddr ethaddr=NyLPC_TEthAddr_pack(0x02,0x01,0x02,0x03,0x04,0x05);
\r
33 const struct NyLPC_TIPv4Addr ipaddr=NyLPC_TIPv4Addr_pack(192,168,128,201);
\r
34 const struct NyLPC_TIPv4Addr netmask=NyLPC_TIPv4Addr_pack(255,255,255,0);
\r
35 const struct NyLPC_TIPv4Addr gateway=NyLPC_TIPv4Addr_pack(192,168,128,254);
\r
38 #define SIZE_OF_RX 256
\r
41 NyLPC_TcThread_t th;
\r
42 NyLPC_TcTcpSocket_t socket;
\r
43 char rbuf[SIZE_OF_RX];
\r
47 extern struct NyLPC_TRomFileData file_cat_jpg;
\r
48 extern struct NyLPC_TRomFileData file_index_html;
\r
49 NyLPC_TcRomFileSet_t rfs;
\r
50 const struct NyLPC_TRomFileData* rfsd[]={
\r
56 static NyLPC_TUInt16 parseReqHeader(NyLPC_TcHttpStream_t* i_st,struct NyLPC_THttpShortRequestHeader* o_reqh);
\r
57 static NyLPC_TBool writeError(NyLPC_TcHttpStream_t* i_st,const struct NyLPC_THttpBasicHeader* i_rqh,NyLPC_TUInt16 i_status);
\r
58 static NyLPC_TBool writeFile(NyLPC_TcHttpStream_t* i_st,const struct NyLPC_THttpBasicHeader* i_rqh,const struct NyLPC_TRomFileData* i_file);
\r
59 static NyLPC_TBool writeJson(NyLPC_TcHttpStream_t* i_st,const struct NyLPC_THttpBasicHeader* i_rqh);
\r
67 //uipサービス初期化。いろいろ利用可能に。
\r
68 NyLPC_cUipService_initialize();
\r
69 for(i=0;i<NUM_OF_TH;i++){
\r
70 NyLPC_cThread_initialize(&(proc[i].th),200,NyLPC_TcThread_PRIORITY_IDLE);
\r
71 NyLPC_cTcpSocket_initialize(&(proc[i].socket),proc[i].rbuf,SIZE_OF_RX);
\r
74 NyLPC_cRomFileSet_initialize(&rfs,rfsd,2);
\r
79 static int num_of_reqest=0;
\r
80 static int num_of_error=0;
\r
81 static int num_of_connect=0;
\r
82 static int num_of_tx=0;
\r
85 static int server(void* p)
\r
87 struct TProc* proc=(struct TProc*)p;
\r
89 const struct NyLPC_TRomFileData* rf;
\r
90 NyLPC_TcHttpStream_t st;
\r
91 struct NyLPC_THttpShortRequestHeader reqheader;
\r
92 if(!NyLPC_cTcpSocket_accept(&(proc->socket),3000)){
\r
98 if(NyLPC_cHttpStream_initialize(&st,&(proc->socket))){
\r
100 ret=parseReqHeader(&st,&reqheader);
\r
102 //コネクションが増えすぎたら持続性接続を停止するために上書き。
\r
103 if(num_of_connect>5){
\r
104 reqheader.super.connection=NyLPC_THttpMessgeHeader_Connection_CLOSE;
\r
107 //エラーならエラーレスポンスを生成。持続性接続しない。
\r
108 writeError(&st,&(reqheader.super),ret);
\r
113 if(strncmp("/rf.api?",reqheader.url,8)==0){
\r
115 rf=NyLPC_cRomFileSet_getFilaData(&rfs,reqheader.url+8);
\r
118 if(!writeError(&st,&(reqheader.super),404)){
\r
122 if(!writeFile(&st,&(reqheader.super),rf)){
\r
127 }else if(strncmp("/status.json",reqheader.url,8)==0){
\r
128 if(!writeJson(&st,&(reqheader.super))){
\r
133 if(!writeFile(&st,&(reqheader.super),NyLPC_cRomFileSet_getFilaData(&rfs,"index.html"))){
\r
140 NyLPC_cHttpStream_finalize(&st);
\r
143 NyLPC_cTcpSocket_close(&(proc->socket),5000);
\r
151 NyLPC_TcIPv4Config_t config;
\r
152 NyLPC_TcTcpListener_t listener;
\r
156 NyLPC_cIPv4Config_initialzeForEthernet(&config,ðaddr,1480);
\r
157 NyLPC_cIPv4Config_setDefaultRoute(&config,&gateway);
\r
158 NyLPC_cIPv4Config_setIp(&config,&ipaddr,&netmask);
\r
161 NyLPC_cTcpListener_initialize(&listener,80);
\r
162 NyLPC_cUipService_start(&config);
\r
165 for(i=0;i<NUM_OF_TH;i++){
\r
166 if(NyLPC_cThread_isTerminated(&(proc[i].th))){
\r
168 if(!NyLPC_cTcpListener_listen(&listener,&(proc[i].socket),5000)){
\r
172 NyLPC_cThread_start(&(proc[i].th),server,&(proc[i]));
\r
184 static NyLPC_TUInt16 parseReqHeader(NyLPC_TcHttpStream_t* i_st,struct NyLPC_THttpShortRequestHeader* o_reqh)
\r
186 NyLPC_TUInt16 ret=200;
\r
187 NyLPC_TcHttpShortRequestHeaderParser_t hp;
\r
188 NyLPC_cHttpShortRequestHeaderParser_initialize(&hp);
\r
191 if(!NyLPC_cHttpShortRequestHeaderParser_parse(&hp,i_st,o_reqh)){
\r
192 ret=NyLPC_cHttpBasicHeaderParser_getStatusCode(&hp.super);
\r
195 if(o_reqh->super.type!=NyLPC_THttpHeaderType_REQUEST){
\r
199 if(o_reqh->super.startline.req.method!=NyLPC_THttpMethodType_GET){
\r
202 NyLPC_cHttpBasicHeaderParser_finalize(&hp);
\r
207 * 戻り値はpersistentConnectionが有効かどうか。
\r
209 static NyLPC_TBool writeError(NyLPC_TcHttpStream_t* i_st,const struct NyLPC_THttpBasicHeader* i_rqh,NyLPC_TUInt16 i_status)
\r
211 static const char* HTML_FORMAT="<html><h1>STATUS %d</h1><hr/>"NyLPC_cHttpdConfig_SERVER"</html>";
\r
212 NyLPC_TcHttpHeaderWriter_t hw;
\r
213 NyLPC_TcHttpBodyWriter_t bw;
\r
215 if(!NyLPC_cHttpHeaderWriter_initialize(&hw,i_st,i_rqh)){
\r
216 return NyLPC_TBool_FALSE;
\r
219 if(!NyLPC_THttpBasicHeader_isPersistent(i_rqh)){
\r
220 NyLPC_cHttpHeaderWriter_setClose(&hw);
\r
222 //@bug HTTP/1.1未満のクライアントを考慮していない。
\r
223 NyLPC_cHttpHeaderWriter_setChunked(&hw);
\r
225 NyLPC_cHttpHeaderWriter_writeHeader(&hw,i_status);
\r
227 NyLPC_cHttpHeaderWriter_writeMessage(&hw,"Content-type","text/html");
\r
229 //ヘッダ書込み終わり。(最後だけチェック)
\r
230 if(!NyLPC_cHttpHeaderWriter_close(&hw)){
\r
231 NyLPC_cHttpHeaderWriter_finalize(&hw);
\r
232 return NyLPC_TBool_FALSE;
\r
234 NyLPC_cHttpHeaderWriter_finalize(&hw);
\r
237 NyLPC_cHttpBodyWriter_initialize(&bw,i_st);
\r
239 NyLPC_cHttpBodyWriter_setChunked(&bw);
\r
240 NyLPC_cHttpBodyWriter_format(&bw,HTML_FORMAT,(NyLPC_TInt32)i_status);
\r
242 if(!NyLPC_cHttpBodyWriter_close(&bw)){
\r
243 NyLPC_cHttpBodyWriter_finalize(&hw);
\r
244 return NyLPC_TBool_FALSE;
\r
246 NyLPC_cHttpBodyWriter_finalize(&hw);
\r
247 return NyLPC_THttpBasicHeader_isPersistent(i_rqh);
\r
252 * 戻り値はpersistentConnectionが有効かどうか。
\r
254 static NyLPC_TBool writeJson(NyLPC_TcHttpStream_t* i_st,const struct NyLPC_THttpBasicHeader* i_rqh)
\r
256 static const char* JSON_FORMAT="{nr:%d,ne:%d,ac:%d,er:\"%d/%d/%d\",tx:%d}";
\r
257 NyLPC_TcHttpHeaderWriter_t hw;
\r
258 NyLPC_TcHttpBodyWriter_t bw;
\r
260 if(!NyLPC_cHttpHeaderWriter_initialize(&hw,i_st,i_rqh)){
\r
261 return NyLPC_TBool_FALSE;
\r
264 if(!NyLPC_THttpBasicHeader_isPersistent(i_rqh)){
\r
265 NyLPC_cHttpHeaderWriter_setClose(&hw);
\r
267 //@bug HTTP/1.1未満のクライアントを考慮していない。
\r
268 NyLPC_cHttpHeaderWriter_setChunked(&hw);
\r
270 NyLPC_cHttpHeaderWriter_writeHeader(&hw,200);
\r
272 NyLPC_cHttpHeaderWriter_writeMessage(&hw,"Content-type","application/json");
\r
273 NyLPC_cHttpHeaderWriter_writeMessage(&hw,"Access-Control-Allow-Origin","*");
\r
275 //ヘッダ書込み終わり。(最後だけチェック)
\r
276 if(!NyLPC_cHttpHeaderWriter_close(&hw)){
\r
277 NyLPC_cHttpHeaderWriter_finalize(&hw);
\r
278 return NyLPC_TBool_FALSE;
\r
280 NyLPC_cHttpHeaderWriter_finalize(&hw);
\r
283 NyLPC_cHttpBodyWriter_initialize(&bw,i_st);
\r
285 NyLPC_cHttpBodyWriter_setChunked(&bw);
\r
286 NyLPC_cHttpBodyWriter_format(&bw,JSON_FORMAT,
\r
287 (NyLPC_TInt32)num_of_reqest,(NyLPC_TInt32)num_of_error,(NyLPC_TInt32)num_of_connect,
\r
288 NyLPC_assert_counter,NyLPC_abort_counter,NyLPC_debug_counter,dbg_getNumofUsedTx());
\r
290 if(!NyLPC_cHttpBodyWriter_close(&bw)){
\r
291 NyLPC_cHttpBodyWriter_finalize(&hw);
\r
292 return NyLPC_TBool_FALSE;
\r
294 NyLPC_cHttpBodyWriter_finalize(&hw);
\r
295 return NyLPC_THttpBasicHeader_isPersistent(i_rqh);
\r
298 * ROMファイルのレスポンスライタ。
\r
299 * 戻り値はpersistentConnectionが有効かどうか。
\r
301 static NyLPC_TBool writeFile(NyLPC_TcHttpStream_t* i_st,const struct NyLPC_THttpBasicHeader* i_rqh,const struct NyLPC_TRomFileData* i_file)
\r
303 NyLPC_TcHttpHeaderWriter_t hw;
\r
304 NyLPC_TcHttpBodyWriter_t bw;
\r
306 if(!NyLPC_cHttpHeaderWriter_initialize(&hw,i_st,i_rqh)){
\r
307 return NyLPC_TBool_FALSE;
\r
310 if(!NyLPC_THttpBasicHeader_isPersistent(i_rqh)){
\r
311 NyLPC_cHttpHeaderWriter_setClose(&hw);
\r
313 NyLPC_cHttpHeaderWriter_setContentLength(&hw,i_file->size);
\r
315 NyLPC_cHttpHeaderWriter_writeHeader(&hw,200);
\r
317 NyLPC_cHttpHeaderWriter_writeMessage(&hw,"Content-type",i_file->content_type);
\r
319 //ヘッダ書込み終わり。(最後だけチェック)
\r
320 if(!NyLPC_cHttpHeaderWriter_close(&hw)){
\r
321 NyLPC_cHttpHeaderWriter_finalize(&hw);
\r
322 return NyLPC_TBool_FALSE;
\r
324 NyLPC_cHttpHeaderWriter_finalize(&hw);
\r
327 NyLPC_cHttpBodyWriter_initialize(&bw,i_st);
\r
328 NyLPC_cHttpBodyWriter_write(&bw,i_file->data,i_file->size);
\r
330 if(!NyLPC_cHttpBodyWriter_close(&bw)){
\r
331 NyLPC_cHttpBodyWriter_finalize(&hw);
\r
332 return NyLPC_TBool_FALSE;
\r
334 NyLPC_cHttpBodyWriter_finalize(&hw);
\r
335 return NyLPC_THttpBasicHeader_isPersistent(i_rqh);
\r