Handle HTTP redirections automatically.
[doldaconnect.git] / common / httest.c
1 /*
2  *  Dolda Connect - Modular multiuser Direct Connect-style client
3  *  Copyright (C) 2007 Fredrik Tolf <fredrik@dolda2000.com>
4  *  
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *  
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *  
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <unistd.h>
23 #include <string.h>
24 #include <sys/poll.h>
25 #include <errno.h>
26
27 #include <utils.h>
28 #include <http.h>
29
30 void parse(char *url)
31 {
32     struct hturlinfo *u;
33     
34     if((u = parseurl(url)) == NULL) {
35         fprintf(stderr, "httest: %s: invalid url\n", url);
36         return;
37     }
38     printf("host: %s\n", u->host);
39     printf("port: %i\n", u->port);
40     printf("path: %s\n", u->path);
41     printf("query: %s\n", u->query);
42     printf("fragment: %s\n", u->fragment);
43     freeurl(u);
44 }
45
46 void head(char *url)
47 {
48     struct hturlinfo *u;
49     struct htconn *c;
50     struct pollfd pfd;
51     struct strpair *p;
52     int ret;
53     
54     if((u = parseurl(url)) == NULL) {
55         fprintf(stderr, "httest: %s: invalid url\n", url);
56         return;
57     }
58     c = htconnect(u);
59     freeurl(u);
60     while(1) {
61         pfd.fd = c->fd;
62         pfd.events = htpollflags(c);
63         if(poll(&pfd, 1, -1) < 0) {
64             fprintf(stderr, "httest: %s: %s\n", url, strerror(errno));
65             freehtconn(c);
66             return;
67         }
68         if((ret = htprocess(c, pfd.revents)) < 0) {
69             fprintf(stderr, "httest: %s: %s\n", url, strerror(errno));
70             freehtconn(c);
71             return;
72         }
73         c->databufdata = 0;
74         if(ret)
75             break;
76     }
77     printf("%i %s\n", c->rescode, c->resstr);
78     for(p = c->headers; p != NULL; p = p->next)
79         printf("%s: %s\n", p->key, p->val);
80     freehtconn(c);
81 }
82
83 void get(char *url)
84 {
85     struct hturlinfo *u;
86     struct htconn *c;
87     struct pollfd pfd;
88     struct strpair *p;
89     int ret, ret2;
90     
91     if((u = parseurl(url)) == NULL) {
92         fprintf(stderr, "httest: %s: invalid url\n", url);
93         return;
94     }
95     c = htconnect(u);
96     freeurl(u);
97     c->autoredir = 1;
98     while(1) {
99         pfd.fd = c->fd;
100         pfd.events = htpollflags(c);
101         if(poll(&pfd, 1, -1) < 0) {
102             fprintf(stderr, "httest: %s: %s\n", url, strerror(errno));
103             freehtconn(c);
104             return;
105         }
106         if((ret = htprocess(c, pfd.revents)) < 0) {
107             fprintf(stderr, "httest: %s: %s\n", url, strerror(errno));
108             freehtconn(c);
109             return;
110         }
111         while(c->databufdata > 0) {
112             ret2 = write(1, c->databuf, c->databufdata);
113             memmove(c->databuf, c->databuf + ret2, c->databufdata -= ret2);
114         }
115         if(ret)
116             break;
117     }
118     printf("%i %s\n", c->rescode, c->resstr);
119     for(p = c->headers; p != NULL; p = p->next)
120         printf("%s: %s\n", p->key, p->val);
121     freehtconn(c);
122 }
123
124 int main(int argc, char **argv) {
125     int i;
126     
127     for(i = 1; i < argc; i++) {
128         if(!strcmp(argv[i], "parse")) {
129             parse(argv[++i]);
130         } else if(!strcmp(argv[i], "head")) {
131             head(argv[++i]);
132         } else if(!strcmp(argv[i], "get")) {
133             get(argv[++i]);
134         }
135     }
136     return(0);
137 }