Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

IceCast2.cpp

Go to the documentation of this file.
00001 /*------------------------------------------------------------------------------
00002 
00003    Copyright (c) 2000 Tyrell Corporation. All rights reserved.
00004 
00005    Tyrell DarkIce
00006 
00007    File     : IceCast2.cpp
00008    Version  : $Revision: 1.11 $
00009    Author   : $Author: darkeye $
00010    Location : $Source: /cvsroot/darkice/darkice/src/IceCast2.cpp,v $
00011    
00012    Copyright notice:
00013 
00014     This program is free software; you can redistribute it and/or
00015     modify it under the terms of the GNU General Public License  
00016     as published by the Free Software Foundation; either version 2
00017     of the License, or (at your option) any later version.
00018    
00019     This program is distributed in the hope that it will be useful,
00020     but WITHOUT ANY WARRANTY; without even the implied warranty of 
00021     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
00022     GNU General Public License for more details.
00023    
00024     You should have received a copy of the GNU General Public License
00025     along with this program; if not, write to the Free Software
00026     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00027 
00028 ------------------------------------------------------------------------------*/
00029 
00030 /* ============================================================ include files */
00031 
00032 #ifdef HAVE_CONFIG_H
00033 #include "config.h"
00034 #endif
00035 
00036 #ifdef HAVE_STDIO_H
00037 #include <stdio.h>
00038 #else
00039 #error need stdio.h
00040 #endif
00041 
00042 #ifdef HAVE_STRING_H
00043 #include <string.h>
00044 #else
00045 #error need string.h
00046 #endif
00047 
00048 #ifdef HAVE_MATH_H
00049 #include <math.h>
00050 #else
00051 #error need math.h
00052 #endif
00053 
00054 
00055 #include "Exception.h"
00056 #include "Source.h"
00057 #include "Sink.h"
00058 #include "Util.h"
00059 #include "IceCast2.h"
00060 
00061 
00062 /* ===================================================  local data structures */
00063 
00064 
00065 /* ================================================  local constants & macros */
00066 
00067 /*------------------------------------------------------------------------------
00068  *  File identity
00069  *----------------------------------------------------------------------------*/
00070 static const char fileid[] = "$Id: IceCast2.cpp,v 1.11 2005/04/11 18:32:32 darkeye Exp $";
00071 
00072 
00073 /*------------------------------------------------------------------------------
00074  *  Size of string conversion buffer
00075  *----------------------------------------------------------------------------*/
00076 #define STRBUF_SIZE         32
00077 
00078 
00079 /*------------------------------------------------------------------------------
00080  *  Expected positive response from server begins like this.
00081  *----------------------------------------------------------------------------*/
00082 static const char responseOK[] = "HTTP/1.0 200";
00083 
00084 
00085 /* ===============================================  local function prototypes */
00086 
00087 
00088 /* =============================================================  module code */
00089 
00090 /*------------------------------------------------------------------------------
00091  *  Initialize the object
00092  *----------------------------------------------------------------------------*/
00093 void
00094 IceCast2 :: init (  StreamFormat            format,
00095                     const char            * mountPoint,
00096                     const char            * description )
00097                                                         throw ( Exception )
00098 {
00099     this->format         = format;
00100     this->mountPoint     = Util::strDup( mountPoint);
00101     this->description    = description    ? Util::strDup( description) : 0;
00102 }
00103 
00104 
00105 /*------------------------------------------------------------------------------
00106  *  De-initialize the object
00107  *----------------------------------------------------------------------------*/
00108 void
00109 IceCast2 :: strip ( void )                           throw ( Exception )
00110 {
00111     delete[] mountPoint;
00112     if ( description ) {
00113         delete[] description;
00114     }
00115 }
00116 
00117 
00118 /*------------------------------------------------------------------------------
00119  *  Log in to the IceCast2 server
00120  *----------------------------------------------------------------------------*/
00121 bool
00122 IceCast2 :: sendLogin ( void )                           throw ( Exception )
00123 {
00124     Sink          * sink   = getSink();
00125     Source        * source = getSocket();
00126     const char    * str;
00127     char            resp[STRBUF_SIZE];
00128     unsigned int    len;
00129     unsigned int    lenExpected;
00130 
00131     if ( !source->isOpen() ) {
00132         return false;
00133     }
00134     if ( !sink->isOpen() ) {
00135         return false;
00136     }
00137 
00138     // send the request, a string like:
00139     // "SOURCE <mountpoint> ICE/1.0"
00140     str = "SOURCE /";
00141     sink->write( str, strlen( str));
00142     str = getMountPoint();
00143     sink->write( str, strlen( str));
00144     str = " HTTP/1.0";
00145     sink->write( str, strlen( str));
00146 
00147     // send the content type, Ogg Vorbis
00148     str = "\nContent-type: ";
00149     sink->write( str, strlen( str));
00150     switch ( format ) {
00151         case mp3:
00152             str = "audio/mpeg";
00153             break;
00154 
00155         case oggVorbis:
00156             str = "application/ogg";
00157             break;
00158 
00159         default:
00160             throw Exception( __FILE__, __LINE__,
00161                              "unsupported stream format", format);
00162             break;
00163     }
00164     sink->write( str, strlen( str));
00165 
00166     // send the authentication info
00167     str = "\nAuthorization: Basic ";
00168     sink->write( str, strlen(str));
00169     {
00170         // send source:<password> encoded as base64
00171         char        * source = "source:";
00172         const char  * pwd    = getPassword();
00173         char        * tmp    = new char[Util::strLen(source) +
00174                                         Util::strLen(pwd) + 1];
00175         Util::strCpy( tmp, source);
00176         Util::strCat( tmp, pwd);
00177         char  * base64 = Util::base64Encode( tmp);
00178         delete[] tmp;
00179         sink->write( base64, strlen(base64));
00180         delete[] base64;
00181     }
00182 
00183     // send user agent info
00184     str = "\nUser-Agent: DarkIce/" VERSION " (http://darkice.sourceforge.net/)";
00185     sink->write( str, strlen( str));
00186 
00187     // send the ice- headers
00188     str = "\nice-bitrate: ";
00189     sink->write( str, strlen( str));
00190     if ( log10(getBitRate()) >= (STRBUF_SIZE-2) ) {
00191         throw Exception( __FILE__, __LINE__,
00192                          "bitrate does not fit string buffer", getBitRate());
00193     }
00194     sprintf( resp, "%d", getBitRate());
00195     sink->write( resp, strlen( resp));
00196 
00197     str = "\nice-public: ";
00198     sink->write( str, strlen( str));
00199     str = getIsPublic() ? "1" : "0";
00200     sink->write( str, strlen( str));
00201 
00202     if ( getName() ) {
00203         str = "\nice-name: ";
00204         sink->write( str, strlen( str));
00205         str = getName();
00206         sink->write( str, strlen( str));
00207     }
00208 
00209     if ( getDescription() ) {
00210         str = "\nice-description: ";
00211         sink->write( str, strlen( str));
00212         str = getDescription();
00213         sink->write( str, strlen( str));
00214     }
00215 
00216     if ( getUrl() ) {
00217         str = "\nice-url: ";
00218         sink->write( str, strlen( str));
00219         str = getUrl();
00220         sink->write( str, strlen( str));
00221     }
00222 
00223     if ( getGenre() ) {
00224         str = "\nice-genre: ";
00225         sink->write( str, strlen( str));
00226         str = getGenre();
00227         sink->write( str, strlen( str));
00228     }
00229 
00230     str = "\n\n";
00231     sink->write( str, strlen( str));
00232     sink->flush();
00233 
00234     // read the response, expected response begins with responseOK
00235     lenExpected = Util::strLen( responseOK);
00236     if ( (len = source->read( resp, STRBUF_SIZE-1)) < lenExpected ) {
00237         return false;
00238     }
00239     resp[lenExpected] = 0;
00240     if ( !Util::strEq( resp, responseOK) ) {
00241         return false;
00242     }
00243     
00244     // suck anything that the other side has to say
00245     while ( source->canRead( 0, 0) && 
00246            (len = source->read( resp, STRBUF_SIZE-1)) );
00247 
00248     return true;
00249 }
00250 
00251 
00252 
00253 /*------------------------------------------------------------------------------
00254  
00255   $Source: /cvsroot/darkice/darkice/src/IceCast2.cpp,v $
00256 
00257   $Log: IceCast2.cpp,v $
00258   Revision 1.11  2005/04/11 18:32:32  darkeye
00259   changed MIME type to application/ogg, which is now official
00260 
00261   Revision 1.10  2002/11/29 08:14:47  darkeye
00262   fixed minor bug in IcecCast2.cpp, which could have lead to a buffer
00263   overflow
00264 
00265   Revision 1.9  2002/10/20 21:09:35  darkeye
00266   added processing of server response
00267 
00268   Revision 1.8  2002/08/20 20:16:59  darkeye
00269   added User-Agent header to HTTP login
00270 
00271   Revision 1.7  2002/08/20 19:34:43  darkeye
00272   minor fix
00273 
00274   Revision 1.6  2002/08/20 18:39:13  darkeye
00275   added HTTP Basic authentication for icecast2 logins
00276 
00277   Revision 1.5  2002/05/28 12:35:41  darkeye
00278   code cleanup: compiles under gcc-c++ 3.1, using -pedantic option
00279 
00280   Revision 1.4  2002/02/20 10:35:35  darkeye
00281   updated to work with Ogg Vorbis libs rc3 and current IceCast2 cvs
00282 
00283   Revision 1.3  2002/02/19 15:24:26  darkeye
00284   send Content-type header when logging in to icecast2 servers
00285 
00286   Revision 1.2  2001/11/20 09:06:18  darkeye
00287   fixed public stream reporting
00288 
00289   Revision 1.1  2001/09/14 19:31:06  darkeye
00290   added IceCast2 / vorbis support
00291 
00292 
00293   
00294 ------------------------------------------------------------------------------*/
00295 

Generated on Thu Apr 14 13:59:12 2005 for DarkIce by  doxygen 1.4.1