WIZlib Library API  ver 1.0
WIZlib Library API User Menual
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
httputil.c
Go to the documentation of this file.
1 
12 #include "protocol/HTTP/httputil.h"
13 #include "webpage.h"
14 #include "romfile.h"
15 
16 #define DEFAULT_HTTP_PORT 80
17 extern char rx_buf[MAX_URI_SIZE];
18 extern char tx_buf[MAX_URI_SIZE];
19 extern uint8 BUFPUB[1024];
20 
21 uint8 *homepage_default = "/ipconfig.htm";
22 
23 
24 void mid(char* src, char* s1, char* s2, char* sub)
25 {
26  char* sub1;
27  char* sub2;
28  uint16 n;
29 
30  sub1=strstr((char*)src,(char*)s1);
31  sub1+=strlen((char*)s1);
32  sub2=strstr((char*)sub1,(char*)s2);
33 
34  n=sub2-sub1;
35  strncpy((char*)sub,(char*)sub1,n);
36  sub[n]='\0';
37 }
38 
39 //processing http protocol , and excuting the followed fuction.
40 void WebServer(uint8 s)
41 {
42  int ret;
43  uint32 header_len=0, content_len=0, received_len=0;
44  char sub[10];
45 
46  /* http service start */
47  ret = TCPRecv(s, (int8*)rx_buf, MAX_URI_SIZE);
48 
49  if(ret > 0){ // If Received..
50  *(((uint8*)rx_buf)+ret) = '\0';
51 
52  if(strstr(rx_buf, "Content-Length: ")){
53  mid((char*)rx_buf, "Content-Length: ", "\r\n", sub);
54  content_len=atoi(sub);
55  header_len = (uint32)(strstr(rx_buf, "\r\n\r\n") - rx_buf + 4);
56 
57  received_len = ret;
58  while(received_len!=(content_len+header_len))
59  {
60  ret = TCPRecv(s, (int8*)rx_buf+received_len, MAX_URI_SIZE);
61  received_len+=ret;
62  }
63 
64  *(((uint8*)rx_buf)+received_len) = '\0';
65  }
66 
67  HTTPProcessor(s, (char*)rx_buf); // request is processed
68  memset(rx_buf,0x00,MAX_URI_SIZE);
69 
70  IINCHIP_WRITE(Sn_CR(s),Sn_CR_DISCON);
71  while( IINCHIP_READ(Sn_CR(s)) ) ;
72 
73  //TCPClose(s);
74 
75  } else if(ret == SOCKERR_NOT_TCP){ // Not TCP Socket, It's UDP Socket
76  DBG("UDP Socket Close");
77  UDPClose(s);
78 
79  } else if(ret == SOCKERR_CLOSED){ // Socket Closed
80  LOGA("HTTP Server Started - ch(%d)",(uint16)s);
81  TCPServerOpen(s, DEFAULT_HTTP_PORT);
82  }
83 
84  if(GetTCPSocketStatus(s) == SOCKERR_CLOSE_WAIT){// Close waiting
85  TCPClose(s);
86  }
87 }
88 
93 struct CGI_CALLBACK cgi_callback[MAX_CGI_CALLBACK];
94 void cgi_callback_add(char *tokken, cgi_func get_func, cgi_func set_func)
95 {
96  static uint16 total=0;
97  int len;
98 
99  if(tokken == NULL) {
100  ERR("description string is NULL");
101  return;
102 
103  } else if(total >= MAX_CGI_CALLBACK) {
104  ERR("not enough space");
105  return;
106  }
107 
108  len = strlen(tokken);
109  cgi_callback[total].tokken = malloc(len+1);
110  strcpy(cgi_callback[total].tokken, tokken);
111  cgi_callback[total].get_func = get_func;
112  cgi_callback[total].set_func = set_func;
113  total++;
114 }
115 
116 int32 HTTPSend(uint8 s, char *src, char *dest, uint16 len, uint8 mode)
117 {
118  int32 ret=0;
119  char *oldtmp=0, *newtmp=0;
120  char sub[32];
121  uint16 i, mlen=0;
122  char *tmp = (char*)BUFPUB;
123 
124  oldtmp=src;
125  newtmp=oldtmp;
126  while((newtmp = strstr(oldtmp, "<="))){
127  if(mode == 0)
128  ret += TCPSend(s, (int8*)oldtmp, (uint16)(newtmp-oldtmp));
129  else if(mode == 1)
130  {
131  strncat(dest, oldtmp, (uint16)(newtmp-oldtmp));
132  ret += (uint16)(newtmp-oldtmp);
133  }
134  else if(mode == 2)
135  ret += (uint16)(newtmp-oldtmp);
136 
137  mid(newtmp, "<=", ">", sub);// mid 함수의 리턴값에 따라 "<=" 까지만 읽었고, ">" 까지 읽지 않았는지 판단한 후 다음 파일을 읽고나서 처리 하도록 구현해야 함.
138  for(i=0; i<MAX_CGI_CALLBACK; i++){
139  if(!strcmp(sub, cgi_callback[i].tokken)){
140  if(cgi_callback[i].get_func == NULL){
141  i = MAX_CGI_CALLBACK;
142  break;
143  }
144 
145  cgi_callback[i].get_func(tmp, &mlen);
146 
147  if(mode == 0)
148  ret += TCPSend(s, (int8*)tmp, mlen);
149  else if(mode == 1)
150  {
151  strncat(dest, tmp, mlen);
152  ret += mlen;
153  }
154  else if(mode == 2)
155  ret += mlen;
156  break;
157  }
158  }
159  if(i==MAX_CGI_CALLBACK){
160  mlen = sprintf(tmp, "<=%s>", sub);
161 
162  if(mode == 0)
163  ret += TCPSend(s, (int8*)tmp, mlen);
164  else if(mode == 1)
165  {
166  strncat(dest, tmp, mlen);
167  ret += mlen;
168  }
169  else if(mode == 2)
170  ret += mlen;
171  }
172  oldtmp = newtmp + strlen(sub)+3;
173  }
174 
175  if(mode == 0)
176  ret += TCPSend(s, (int8*)oldtmp, (len-(uint16)(oldtmp-src)));
177  else if(mode == 1)
178  {
179  strncat(dest, oldtmp, (len-(uint16)(oldtmp-src)));
180  ret += (len-(uint16)(oldtmp-src));
181  }
182  else if(mode == 2)
183  ret += (len-(uint16)(oldtmp-src));
184 
185  return ret;
186 }
187 
188 void FILESend(uint8 s, st_http_request *http_request, char* buf)
189 {
190  uint32 file_len=0, file_len_tmp=0;
191  uint32 send_len=0, content_len=0;
192  uint32 content = 0;
193  char* name=(char*)http_request->URI;
194  if(strcmp(name,"/"))
195  name++;
196 
197  /* Search the specified file in stored binaray html image */
198  if(!search_file_rom((unsigned char *)name, &content, &file_len))
199  {
200  memcpy(buf, ERROR_HTML_PAGE, sizeof(ERROR_HTML_PAGE));
201  TCPSend(s, (int8*)buf, strlen((char const*)buf));
202  }
203  else
204  {
205  file_len_tmp = file_len;
206  send_len=0;
207  while(file_len_tmp)
208  {
209  if(file_len_tmp>1024)
210  {
211  read_from_flashbuf(content+send_len, (uint8*)buf, 1024);
212 
213  // Replace html's system environment value to real value and check size
214  content_len += HTTPSend(NULL, buf, NULL, 1024, 2);
215 
216  send_len+=1024;
217  file_len_tmp-=1024;
218  }
219  else
220  {
221  read_from_flashbuf(content+send_len, (uint8*)buf, file_len_tmp);
222  buf[file_len_tmp] = '\0';
223 
224  // Replace html's system environment value to real value and check size
225  content_len += HTTPSend(NULL, buf, NULL, file_len_tmp, 2);
226 
227  send_len+=file_len_tmp;
228  file_len_tmp-=file_len_tmp;
229  }
230  }
231  make_http_response_head((unsigned char*)buf, http_request->TYPE, content_len);
232  TCPSend(s, (int8*)buf, strlen((char const*)buf));
233 
234  send_len=0;
235  while(file_len)
236  {
237  if(file_len>1024)
238  {
239  read_from_flashbuf(content+send_len, (uint8*)buf, 1024);
240 
241  // Replace html's system environment value to real value and send
242  if(HTTPSend(s, buf, NULL, 1024, 0)<0)
243  {
244  return;
245  }
246 
247  send_len+=1024;
248  file_len-=1024;
249  }
250  else
251  {
252  read_from_flashbuf(content+send_len, (uint8*)buf, file_len);
253  buf[file_len] = '\0';
254 
255  // Replace html's system environment value to real value and send
256  HTTPSend(s, buf, NULL, (uint16)file_len, 0);
257 
258  send_len+=file_len;
259  file_len-=file_len;
260  }
261  }
262  }
263 }
264 
265 void HTTPProcessor(uint8 s, char * buf)
266 {
267  uint8* http_response;
268  st_http_request *http_request;
269 
270  http_response = (uint8*)rx_buf;
271  http_request = (st_http_request*)tx_buf;
272 
273  memset(tx_buf,0x00,MAX_URI_SIZE);
274  parse_http_request(http_request, buf); // After analyze request, convert into http_request
275  memset(rx_buf,0x00,MAX_URI_SIZE);
276 
277  //method Analyze
278  switch (http_request->METHOD)
279  {
280  case METHOD_ERR :
281  memcpy(http_response, ERROR_REQUEST_PAGE, sizeof(ERROR_REQUEST_PAGE));
282  TCPSend(s, (int8 *)http_response, strlen((char*)http_response));
283  break;
284  case METHOD_HEAD:
285  case METHOD_GET:
286  case METHOD_POST:
287  if (!strcmp((char*)http_request->URI, "/")) strcpy(http_request->URI, (char const*)homepage_default); // If URI is "/", respond by index.htm
288 
289  RESTProcessor(http_request);
290 
291  //get http type from type
292  find_http_uri_type(&http_request->TYPE, http_request->URI); //Check file type (HTML, TEXT, GIF, JPEG are included)
293 
294  if(http_request->TYPE == PTYPE_PL || http_request->TYPE == PTYPE_CGI)
295  {
296  CGIProcessor(http_request, (char*)http_response);
297  }
298 
299  FILESend(s, http_request, (char*)http_response);
300 
301  break;
302 
303  default:
304  break;
305  }
306 }
307 
308 void RESTProcessor(st_http_request *http_request)
309 {
310  return;
311 }
312 
313 void CGIProcessor(st_http_request *http_request, char* buf)
314 {
315  uint32 file_len=0;
316  uint32 content = 0;
317  char *oldtmp=0, *newtmp=0;
318  char sub[32], *subtmp=0;
319  uint16 i;
320  char* name=(char*)http_request->URI;
321  if(strcmp(name,"/"))
322  name++;
323 
324  /* Search the specified file in stored binaray html image */
325  if(search_file_rom((unsigned char *)name, &content, &file_len))
326  {
327  if(file_len > 1024)// cgi파일은 최대 1024 Bytes 까지 제한
328  return;
329 
330  read_from_flashbuf(content, (uint8*)buf, file_len);
331  buf[file_len] = '\0';
332  HTTPSend(NULL, buf, (char*)BUFPUB, file_len, 1);
333 
334  oldtmp=(char*)BUFPUB;
335  newtmp=oldtmp;
336  while((newtmp = strstr(oldtmp, "<?"))){
337  mid(newtmp, "<?", "?>", sub);
338  oldtmp = newtmp + strlen(sub) + 4;
339 
340  subtmp = strstr(sub, "SetValue");
341  mid(subtmp, "(", ")", sub);
342 
343  for(i=0; i<MAX_CGI_CALLBACK; i++){
344  if(!strcmp(sub, cgi_callback[i].tokken)){
345  char *tmp;
346  uint16 len;
347 
348  if(cgi_callback[i].set_func == NULL){
349  i = MAX_CGI_CALLBACK;
350  break;
351  }
352 
353  tmp = (char*)get_http_param_value(http_request->param,cgi_callback[i].tokken);
354  len = strlen(tmp);
355 
356  cgi_callback[i].set_func(tmp, &len);
357  break;
358  }
359  }
360  if(i==MAX_CGI_CALLBACK){
361  }
362  }
363  }
364 }