Main Page   Data Structures   File List   Data Fields   Globals   Related Pages  

inet/httpget.cpp

Go to the documentation of this file.
00001 /*  httpget.cpp
00002     A simple http client
00003 
00004     13.08.2001: tk, initial implementation, based on Beck
00005                     example code.
00006 
00007     Copyright (c)2000 by Thomas Kindler, thomas.kindler@gmx.de
00008 
00009     This program is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU General Public License as
00011     published by the Free Software Foundation; either version 2 of
00012     the License, or (at your option) any later version. Read the
00013     full License at http://www.gnu.org/copyleft for more details.
00014 */
00015 
00016 // include files ----------
00017 //
00018 #include <conio.h>
00019 #include <stdio.h>
00020 #include <string.h>
00021 #include <stdlib.h>
00022 #include <assert.h>
00023 #include "inet/httpget.h"
00024 #include "inet/base64.h"
00025 #include "inet/dns.h"
00026 #include "inet/url.h"
00027 #include "clib/rtos.h"
00028 #include "clib/tcpip.h"
00029 #include "mpbuf.h"
00030 #include "misc.h"
00031 #include "vs1001.h"
00032 
00049 char *sockgets(char *s, int n, int sd)
00050 {
00051   int   error, rcvd;
00052   char *ptr = s;
00053 
00054   while (n>1) {
00055     rcvd = recv(sd, ptr, 1, MSG_TIMEOUT, 10000L, &error);
00056     if (error != 0 || rcvd != 1)
00057       return NULL;
00058 
00059     if (*ptr++ == '\n')
00060       break;
00061 
00062     n--;
00063   }
00064   *ptr = '\0';
00065   assert(ptr < s+n);
00066 
00067   return s;
00068 }
00069 
00070 
00082 int sockputs(const char *s, int sd)
00083 {
00084   int len, error, sent;
00085 
00086   len = strlen(s);
00087   while (len>0) {
00088     sent = send(sd, (char*)s, len, 0, &error);
00089     if (error!=0 || sent<0)
00090       break;
00091     s   += sent;
00092     len -= sent;
00093   }
00094   assert(len>=0);
00095 
00096   return (len==0) ? 1 : EOF;
00097 }
00098 
00099 
00108 unsigned  http_connect(const char *urlString, int *error)
00109 {
00110   unsigned long  ipnumber, ttl;
00111   char     ipaddr[16];
00112   unsigned socket = 0;
00113 
00114   URL  *url = parse_url(urlString);
00115   if (!url->port)
00116     url->port = DEFAULT_HTTP_PORT;
00117 
00118   printf("connecting to %s..\n", url->host);
00119   if (inet_addr(url->host, &ipnumber)) {
00120     int ret = gethostbyname(NULL, url->host, &ttl, &ipnumber, ipaddr);
00121     if (!ret) {
00122       printf("  can't resolve host address!\n");
00123       // No route to host error.. not exactly, but close ;)
00124       //
00125       *error = 265;
00126       goto Return;
00127     } else printf("  resolved to %s.\n", ipaddr);
00128   } else {
00129     strncpy(ipaddr, url->host, sizeof(ipaddr));
00130   }
00131 
00132   // Send request to server -----
00133   //
00134   char  request[512], *r = request;  // worst case !
00135   r += sprintf(r, "GET /%s HTTP/1.0\r\n", url->path ? url->path : "");
00136   r += sprintf(r, "Host: %s:%u\r\n", url->host, url->port);
00137   r += sprintf(r, "User-Agent: mp3v2 client 1.1, www.kreapc.de\r\n");
00138   r += sprintf(r, "Connection: Keep-Alive\r\n");
00139 //  r += sprintf(r, "Icy-MetaData: 1\r\n");
00140 
00141   if (url->user) {
00142     char *authcode = NULL;
00143     char str[64], *s = str;
00144 
00145     s += sprintf(s, "%s", url->user);
00146     if (url->pass)
00147       s += sprintf(s, ":%s", url->pass);
00148     assert((s-str)<sizeof(str));
00149     authcode = base64encode(str, strlen(str), NULL);
00150 
00151     if (authcode) {
00152       r += sprintf(r, "Authorization: Basic %s\r\n", authcode);
00153       free(authcode);
00154     }
00155   }
00156   r += sprintf(r, "\r\n");
00157   assert((r-request)<sizeof(request));
00158 
00159   printf("  opening connection.. ");
00160   socket = tcp_connect(ipaddr, 0, url->port, error);
00161   if (*error) {
00162     printf("error %d.\n", *error);
00163     goto Return;
00164   } else printf("ok.\n");
00165 
00166   printf("  sending request.. ");
00167   printf("\n%s\n", request);
00168 
00169   if (!sockputs(request, socket)) {
00170     printf( "error while sending request\n");
00171     goto Return;
00172   } else printf("ok.\n");
00173 
00174 
00175 Return:
00176   if (url)
00177     free_url(url);
00178   return  socket;
00179 }
00180 
00181 
00182 void  getMetaData(int sd)
00183 {
00184   int   error, rcvd;
00185   char  metalen;
00186   char  metadata[512];
00187 
00188   rcvd = recv(sd, &metalen, 1, MSG_TIMEOUT, 10000L, &error);
00189   if (error!=0 || rcvd!=1)
00190     return;
00191 
00192   if (metalen) {
00193     printf("%d bytes: ", metalen*16);
00194     rcvd = recv(sd, metadata, metalen*16, MSG_TIMEOUT, 10000L, &error);
00195     if (error!=0)
00196       return;
00197     printf("%s\n", metadata);
00198   }
00199 
00200 }
00201 
00202 
00203 void  http_get(const char *urlString)
00204 {
00205   int       sd, error;
00206   unsigned  rcvd;
00207   char      header[512];
00208 
00209   int       tcp_delay = 0;
00210   SetSocketOption options = {
00211     IP_PROTOTCP_LEVEL, TCP_DELAY_ACK,
00212     (char*)&tcp_delay, sizeof(tcp_delay)        
00213   };
00214 
00215   sd = http_connect(urlString, &error);
00216   if (error)
00217     goto Return;
00218           
00219   // set TCP_DELAY_ACK option
00220   setsockopt(sd, &options, &error);
00221   printf("setsockopt returned %x\n", error);
00222 
00223   printf("receiving header.. ");
00224   while (1) {
00225     sockgets(header, sizeof(header), sd);
00226     printf("%s", header);
00227     if (!strcmp(header, "\r\n"))
00228       break;
00229   }
00230 
00231   // set threshold to 50% to handle slow servers nicely
00232   //
00233   BUF_SetThreshold(BUF_GetSize()/2);
00234   BUF_Play();
00235 
00236   while (!kbhit() && !error) {
00237 //    LCD_SetBrightness(((float)BUF_GetCount()/BUF_GetSize())*255);
00238 
00239     // fill buffer
00240     //
00241     if (BUF_GetFreeBytes() > 8192) {
00242       char *buf1;
00243       long  len = 8192, len1;
00244 
00245       while (len>0) {
00246         BUF_Lock(-1, len, &buf1, &len1, 0, 0 );
00247         rcvd = recv(sd, buf1, len1, MSG_TIMEOUT, 10000L, &error);
00248         if (error || rcvd == 0)
00249           break;
00250         BUF_Unlock(rcvd);
00251         len -= rcvd;
00252       }
00253 //      getMetaData(sd);
00254 
00255       printf(".");
00256     }
00257     // update display
00258     //
00259 /*    cleardevice();
00260     gotoxy(0,0);
00261     gprintf(ProgressBar(BUF_GetCount(), 0, BUF_GetSize()));
00262     LCD_Update();  */
00263 
00264     // be nice to other apps..
00265     //
00266     RTX_Sleep_Time(100);
00267   }
00268   BUF_Clear();
00269   getch();
00270 
00271 Return:
00272   if (sd)
00273     closesocket(sd, &error);
00274   return;
00275 }

Generated on Sun Aug 4 21:47:28 2002 for k/os mp3v2 by doxygen1.2.16