Initial xloong code
[xloong.git] / pmon / netio / httplib.c
blob564fdd7ba4f530a34ac3a7f35664ae29b2200488
1 /* httplib.c, v1.0 2008/09/07 9:54 */
2 /*
4 * Note:(Http increased download a need to amend some of the things)
5 * 1.cons/files: add "file pmon/netio/httplib.c inet"
6 * 2.ib/libc/open.c: add"else if(strpat(dname, "http:*"))" in function of open
7 * 3.pmon/netio/netio.c: add"else {return fd;}" in line 89 of function of netiopen
8 * 4../sys/netinet/in_proto.c: " #if NTCP > 0"->"#if NTCP = 0" in line 137
10 *The first test was a success in zloader.2fdev.cs5536 in 2008/09/07 9:50
11 *test begin:
13 * ifaddr rtk0 10.0.0.187
14 * load tftp://10.0.0.111/gzram
15 * g
16 * ifaddr rtk0 10.0.0.187
17 * load http://10.0.0.111/gzram
18 * g
19 *test end;
20 *The last test was a success in zloader.2fdev.cs5536 in 2008/09/07 11:13
23 #undef _KERNEL
24 #include <sys/types.h>
25 #include <sys/param.h>
26 #include <sys/socket.h>
27 #include <sys/ioctl.h>
28 #include <sys/file.h>
29 #include <sys/time.h>
30 #include <sys/syslog.h>
31 #include <sys/endian.h>
33 #include <netinet/in.h>
34 #include <stdio.h>
35 #include <errno.h>
36 #include <netdb.h>
37 #include <string.h>
38 #include <stdlib.h>
39 #include <unistd.h>
40 #include <file.h>
41 #include <net/if.h>
43 #include "netio.h"
44 #include <pmon.h>
45 #define HPSIZE 0x2000
48 * struct httpfile:
49 * sockaddr_in->hostaddr
50 * sock ->ID of socket
51 * flags ->limits of authority
54 struct httpfile {
55 struct sockaddr_in sin;
56 int sock;
57 short flags;
58 int start;
59 int end;
60 int foffs;
61 char buf[HPSIZE];
62 int eof;
67 * my_buf ->file
68 * fp_buf ->Guidelines document
69 * buf_size ->size of file
72 static int buf_size;
74 static int httpopen (int, struct Url *, int, int);
75 static int httpread (int, void *, int);
76 static int httpwrite ();
77 static off_t httplseek (int, long, int );
78 static int httpioctl ();
79 static int httpclose ();
80 static int my_write(char *, int, char *);
81 static int my_read(int, struct httpfile*);
85 * init struct httpops
88 static NetFileOps httpops = {
89 "http",
90 httpopen,
91 httpread,
92 httpwrite,
93 httplseek,
94 httpioctl,
95 httpclose
97 static void init_netfs __P((void)) __attribute__ ((constructor));
99 static void
100 init_netfs()
102 netfs_init(&httpops);
105 static int
106 httpopen (int fd, struct Url *url, int flags, int perms)
108 struct hostent *hp;
109 struct httpfile *http;
110 NetFile *nfp = (NetFile *)_file[fd].data;
111 char hbuf[MAXHOSTNAMELEN];
112 int oflags = flags & O_ACCMODE;
113 char *host;
114 int connect_fd;
115 // get hostname
116 if(strlen(url->hostname) != 0)
118 host = url->hostname;
120 else
122 host = getenv("httphost");
123 if(!host)
125 log(LOG_INFO, "http: missing/bad host name: %s\n", url->filename);
126 errno = EDESTADDRREQ;
127 return -1;
130 //set up struct httpfile*, and clear 0
131 http = (struct httpfile *)malloc(sizeof (struct httpfile));
132 bzero(http, sizeof(struct httpfile));
134 nfp->data = (void *)http;
136 //set socket,and get number of socket
137 http->sock = socket(AF_INET, SOCK_STREAM, 0);
139 //sin_family = AF_INET,and bind
140 http->sin.sin_family = AF_INET;
141 http->sin.sin_port = htons(url->port?url->port:80);
142 http->flags = flags;
145 //get the message of host
146 hp = gethostbyname(host);
147 if(hp)
149 http->sin.sin_family = hp->h_addrtype;
150 bcopy(hp->h_addr, (void *)&http->sin.sin_addr, hp->h_length);
151 strncpy(hbuf, hp->h_name, sizeof(hbuf)-1);
152 hbuf[sizeof(hbuf)-1]='\0';
153 host = hbuf;
155 else
156 goto error;
159 * connect the httpd
162 connect_fd = connect(http->sock,&http->sin, sizeof(http->sin));
163 if(connect_fd < 0)
164 goto error;
168 * my_write ->add head of http,send filename address and port of host
169 * my_read ->del head of http,receive file
172 my_write(host, http->sock, url->filename);
173 my_read(http->sock, http);
174 http->end=read(http->sock, http->buf, HPSIZE);
175 http->start = 0;
176 return 0;
177 error:
178 return -1;
181 static int
182 my_write(char *host, int socketfd, char *filename)
184 char html_http[1000];
185 int n;
186 sprintf(html_http, "%s%s%s%s%s", "GET /",filename,
187 " HTTP/1.1\r\nHost:", host,":8000\r\n"
188 "User-Agent:Mozilla/5.0(X11;U;Linux i686;en-US;rv:1.8.16)Gecko/20061201 Firefox/2.0.0.6(Ubuntu-feisty)\r\n"
189 "Accept:text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5\r\n"
190 "Accept-Language:en-us,en;q=0.5\r\n"
191 "Accept-Encoding:gzip,defalte\r\n"
192 "Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n"
193 "Keep-Alive:300\r\n"
194 "Connecting:keep-alive\r\n\r\n");
196 again:
197 if ((n = write(socketfd, html_http, strlen(html_http))) == -1)
199 if (errno == EINTR)
200 goto again;
201 else return -1;
203 return n;
205 static int sum_number = 0;
206 int my_readline(int fd, char *buf, int count)
208 char ch[2];
209 int number = 0;
210 ch[0] = '3';
211 while(1)
213 read(fd, ch ,1);
214 *buf++ = ch[0];
215 number++;
216 if(ch[0] == '\n')
217 break;
219 sum_number += number;
220 return number;
222 static int
223 my_read(int socketfd, struct httpfile *http)
225 char rhtml_http[1000];
226 char buf_length[20];
227 char *buf_c_l;
228 int buf_len = 0;
229 int n;
230 char ch[2];
231 while((n = my_readline(socketfd, rhtml_http, 1000)) > 2)
233 // write(1, rhtml_http, n);
234 if(strstr(rhtml_http, "Content-Length") != NULL)
236 buf_c_l = rhtml_http + 16;
237 strcpy(buf_length, buf_c_l);
238 buf_len = atoi(buf_length);
239 buf_size = buf_len;
241 memset(rhtml_http, 0 , 1000);
244 return 0;
249 * read the buf ->read the file
252 static int
253 httpread (int fd,void* buf,int nread)
255 struct httpfile *http;
256 NetFile *nfp;
257 int nb, n;
258 int nj;
259 char *buf_flag;
260 nfp = (NetFile *)_file[fd].data;
261 http = (struct httpfile *)nfp->data;
262 buf_flag = http->buf;
264 for (nb = nread; nb != 0 && http->start < http->end; ) {
266 if (http->foffs >= http->start && http->foffs < http->end) {
267 /* got some data that's in range */
268 n = http->end - http->foffs;
269 if (n > nb) n = nb;
270 bcopy(http->buf+http->foffs-http->start, buf, n);
271 http->foffs += n;
272 buf += n;
273 nb -= n;
275 if (http->foffs >= http->end) {
276 http->start = http->end;
277 if(http->foffs>=buf_size)break;
278 n = read(http->sock, http->buf, HPSIZE);
279 if(n<=0)break;
280 http->end = http->start + n;
281 if (http->flags & O_NONBLOCK)
282 dotik (100, 0);
285 return nread -nb;
288 static int
289 httpwrite (fd, buf, nwrite)
290 int fd;
291 const void *buf;
292 int nwrite;
294 return -1;
299 * lseek of file
302 static off_t
303 httplseek (int fd, long offs, int how)
305 struct httpfile *http;
306 NetFile *nfp;
308 nfp = (NetFile *)_file[fd].data;
309 http = (struct httpfile *)nfp->data;
311 switch (how) {
312 case SEEK_SET:
313 http->foffs = offs;
314 break;
315 case SEEK_CUR:
316 http->foffs += offs;
317 break;
318 case SEEK_END:
319 default:
320 return -1;
322 return http->foffs;
326 static int
327 httpioctl (fd, op, argp)
328 int fd;
329 int op;
330 void *argp;
332 return -1;
337 * close the file
340 static int
341 httpclose (int fd)
343 NetFile *nfp;
344 struct httpfile *http;
346 nfp = (NetFile *)_file[fd].data;
347 http = (struct httpfile *)nfp->data;
348 close (http->sock);
349 free(http);
350 return 0;