PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : HTTP Resume



Woolf
21-10-2002, 20:16
OK, das gehört nicht unbedingt in ein Progger forum
Aber ich mach grad einen Download manager
Und hab ein bisschen probiert. Mit Telnet mal HTTP/1.1 befehle getestet.

Ich wollte fragen wie ich einen Resume modus machen kann
So in der art
telnet abc.xyz.uv.st 80
>Get /foobar.htm HTTP/1.1
>Host: abc.xyz.uv.st
>Accept: */*
>[Alles ab dem Byte 100000] <<< was ich wissen will

Könnt ihr mir da helfen?

The Ripper
21-10-2002, 20:21
Alle offenen Protokolle im Internet sind hier dokumentiert:
http://www.rfc-editor.org/rfcxx00.html
HTTP/1.1: ftp://ftp.rfc-editor.org/in-notes/rfc2616.txt

Mattburger
22-10-2002, 10:03
Hi Woolf,

ich hatte vor ein paar Wochen das selbe Problem.
Hab denn Tip mit cURL bekommen. Hat aber nicht wirklich weitergeholfen.

Habs dann selbst ausprogrammiert mit einer Socket verbindung.
Achung bei Accept-Encoding: *;q=0 - sonst must du die chunks auseinandersetzen
und eventuell noch entkomprimieren.
Ansonsten ein Get absetzen, das CRLFCRLF abwarten und den rest rausschreiben.

Hier der Source-Code:


#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/errno.h>
#include <signal.h>

char *program_name;
int timeout_value = 30;
int get_header=0;

err_exit(i,s)
int i;
char *s;
{
if (i == -1) {
perror(s);
exit(1);
}
}

main(argc,argv)
int argc;
char *argv[];
{
extern int optind;
extern char *optarg;
int c;

program_name = argv[0];

while ((c = getopt(argc, argv, "ht:")) != EOF) {
switch (c) {
case 'h': get_header = 1; break;
case 't': timeout_value = atoi(optarg); break;
default: usage(); break;
}
}

argc -= optind-1;
argv += optind-1;

if (argc != 2)
usage();

fetch(argv[1]);

return 0;
}

usage()
{
fprintf(stderr,"usage %s: [-h] [-t <timeout>] url\n", program_name);
fprintf(stderr,"-h: get header\n");
fprintf(stderr,"-t <timeout>: give up after <timeout> seconds\n");
exit(1);
}

timeout()
{
}

open_my_socket(host, port)
char *host;
int port;
{
int sd;
struct sockaddr_in addr;
struct hostent* hp;
int err;

hp = gethostbyname(host);
if (hp == NULL) {
perror("gethostbyname");
fprintf(stderr, "can't gethostbyname(\"%s\")\n", host);
exit(1);
}

signal(SIGALRM, timeout);
if (timeout_value>0)
alarm(timeout_value);
sd = socket(AF_INET, SOCK_STREAM, 0);
alarm(0); /* cancel the alarm */
if (sd==-1 && errno==EINTR) {
perror("socket");
exit(1);
}
err_exit(sd,"socket(2) call failed");

/* fill in the addr structure */
addr.sin_family = AF_INET;
addr.sin_port = port;
addr.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;

/* hook up to it */

signal(SIGALRM, timeout);
if (timeout_value>0)
alarm(timeout_value);
err = connect(sd, &addr, sizeof(addr));
alarm(0); /* cancel the alarm */
if (err==-1 && errno==EINTR) {
perror("socket");
exit(1);
}
err_exit(err,"connect failed");

return sd;
}

fetch(url)
char *url;
{
int fd, port, len, start;
char server[80], buf[81920], path[256];
char *printbuf;

if (strncmp(url, "ftp:", 4)==0) {
strcpy(server, "web_proxy.irgendwas.com");
strcpy(path, url);
port = 8088;
}
else {
/*
* URL is of the form
* http://server:port/path
*/

/* Skip the leading http: */
if (strncmp(url, "http:",5)==0) {
url += 5;
}
if (strncmp(url, "//",2)!=0) {
fprintf(stderr, "%s: bad URL\n", program_name);
exit(1);
}
url += 2;

/* Get the server up to a slash or a colon */
if (sscanf(url, "%[^:/]", &server) != 1 || server[0]=='\0') {
fprintf(stderr, "%s: can't parse server in URL\n", program_name);
exit(1);
}
url += strlen(server);

if (*url == ':') {
url++;
port = strtol(url, &url, 10);
}
else
port = 80;

strcpy(path, url);
}

fd = open_my_socket(server, port);
if (fd == -1)
return;

if (get_header)
sprintf(buf, "GET %s HTTP/1.0\r\n"
"Accept: text/plain\r\n"
"Host: %s\r\n"
"Connection: Close\r\n",
path, server);
else {
fprintf(stderr,"GET %s HTTP/1.0\r\n"
"Accept: */*\r\n"
"Accept-Encoding: *;q=0\r\n"
"Host: %s\r\n"
"Connection: Close\r\n\r\n", path,server);
sprintf(buf, "GET %s HTTP/1.0\r\n"
"Accept: */*\r\n"
"Accept-Encoding: *;q=0\r\n"
"Host: %s\r\n"
"Connection: Close\r\n\r\n", path,server);
}

write(fd, buf, strlen(buf));

start= 0;
for (;;) {
if (timeout_value>0)
alarm(timeout_value);
len = read(fd, buf, sizeof(buf));
printbuf= &buf[0];
alarm(0); /* cancel the alarm */
if (len <= 0)
break;
if (start==0) {
printbuf= strstr( buf, "\r\n\r\n");
//fprintf(stderr, "len bevore: %d\r\n", len );
len = len - 4 -( printbuf - &buf[0] );
// fprintf(stderr, "len after : %d\r\n", len );
start= 1;
}
/* write(1, buf, len); */
if (len > 0)
write( 1, printbuf, len );
}
if (len == -1)
perror("read");
}

Woolf
22-10-2002, 15:12
Danke erstmal, aber Mattburger-- :

:D hättest bei die "Grafische Smilies deaktivieren?" anhakeln müssen, der code da besteht zum Teil aus smilies :D

Aber, erm mir gehts eher darum, wie ich ab einem bestimmten byte fortsetzen kann, in deinem code steht davon nix :(

Und dieses rfc is dumm zum lesen, gibz davon keine formatierte ausgabe? .txt und mit seitenangaben is doch besch...


Das mit dem Content-Range: bytes x-
funkt ned -<-

Mattburger
22-10-2002, 16:51
Hi ! hab's jetzt korrigiert.

Hast recht war ziemlich schluderig. - ;)

Eigentlich wollte ich dir ja nur eine Anregung zum selbstprogrammieren geben.
Es fehlt natürlich der Test mit dem Offset. etc.

Ein fertiges Programm hab ich leider nicht.

Gruesse aus Reutlingen
Mike

Woolf
22-10-2002, 20:05
:D Die Anregung hast mir erfolgreich gegeben :)

Aber mir gehts grad um das HTTP 1.1 Protokoll

Sobald ich das kapiert hab werd ich nachdenken ob ich java oder C/C++ verwend
C/C++ kann ich ja, aber java2 wär ne herausforderung, hab die nötige lektüre, nur komm ich in letzter zeit nicht zum lesen :)

Deshalb probier ich ja auch grad mit telnet, das programm kann ich ja erst machen wenn ich alles notwendige habe

Ich plane voraus, ja ich könnt ein downloadprog machen, aber ich möcht zuerst alles beisammen haben, und genau das fehlt eben noch

Einfach draus los programmieren mach ich nur bei Games, und selbst da vorher eine kurze Struktur...

Ein kleines beispiel: (hier bitte beachten, dass ich kein professioneller progger sondern ein 14-jähriger Schüler bin...)
hab so ein game gemacht wo du windowszeichen in müllkübel schiebst, so ähnlich wie sokoban, war ein SDL test von mir, habs ausgeweitet und man kann jetzt mit text dateien
"level[nummer von 0 bis 9].lvl" ungefähr so:


WWWWWWW
WM W
W PW
...

Levels basteln
Das "levelpackage" was man gern spieln möcht verlinkt man dann als "levels" Ordner
Hab zum beispiel
Easy.levels drin
> ln -s Easy.levels levels
und dann:
>./windowkiller
Ganz gut für nen 14-Jährigen, oder? Hab sogar Joystick steuerung dazugefügt ;) :D



Jetzt hab ich mich schon wieder mal Festge"-schrieben"