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
12 #include "../api/NyLPC_cHttpd.h"
\r
13 #include "../api/NyLPC_cModShortUrl.h"
\r
17 NyLPC_TcHttpd_t super;
\r
20 NyLPC_TcModShortUrl_t mod_surl;
\r
22 void handler(NyLPC_TcHttpdConnection_t* i_connection)
\r
24 NyLPC_THttpMethodType m;
\r
25 NyLPC_cModShortUrl_parse(&mod_surl,i_connection);
\r
26 m=NyLPC_cModShortUrl_getMethod(&mod_surl);
\r
27 if(m!=NyLPC_THttpMethodType_HEAD || m!=NyLPC_THttpMethodType_GET){
\r
28 NyLPC_cHttpdConnection_sendResponseHeader(i_connection,200,"text/html",NULL);
\r
30 if(m==NyLPC_THttpMethodType_GET){
\r
31 NyLPC_cHttpdConnection_sendResponseBodyF(i_connection,"<html><body>");
\r
32 NyLPC_cHttpdConnection_sendResponseBodyF(i_connection,"your request is %s",NyLPC_cModShortUrl_getPath(&mod_surl));
\r
34 NyLPC_cHttpdConnection_sendResponseBodyF(i_connection,"</body></html>");
\r
40 //uipサービス初期化。いろいろ利用可能に。
\r
41 NyLPC_cNet_initialize(&net);
\r
42 NyLPC_cHttpd_initialize(&httpd.super,80);
\r
43 httpd.super.function._handler=handler;
\r
44 NyLPC_cModShortUrl_initialize(&mod_surl);
\r
50 NyLPC_TcNetConfig_t c2;
\r
51 NyLPC_cNetConfig_initialize(&c2);
\r
52 NyLPC_cNet_start(&net,&c2);
\r
53 NyLPC_cHttpd_loop(&httpd.super);
\r
62 const struct NyLPC_TEthAddr ethaddr=NyLPC_TEthAddr_pack(0x02,0x01,0x02,0x03,0x04,0x05);
\r
63 const struct NyLPC_TIPv4Addr ipaddr=NyLPC_TIPv4Addr_pack(192,168,0,39);
\r
64 const struct NyLPC_TIPv4Addr netmask=NyLPC_TIPv4Addr_pack(255,255,255,0);
\r
65 const struct NyLPC_TIPv4Addr gateway=NyLPC_TIPv4Addr_pack(192,168,0,254);
\r
68 #define SIZE_OF_RX 256
\r
71 NyLPC_TcThread_t th;
\r
72 NyLPC_TcTcpSocket_t socket;
\r
73 char rbuf[SIZE_OF_RX];
\r
77 extern struct NyLPC_TRomFileData file_cat_jpg;
\r
78 extern struct NyLPC_TRomFileData file_index_html;
\r
79 NyLPC_TcRomFileSet_t rfs;
\r
80 const struct NyLPC_TRomFileData* rfsd[]={
\r
86 static NyLPC_TUInt16 parseReqHeader(NyLPC_TcHttpStream_t* i_st,struct NyLPC_THttpShortRequestHeader* o_reqh);
\r
87 static NyLPC_TBool writeError(NyLPC_TcHttpStream_t* i_st,const struct NyLPC_THttpBasicHeader* i_rqh,NyLPC_TUInt16 i_status);
\r
88 static NyLPC_TBool writeFile(NyLPC_TcHttpStream_t* i_st,const struct NyLPC_THttpBasicHeader* i_rqh,const struct NyLPC_TRomFileData* i_file);
\r
89 static NyLPC_TBool writeJson(NyLPC_TcHttpStream_t* i_st,const struct NyLPC_THttpBasicHeader* i_rqh);
\r
97 //uipサービス初期化。いろいろ利用可能に。
\r
98 NyLPC_cUipService_initialize();
\r
99 // for(i=0;i<NUM_OF_TH;i++){
\r
100 // NyLPC_cThread_initialize(&(proc[i].th),200,NyLPC_TcThread_PRIORITY_IDLE);
\r
101 // NyLPC_cTcpSocket_initialize(&(proc[i].socket),proc[i].rbuf,SIZE_OF_RX);
\r
103 // //ROMのファイルシステムを初期化
\r
104 // NyLPC_cRomFileSet_initialize(&rfs,rfsd,2);
\r
109 static int num_of_reqest=0;
\r
110 static int num_of_error=0;
\r
111 static int num_of_connect=0;
\r
112 static int num_of_tx=0;
\r
115 static int server(void* p)
\r
117 struct TProc* proc=(struct TProc*)p;
\r
119 const struct NyLPC_TRomFileData* rf;
\r
120 NyLPC_TcHttpStream_t st;
\r
121 struct NyLPC_THttpShortRequestHeader reqheader;
\r
122 if(!NyLPC_cTcpSocket_accept(&(proc->socket),3000)){
\r
128 if(NyLPC_cHttpStream_initialize(&st,&(proc->socket))){
\r
130 ret=parseReqHeader(&st,&reqheader);
\r
132 //コネクションが増えすぎたら持続性接続を停止するために上書き。
\r
133 if(num_of_connect>5){
\r
134 reqheader.super.connection=NyLPC_THttpMessgeHeader_Connection_CLOSE;
\r
137 //エラーならエラーレスポンスを生成。持続性接続しない。
\r
138 writeError(&st,&(reqheader.super),ret);
\r
143 if(strncmp("/rf.api?",reqheader.url,8)==0){
\r
145 rf=NyLPC_cRomFileSet_getFilaData(&rfs,reqheader.url+8);
\r
148 if(!writeError(&st,&(reqheader.super),404)){
\r
152 if(!writeFile(&st,&(reqheader.super),rf)){
\r
157 }else if(strncmp("/status.json",reqheader.url,8)==0){
\r
158 if(!writeJson(&st,&(reqheader.super))){
\r
163 if(!writeFile(&st,&(reqheader.super),NyLPC_cRomFileSet_getFilaData(&rfs,"index.html"))){
\r
170 NyLPC_cHttpStream_finalize(&st);
\r
173 NyLPC_cTcpSocket_close(&(proc->socket),5000);
\r
181 NyLPC_TcIPv4Config_t config;
\r
182 NyLPC_TcTcpListener_t listener;
\r
186 NyLPC_cIPv4Config_initialzeForEthernet(&config,ðaddr,1480);
\r
187 NyLPC_cIPv4Config_setDefaultRoute(&config,&gateway);
\r
188 NyLPC_cIPv4Config_setIp(&config,&ipaddr,&netmask);
\r
191 // NyLPC_cTcpListener_initialize(&listener,80);
\r
192 NyLPC_cUipService_start(&config);
\r
195 for(i=0;i<NUM_OF_TH;i++){
\r
196 if(NyLPC_cThread_isTerminated(&(proc[i].th))){
\r
198 if(!NyLPC_cTcpListener_listen(&listener,&(proc[i].socket),5000)){
\r
202 NyLPC_cThread_start(&(proc[i].th),server,&(proc[i]));
\r
214 static NyLPC_TUInt16 parseReqHeader(NyLPC_TcHttpStream_t* i_st,struct NyLPC_THttpShortRequestHeader* o_reqh)
\r
216 NyLPC_TUInt16 ret=200;
\r
217 NyLPC_TcHttpShortRequestHeaderParser_t hp;
\r
218 NyLPC_cHttpShortRequestHeaderParser_initialize(&hp);
\r
221 if(!NyLPC_cHttpShortRequestHeaderParser_parse(&hp,i_st,o_reqh)){
\r
222 ret=NyLPC_cHttpBasicHeaderParser_getStatusCode(&hp.super);
\r
225 if(o_reqh->super.type!=NyLPC_THttpHeaderType_REQUEST){
\r
229 if(o_reqh->super.startline.req.method!=NyLPC_THttpMethodType_GET){
\r
232 NyLPC_cHttpBasicHeaderParser_finalize(&hp);
\r
237 * 戻り値はpersistentConnectionが有効かどうか。
\r
239 static NyLPC_TBool writeError(NyLPC_TcHttpStream_t* i_st,const struct NyLPC_THttpBasicHeader* i_rqh,NyLPC_TUInt16 i_status)
\r
241 static const char* HTML_FORMAT="<html><h1>STATUS %d</h1><hr/>"NyLPC_cHttpdConfig_SERVER"</html>";
\r
242 NyLPC_TcHttpHeaderWriter_t hw;
\r
243 NyLPC_TcHttpBodyWriter_t bw;
\r
245 if(!NyLPC_cHttpHeaderWriter_initialize(&hw,i_st,i_rqh)){
\r
246 return NyLPC_TBool_FALSE;
\r
249 if(!NyLPC_THttpBasicHeader_isPersistent(i_rqh)){
\r
250 NyLPC_cHttpHeaderWriter_setClose(&hw);
\r
252 //@bug HTTP/1.1未満のクライアントを考慮していない。
\r
253 NyLPC_cHttpHeaderWriter_setChunked(&hw);
\r
255 NyLPC_cHttpHeaderWriter_writeHeader(&hw,i_status);
\r
257 NyLPC_cHttpHeaderWriter_writeMessage(&hw,"Content-type","text/html");
\r
259 //ヘッダ書込み終わり。(最後だけチェック)
\r
260 if(!NyLPC_cHttpHeaderWriter_close(&hw)){
\r
261 NyLPC_cHttpHeaderWriter_finalize(&hw);
\r
262 return NyLPC_TBool_FALSE;
\r
264 NyLPC_cHttpHeaderWriter_finalize(&hw);
\r
267 NyLPC_cHttpBodyWriter_initialize(&bw,i_st);
\r
269 NyLPC_cHttpBodyWriter_setChunked(&bw);
\r
270 NyLPC_cHttpBodyWriter_format(&bw,HTML_FORMAT,(NyLPC_TInt32)i_status);
\r
272 if(!NyLPC_cHttpBodyWriter_close(&bw)){
\r
273 NyLPC_cHttpBodyWriter_finalize(&hw);
\r
274 return NyLPC_TBool_FALSE;
\r
276 NyLPC_cHttpBodyWriter_finalize(&hw);
\r
277 return NyLPC_THttpBasicHeader_isPersistent(i_rqh);
\r
282 * 戻り値はpersistentConnectionが有効かどうか。
\r
284 static NyLPC_TBool writeJson(NyLPC_TcHttpStream_t* i_st,const struct NyLPC_THttpBasicHeader* i_rqh)
\r
286 static const char* JSON_FORMAT="{nr:%d,ne:%d,ac:%d,er:\"%d/%d/%d\",tx:%d}";
\r
287 NyLPC_TcHttpHeaderWriter_t hw;
\r
288 NyLPC_TcHttpBodyWriter_t bw;
\r
290 if(!NyLPC_cHttpHeaderWriter_initialize(&hw,i_st,i_rqh)){
\r
291 return NyLPC_TBool_FALSE;
\r
294 if(!NyLPC_THttpBasicHeader_isPersistent(i_rqh)){
\r
295 NyLPC_cHttpHeaderWriter_setClose(&hw);
\r
297 //@bug HTTP/1.1未満のクライアントを考慮していない。
\r
298 NyLPC_cHttpHeaderWriter_setChunked(&hw);
\r
300 NyLPC_cHttpHeaderWriter_writeHeader(&hw,200);
\r
302 NyLPC_cHttpHeaderWriter_writeMessage(&hw,"Content-type","application/json");
\r
303 NyLPC_cHttpHeaderWriter_writeMessage(&hw,"Access-Control-Allow-Origin","*");
\r
305 //ヘッダ書込み終わり。(最後だけチェック)
\r
306 if(!NyLPC_cHttpHeaderWriter_close(&hw)){
\r
307 NyLPC_cHttpHeaderWriter_finalize(&hw);
\r
308 return NyLPC_TBool_FALSE;
\r
310 NyLPC_cHttpHeaderWriter_finalize(&hw);
\r
313 NyLPC_cHttpBodyWriter_initialize(&bw,i_st);
\r
315 NyLPC_cHttpBodyWriter_setChunked(&bw);
\r
316 NyLPC_cHttpBodyWriter_format(&bw,JSON_FORMAT,
\r
317 (NyLPC_TInt32)num_of_reqest,(NyLPC_TInt32)num_of_error,(NyLPC_TInt32)num_of_connect,
\r
318 NyLPC_assert_counter,NyLPC_abort_counter,NyLPC_debug_counter,dbg_getNumofUsedTx());
\r
320 if(!NyLPC_cHttpBodyWriter_close(&bw)){
\r
321 NyLPC_cHttpBodyWriter_finalize(&hw);
\r
322 return NyLPC_TBool_FALSE;
\r
324 NyLPC_cHttpBodyWriter_finalize(&hw);
\r
325 return NyLPC_THttpBasicHeader_isPersistent(i_rqh);
\r
328 * ROMファイルのレスポンスライタ。
\r
329 * 戻り値はpersistentConnectionが有効かどうか。
\r
331 static NyLPC_TBool writeFile(NyLPC_TcHttpStream_t* i_st,const struct NyLPC_THttpBasicHeader* i_rqh,const struct NyLPC_TRomFileData* i_file)
\r
333 NyLPC_TcHttpHeaderWriter_t hw;
\r
334 NyLPC_TcHttpBodyWriter_t bw;
\r
336 if(!NyLPC_cHttpHeaderWriter_initialize(&hw,i_st,i_rqh)){
\r
337 return NyLPC_TBool_FALSE;
\r
340 if(!NyLPC_THttpBasicHeader_isPersistent(i_rqh)){
\r
341 NyLPC_cHttpHeaderWriter_setClose(&hw);
\r
343 NyLPC_cHttpHeaderWriter_setContentLength(&hw,i_file->size);
\r
345 NyLPC_cHttpHeaderWriter_writeHeader(&hw,200);
\r
347 NyLPC_cHttpHeaderWriter_writeMessage(&hw,"Content-type",i_file->content_type);
\r
349 //ヘッダ書込み終わり。(最後だけチェック)
\r
350 if(!NyLPC_cHttpHeaderWriter_close(&hw)){
\r
351 NyLPC_cHttpHeaderWriter_finalize(&hw);
\r
352 return NyLPC_TBool_FALSE;
\r
354 NyLPC_cHttpHeaderWriter_finalize(&hw);
\r
357 NyLPC_cHttpBodyWriter_initialize(&bw,i_st);
\r
358 NyLPC_cHttpBodyWriter_write(&bw,i_file->data,i_file->size);
\r
360 if(!NyLPC_cHttpBodyWriter_close(&bw)){
\r
361 NyLPC_cHttpBodyWriter_finalize(&hw);
\r
362 return NyLPC_TBool_FALSE;
\r
364 NyLPC_cHttpBodyWriter_finalize(&hw);
\r
365 return NyLPC_THttpBasicHeader_isPersistent(i_rqh);
\r