2 * Acess2 Command-line HTTP Client (wget)
24 int _ParseHeaderLine(char *Line, int State, size_t *Size);
26 int main(int argc, char *argv[])
29 gasURLs = malloc( (argc - 1) * sizeof(*gasURLs) );
32 for(int i = 1; i < argc; i ++ )
37 gasURLs[giNumURLs++] = arg;
39 else if( arg[1] != '-') {
48 for( int i = 0; i < giNumURLs; i ++ )
51 tURI *uri = URI_Parse(gasURLs[i]);
52 struct addrinfo *addrinfo;
55 fprintf(stderr, "'%s' is not a valid URL", gasURLs[i]);
59 printf("Proto: %s, Host: %s, Path: %s\n", uri->Proto, uri->Host, uri->Path);
61 if( uri->Path[0] == '\0' )
62 outfile = "index.html";
64 outfile = strrchr(uri->Path, '/') + 1;
68 if( strcmp(uri->Proto, "http") == 0 ) {
71 else if( strcmp(uri->Proto, "https") == 0 ) {
76 fprintf(stderr, "Unknown protocol '%s'\n", uri->Proto);
81 rv = getaddrinfo(uri->Host, NULL, NULL, &addrinfo);
83 fprintf(stderr, "Unable to resolve %s: %s\n", uri->Host, gai_strerror(rv));
87 for( struct addrinfo *addr = addrinfo; addr != NULL; addr = addr->ai_next )
90 // TODO: Convert to POSIX/BSD
91 int sock = Net_OpenSocket(addr->ai_family, addr->ai_addr, "tcpc");
92 if( sock == -1 ) continue ;
94 writef(sock, "GET /%s HTTP/1.1\r\n", uri->Path);
95 writef(sock, "Host: %s\r\n", uri->Host);
96 // writef(sock, "Accept-Encodings: */*\r\n");
97 writef(sock, "User-Agent: awget/0.1 (Acess2)\r\n");
101 char inbuf[BUFSIZ+1];
104 size_t bytes_seen = 0;
105 size_t bytes_wanted = -1; // invalid
107 while( state == 0 || state == 1 )
109 if( offset == sizeof(inbuf) ) {
113 // TODO: Handle -1 return
114 offset += read(sock, inbuf + offset, sizeof(inbuf) - offset);
117 char *eol = strchr(inbuf, '\n');
118 // No end of line char? read some more
119 if( eol == NULL ) continue ;
120 // Update write offset
121 offset = eol + 1 - inbuf;
126 if( eol - 1 >= inbuf )
131 state = _ParseHeaderLine(inbuf, state, &bytes_wanted);
133 memmove( inbuf, inbuf + offset, sizeof(inbuf) - offset );
139 int outfd = open(outfile, O_WR|O_CREAT, 0666);
142 while( bytes_seen < bytes_wanted )
144 // Abuses offset as read byte count
145 offset = read(sock, inbuf, sizeof(inbuf));
146 write(outfd, inbuf, offset);
147 bytes_seen += offset;
161 int _ParseHeaderLine(char *Line, int State, size_t *Size)
163 // First line (Status and version)
166 // HACK - assumes HTTP/1.1 (well, 9 chars before status)
167 switch( atoi(Line + 9) )
173 fprintf(stderr, "Unknown HTTP status - %s\n", Line + 9);
178 else if( Line[0] == '\0' )
185 char *colon = strchr(Line, ':');
186 if(colon == NULL) return 1;
189 if( strcmp(Line, "Content-Length") == 0 ) {
190 *Size = atoi(colon + 1);
193 printf("Ignorning header '%s' = '%s'\n", Line, colon+1);