From km@multi.fi Tue Jul 8 11:09:03 1997 Date: Sun, 6 Jul 1997 22:05:07 +0300 (EET DST) From: Kimmo Makkonen To: Henrik Ingo Subject: geturl Hej! Jag skrev en funktion som du kan ha nytta av i ditt quote-program. Funktionen tar som argument en URL, d.v.s. t.ex: geturl("http://www.multi.fi/"); Funktionen returnerar en pekare till en textsträng, i exemplet nedan kan du se ett exempel på användningen i main()-funktionen. Allting är inte utfört på det bästa sättet, men det borde funka ändå. För tillfället funkar bara http:// URLar, men det torde räcka för quote.cgi. Ingen större kontroll över error-situationer finns i denna funktion ännu. En ny sak som jag prövade var dynamisk allokering av minne med realloc() så den saken är jag litet osäker över. Programmet skickar som request endast en rad av formen (exempel): GET /~hingo/index.html Riktiga browsers skickar mer information till servern, här är ett exempel vad lynx skickar för information vid requesten: GET /~hingo/index.html HTTP/1.0 Host: www.multi.fi:80 Accept: audio/x-pn-realaudio, audio/x-realaudio, video/mpeg, audio/x-wav, audio/basic, x-world/x-vrml, application/x-xdma, application/applefile, application/x-metamail-patch, sun-deskset-message, mail-file, default, postscript-file, audio-file, x-sun-attachment, text/enriched, text/richtext, application/andrew-inset, x-be2, application/postscript, message/external-body, message/partial, application/pgp, application/pgp, video/mpeg, video/*, image/*, audio/*, audio/mod, text/html, text/plain, application/x-wais-source, application/html, */*;q=0.001 Accept-Encoding: gzip, compress Accept-Language: en User-Agent: Lynx/2.6 libwww-FM/2.14 From: km@multi.fi Som du ser så skickar lynx email-adressen till servern som man besöker (det var överraskande för mig, jag visste inte om det förrän nu). Jag tror att det var HTTP/0.9 som inte skickade med någon extra information, men fr.o.m. HTTP/1.0 skickas mer info. HTTP/1.1 är väl nyaste versionen nu. Kimmo ---------------------------------------------------------------------------- #include #include #include #include #include #include struct urlinfo { char prot[10]; char host[64]; int port; char path[256]; }; char *geturl(char *); void parseurl(char *, struct urlinfo *); int main(int argc, char *argv[]) { char *content; if (argc != 2) { printf("Usage: %s \n", argv[0]); return(1); } content = geturl(argv[1]); printf("%s", content); return(0); } char *geturl(char *url) { struct urlinfo urldata; struct hostent *hostp; static char *content; char buffer[1024]; int sockid, n, size=0, memsize = 8192, blocksize = 4096; struct sockaddr_in sock; char request[512]; content = (char *)malloc(memsize); parseurl(url, &urldata); /* create socket */ if ((sockid = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("error creating socket, error: %s\n", strerror(errno)); exit(0); } /* name the socket using wildcards */ bzero((char *) &sock, sizeof(sock)); sock.sin_family = AF_INET; // sock.sin_addr.s_addr = inet_addr(urldata.host); hostp = gethostbyname(urldata.host); bcopy(hostp->h_addr, &sock.sin_addr, hostp->h_length); sock.sin_port = htons(urldata.port); if (connect(sockid, (struct sockaddr *) &sock, sizeof(sock)) < 0) { printf("error connecting to server, error: %s\n", strerror(errno)); exit(0); } /* make and send request to the server */ strcpy(request, "GET "); strcat(request, urldata.path); strcat(request, "\n"); write(sockid, request, strlen(request)); /* read response from server */ while ((n = read(sockid, buffer, sizeof(buffer))) > 0) { size += n; if (size > memsize) content = (char *)realloc(content, size + blocksize); strncat(content, buffer, n); } close(sockid); return content; } void parseurl(char *url, struct urlinfo *urldata) { int i, j; char port[10]; /* get the protocol */ for (i = 0; url[i] != 0 && url[i] != ':'; i++) { urldata->prot[i] = url[i]; } urldata->prot[i] = '\0'; i += 3; /* get the host name or ip */ for (j = 0; url[i] != 0 && url[i] != ':' && url[i] != '/'; i++) { urldata->host[j++] = url[i]; } urldata->host[j] = '\0'; /* get the optional port number */ if (url[i] == ':') { i++; for (j = 0; url[i] != 0 && url[i] != '/' && isdigit(url[i]); i++) { port[j++] = url[i]; } port[j] = '\0'; urldata->port = atoi(port); } if (urldata->port == 0) urldata->port = 80; /* get the path */ for (j = 0; url[i] != 0; i++) { urldata->path[j++] = url[i]; } urldata->path[j] = '\0'; if (urldata->path[j - 1] != '/') { strcat(urldata->path, "/"); } } ----------------------------------------------------------------------------