2 * Copyright 2004-2008, François Revol, <revol@free.fr>.
3 * Distributed under the terms of the MIT License.
13 #include <netinet/in.h>
14 #include <arpa/inet.h>
20 #include <KernelExport.h>
21 #define printf dprintf
25 #define DBG "googlefs: http_cnx: "
29 //#define GOOGLEFS_UA "GoogleFS"
30 //Mozilla/3.0 (compatible; NetPositive/2.2.2; BeOS)
31 //Mozilla/5.0 (BeOS; U; BeOS BePC; en-US; rv:1.8.1.18) Gecko/20081114 BonEcho/2.0.0.18
33 #define GOOGLEFS_UA "Mozilla/5.0 (compatible; GoogleFS/0.1; Haiku)"
35 #define GOOGLEFS_UA "Mozilla/5.0 (compatible; GoogleFS/0.1; BeOS)"
39 #define BUFSZ (128*1024)
46 return ksocket_init();
49 status_t
http_uninit()
51 return ksocket_cleanup();
54 status_t
http_create(struct http_cnx
**cnx
)
58 c
= malloc(sizeof(struct http_cnx
));
61 memset(c
, 0, sizeof(struct http_cnx
));
62 err
= c
->sock
= ksocket(AF_INET
, SOCK_STREAM
, 0);
71 status_t
http_delete(struct http_cnx
*cnx
)
75 if ((unsigned long)cnx
< 0x40) {
76 dprintf("http: WARNING: cnx ptr = %p\n", cnx
);
80 kclosesocket(cnx
->sock
);
85 cnx
->buffer
= 0xaa55aa55;//XXX
90 status_t
http_connect(struct http_cnx
*cnx
, struct sockaddr_in
*sin
)
96 dprintf("http_connect(, NULL)!!\n");
99 ip
= sin
->sin_addr
.s_addr
;
100 port
= sin
->sin_port
;
101 dprintf("http_connect(, %d.%d.%d.%d:%d), sock = %ld\n", ip
& 0xff, (ip
>> 8) & 0xff, (ip
>> 16) & 0xff, (ip
>> 24) & 0xff, ntohs(port
), cnx
->sock
);
102 err
= kconnect(cnx
->sock
, (struct sockaddr
*)sin
, sin
->sin_len
);
109 status_t
http_close(struct http_cnx
*cnx
)
116 err
= kclosesocket(cnx
->sock
);
121 status_t
http_get(struct http_cnx
*cnx
, const char *url
)
129 if (strlen(url
) > 4096 - 128)
131 req
= malloc(4096+1);
135 /* no snprintf in kernel :( */
136 sprintf(req
, "GET %s HTTP/"HTTPVER
"\r\nUser-Agent: " GOOGLEFS_UA
"\r\nAccept: */*\r\n\r\n", url
);
137 reqlen
= strlen(req
);
138 err
= len
= write(cnx
->sock
, req
, reqlen
);
142 err
= len
= read(cnx
->sock
, req
, reqlen
);
143 printf("read(sock) = %d\n", len
);
146 //write(1, req, len);
150 fd
= open("/tmp/google.html_", O_CREAT
|O_TRUNC
|O_RDWR
, 0644);
158 if (!strstr(req
, "HTTP/1.0 200"))
162 if (!strstr(req
, "\r\n\r\n")) {
163 if (!strstr(req
, "\n\n")) /* shouldn't happen */
165 headerslen
= strstr(req
, "\n\n") - req
+ 2;
166 req
[headerslen
-1] = '\0';
167 req
[headerslen
-2] = '\0';
169 headerslen
= strstr(req
, "\r\n\r\n") - req
+ 4;
170 req
[headerslen
-3] = '\0';
171 req
[headerslen
-4] = '\0';
173 if (headerslen
< 2 || headerslen
> 4095)
175 p
= strstr(req
, "HTTP/1.");
178 p
+= strlen("HTTP/1.");
182 cnx
->err
= strtol(p
, &p
, 10);
183 if (cnx
->err
< 200 || cnx
->err
> 299)
185 printf("REQ: %d\n", cnx
->err
);
186 contentlen
= len
- headerslen
;
187 // if (!strstr(req, "\n\n") && !strstr(req, "\r\n\r\n"))
190 long left
= reqlen
- headerslen
- contentlen
;
193 p
= realloc(req
, reqlen
);
199 err
= len
= read(cnx
->sock
, req
+ headerslen
+ contentlen
, left
);
206 cnx
->headerslen
= headerslen
;
207 cnx
->data
= req
+ headerslen
;
208 cnx
->datalen
= contentlen
;
209 cnx
->data
[contentlen
] = '\0'; /* we have at least 128 bytes allocated ahead */
231 //#define TESTURL "/"
232 //#define TESTURL "http://www.google.com/search?as_q=google+api+&num=50&hl=en&ie=ISO-8859-1&btnG=Google+Search&as_epq=frequently+asked&as_oq=help&as_eq=plop&lr=lang_en&as_ft=i&as_filetype=&as_qdr=m3&as_nlo=&as_nhi=&as_occt=any&as_dt=i&as_sitesearch="
233 #define TESTURL "http://www.google.com/search?hl=en&ie=UTF-8&num=50&q=beos"
234 int main(int argc
, char **argv
)
236 struct sockaddr_in sin
;
237 struct http_cnx
*cnx
;
243 err
= http_create(&cnx
);
244 printf("error 0x%08lx\n", err
);
245 sin
.sin_len
= sizeof(struct sockaddr_in
);
246 sin
.sin_family
= AF_INET
;
247 sin
.sin_addr
.s_addr
= htonl(INADDR_LOOPBACK
);
248 inet_aton("66.102.11.99", &sin
.sin_addr
);
249 sin
.sin_port
= htons(80);
250 err
= http_connect(cnx
, &sin
);
251 printf("error 0x%08lx\n", err
);
252 err
= http_get(cnx
, TESTURL
);
253 printf("error 0x%08lx\n", err
);
256 printf("HEADERS %d:%s\n", cnx
->headerslen
, cnx
->headers
);
257 printf("DATA: %d:%s\n", cnx
->datalen
, cnx
->data
);