upnp/upnpstack/upnputils/src/upnphttpmessage.cpp
changeset 0 f5a58ecadc66
equal deleted inserted replaced
-1:000000000000 0:f5a58ecadc66
       
     1 /** @file
       
     2 * Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies  this distribution, and is available 
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  HTTP header
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDES
       
    20 #include <e32math.h>
       
    21 #include <f32file.h>
       
    22 #include <e32std.h>
       
    23 
       
    24 #include <e32property.h>
       
    25 
       
    26 #include "upnplist.h"
       
    27 
       
    28 #include "upnphttpmessage.h"
       
    29 #include "upnpcommonupnplits.h"
       
    30 #include "upnpcons.h"
       
    31 #include "upnpstring.h"
       
    32 #include "upnpcustomlog.h"
       
    33 #include "upnpmessageobserver.h"
       
    34 
       
    35 const TInt KHeadersMaxSixe = 8192;
       
    36 // ================= MEMBER FUNCTIONS =======================
       
    37 
       
    38 // -----------------------------------------------------------------------------
       
    39 // CUpnpHttpMessage::NewL
       
    40 // Two-phased constructor.
       
    41 // -----------------------------------------------------------------------------
       
    42 //
       
    43 EXPORT_C CUpnpHttpMessage* CUpnpHttpMessage::NewL()
       
    44     {
       
    45     CUpnpHttpMessage* self = new (ELeave) CUpnpHttpMessage();
       
    46     CleanupStack::PushL(self);
       
    47     self->ConstructL();
       
    48     CleanupStack::Pop(self);
       
    49     
       
    50     return self;
       
    51     }
       
    52 
       
    53 // -----------------------------------------------------------------------------
       
    54 // CCHttpMessage::NewL
       
    55 // Two-phased constructor.
       
    56 // -----------------------------------------------------------------------------
       
    57 //
       
    58 EXPORT_C CUpnpHttpMessage* CUpnpHttpMessage::NewL(const TInetAddr& aAddr)
       
    59     {
       
    60     return NewL(aAddr, NewSessionIdL());
       
    61     }
       
    62 
       
    63 // -----------------------------------------------------------------------------
       
    64 // CCHttpMessage::NewL
       
    65 // Two-phased constructor.
       
    66 // -----------------------------------------------------------------------------
       
    67 //
       
    68 EXPORT_C CUpnpHttpMessage* CUpnpHttpMessage::NewL(TInetAddr aAddr, TInt aSessionId)
       
    69     {
       
    70     CUpnpHttpMessage* self = new (ELeave) CUpnpHttpMessage();
       
    71     CleanupStack::PushL(self);
       
    72     
       
    73     
       
    74     self->ConstructL(aAddr, aSessionId);
       
    75     CleanupStack::Pop(self);
       
    76     
       
    77     return self;
       
    78     }
       
    79 
       
    80 // -----------------------------------------------------------------------------
       
    81 // CCHttpMessage::NewL
       
    82 // Two-phased constructor.
       
    83 // -----------------------------------------------------------------------------
       
    84 //
       
    85 EXPORT_C CUpnpHttpMessage* CUpnpHttpMessage::NewL(TDesC8& aMessageBuffer, TInetAddr aSender)
       
    86     {
       
    87     
       
    88     return NewL(aMessageBuffer, aSender, NewSessionIdL());
       
    89     }
       
    90 
       
    91 // -----------------------------------------------------------------------------
       
    92 // CCHttpMessage::NewL
       
    93 // Two-phased constructor.
       
    94 // -----------------------------------------------------------------------------
       
    95 //
       
    96 EXPORT_C CUpnpHttpMessage* CUpnpHttpMessage::NewL(TDesC8& aMessageBuffer, const TInetAddr& aSender, TInt aSessionId)
       
    97     {
       
    98     CUpnpHttpMessage* self = NewL(aSender, aSessionId);
       
    99     CleanupStack::PushL(self);
       
   100     self->ParseL(aMessageBuffer);
       
   101     CleanupStack::Pop();
       
   102 
       
   103     return self;
       
   104     }
       
   105 
       
   106 // -----------------------------------------------------------------------------
       
   107 // CUpnpHttpMessage::~CUpnpHttpMessage
       
   108 // Destructor.
       
   109 // -----------------------------------------------------------------------------
       
   110 //
       
   111 EXPORT_C CUpnpHttpMessage::~CUpnpHttpMessage()
       
   112     {
       
   113     if (iHeaderList)
       
   114         {
       
   115         iHeaderList->DeleteObjects();
       
   116         delete iHeaderList;
       
   117         }
       
   118 
       
   119     if( iTimer )
       
   120         {
       
   121         iTimer->Cancel();
       
   122         delete iTimer;
       
   123         }
       
   124 
       
   125     if ( iOutUri )
       
   126         {
       
   127         delete iOutUri;
       
   128         }
       
   129 
       
   130     delete iDestinationPath;
       
   131 
       
   132 
       
   133     delete iSenderPath;
       
   134 
       
   135 
       
   136     delete iTextBody;
       
   137 
       
   138 
       
   139     delete iOutFilename;
       
   140 
       
   141 
       
   142     delete iInFilename;
       
   143 
       
   144     }
       
   145 
       
   146 // -----------------------------------------------------------------------------
       
   147 // CUpnpHttpMessage::CUpnpHttpMessage
       
   148 // C++ default constructor can NOT contain any code, that
       
   149 // might leave.
       
   150 // -----------------------------------------------------------------------------
       
   151 //
       
   152 EXPORT_C CUpnpHttpMessage::CUpnpHttpMessage()
       
   153     {
       
   154     iSessionPriority = EPriorityNormal;
       
   155     
       
   156     iOverwriteExisting = EFalse;
       
   157     
       
   158     // Parameters connected with downloading range of requested content.
       
   159     // This mechanism if disabled by default an the whole file is requested.
       
   160     iOffset = 0;
       
   161     iLength = 0; 
       
   162     iSaveAtOffset = EFalse;
       
   163     }
       
   164 
       
   165 // -----------------------------------------------------------------------------
       
   166 // CUpnpHttpMessage::ConstructL
       
   167 // Symbian 2nd phase constructor can leave.
       
   168 // -----------------------------------------------------------------------------
       
   169 //
       
   170 EXPORT_C void CUpnpHttpMessage::ConstructL()
       
   171     {
       
   172     iHeaderList = new (ELeave) CUpnpHttpHeaderList;
       
   173 
       
   174     
       
   175     iTextBody = HBufC8::NewL(0);
       
   176 
       
   177     iDestinationPath = HBufC8::NewL(0);
       
   178     iSenderPath = HBufC8::NewL(0);
       
   179 
       
   180     iInFilename = HBufC8::NewL(0);
       
   181     iOutFilename = HBufC8::NewL(0);
       
   182     //by default EFalse, meaning ignored
       
   183     iClientRequest = EFalse;
       
   184     //TCP-session's 0 means the value will be ignored unless changed later on!
       
   185     iTcpTimeout = 0;
       
   186     iInternalError = KErrNone;
       
   187     }
       
   188 
       
   189 // -----------------------------------------------------------------------------
       
   190 // CUpnpHttpMessage::ConstructL
       
   191 // Symbian 2nd phase constructor can leave.
       
   192 // -----------------------------------------------------------------------------
       
   193 //
       
   194 EXPORT_C void CUpnpHttpMessage::ConstructL( TInetAddr& aSender, TInt aSessionId)
       
   195     {
       
   196     iDestinationPath = HBufC8::NewL(0);
       
   197 
       
   198     iSenderPath = HBufC8::NewL(0);
       
   199 
       
   200     iInFilename = HBufC8::NewL(0);
       
   201     
       
   202     iOutFilename = HBufC8::NewL(0);
       
   203     
       
   204     iHeaderList = new (ELeave) CUpnpHttpHeaderList;
       
   205 
       
   206     iTextBody = HBufC8::NewL(0);
       
   207     
       
   208     iRemoteHost = aSender;
       
   209     iSessionId = aSessionId;
       
   210     //by default EFalse, meaning ignored
       
   211     iClientRequest = EFalse;
       
   212     }
       
   213 
       
   214 // -----------------------------------------------------------------------------
       
   215 // CUpnpHttpMessage::ParseL
       
   216 // Parses one row of headers.
       
   217 // -----------------------------------------------------------------------------
       
   218 //
       
   219 EXPORT_C void CUpnpHttpMessage::ParseL(TDesC8& aBuffer)
       
   220     {
       
   221 
       
   222     // position where the header ends
       
   223     TInt endOfHeader=0;
       
   224     
       
   225     // position of first \r\n
       
   226     TInt posOfNextLine = 0;
       
   227     
       
   228     // position of first space
       
   229     TInt posOfFirstSpace = 0;
       
   230 
       
   231     // position of second space
       
   232     TInt posOfSecondSpace = 0;
       
   233 
       
   234     // Boolean value that is used to check if message is
       
   235     // request or response. If message is response, protocol
       
   236     // version information is at the beginning of first row
       
   237     // (HTTP/1.1 200 OK)
       
   238     // In request, protocol version is at the end.
       
   239     // (GET / HTTP/1.1)
       
   240     TBool isResponse = EFalse;
       
   241 
       
   242 // Handling of header part
       
   243     
       
   244     // trying to find Head/body separator
       
   245     endOfHeader = aBuffer.Find(UpnpString::KDoubleLineFeed);
       
   246     if( endOfHeader == KErrNotFound)
       
   247         {
       
   248         User::Leave(KErrAbort);
       
   249         }
       
   250 
       
   251     posOfNextLine = aBuffer.Find(UpnpString::KLineFeed); 
       
   252     if( posOfNextLine != KErrNotFound )
       
   253         {
       
   254         TPtrC8 spacePtr;
       
   255         spacePtr.Set( aBuffer );
       
   256         
       
   257         // finding first space
       
   258         posOfFirstSpace = spacePtr.Find(UpnpString::KSpace);
       
   259         if ( posOfFirstSpace != KErrNotFound )
       
   260             {
       
   261             spacePtr.Set( spacePtr.Left( posOfFirstSpace ) );
       
   262 
       
   263             // if first word of message is HTTP/1.1 or HTTP/1.0
       
   264             // message is response
       
   265             if( ( spacePtr.Find( KHttp11WithoutSpace() ) == 0 && 
       
   266                   posOfFirstSpace == KHttp11WithoutSpace().Length() ) 
       
   267                 ||
       
   268                 ( spacePtr.Find( KHttp10() ) == 0 && 
       
   269                   posOfFirstSpace == KHttp10().Length() ) )
       
   270                 {
       
   271                 isResponse = ETrue;
       
   272                 }
       
   273             else
       
   274                 {
       
   275                 isResponse = EFalse;            
       
   276                 }
       
   277             }
       
   278         else
       
   279             {
       
   280             isResponse = EFalse;            
       
   281             }
       
   282 
       
   283         // back to basic handling
       
   284         spacePtr.Set( aBuffer );
       
   285         
       
   286         if( posOfFirstSpace < posOfNextLine && posOfFirstSpace != KErrNotFound )
       
   287             {
       
   288             // if first space is found, it has to be before linefeed
       
   289             // +1 comes from going over the first space, we are interested
       
   290             // in what comes after it.
       
   291             spacePtr.Set( spacePtr.Mid( posOfFirstSpace  + 1 ) );
       
   292             posOfSecondSpace = spacePtr.Find(UpnpString::KSpace);
       
   293             if( posOfSecondSpace < posOfNextLine && posOfSecondSpace != KErrNotFound )
       
   294                 {
       
   295                 // check that length of path is longer than zero.
       
   296                 if( posOfSecondSpace > 0 )
       
   297                     {
       
   298                     // Now check that Protocol version is HTTP/1.0 
       
   299                     // or HTTP/1.1. 
       
   300                     
       
   301                     // If message is response, version is defined in first 
       
   302                     // parameter of the message. This has been checked before,
       
   303                     // so if response, no check needed.
       
   304                     spacePtr.Set( spacePtr.Mid( posOfSecondSpace+1 ) );
       
   305                     posOfNextLine = spacePtr.FindC( UpnpString::KLineFeed() );
       
   306                     spacePtr.Set( spacePtr.Left( posOfNextLine ) );
       
   307                     
       
   308                     if( !isResponse )
       
   309                         {
       
   310                         //Check protocol's version                        
       
   311                         if (spacePtr.Match( KHttpVersionPattern() ) == 0 )
       
   312                             {    
       
   313                             //get only version numbers    
       
   314                             TPtrC8 version = spacePtr.Mid(5);
       
   315                             TLex8 lex(version);
       
   316                             TUint major;                            
       
   317                             if(lex.Val(major)!= KErrNone || lex.Peek()!='.')
       
   318                                 {
       
   319                                 {
       
   320                                 // (protocol NOT HTTP/1.0 or HTTP/1.1. Invalid message)
       
   321                                 User::Leave(KErrAbort);        
       
   322                                 }
       
   323                                 }
       
   324                             lex.Inc();                                                        
       
   325                             TUint minor;
       
   326                             if (lex.Val(minor) !=KErrNone)
       
   327                                 {
       
   328                                 // (protocol NOT HTTP/1.x. Invalid message)
       
   329                                 User::Leave(KErrAbort);    
       
   330                                 }                                
       
   331                             lex.SkipSpace();
       
   332                             if (!lex.Eos())
       
   333                                 {
       
   334                                 // (protocol NOT HTTP/1.x. Invalid message)
       
   335                                 User::Leave(KErrAbort);    
       
   336                                 }
       
   337                             //only 1.1 and 1.0 supported
       
   338                             if(major != 1 || (minor>1))
       
   339                                 {
       
   340                                 // (HTTP Version not supported)
       
   341                                 User::Leave(-EHttpVersionNotSupported);    
       
   342                                 }
       
   343                             
       
   344                             }
       
   345                         else
       
   346                             {
       
   347                             // (protocol NOT HTTP/1.0 or HTTP/1.1. Invalid message)
       
   348                             User::Leave(KErrAbort);                                
       
   349                             }
       
   350                         }
       
   351         
       
   352                     }
       
   353                 else
       
   354                     {
       
   355                     // header too short. Invalid message
       
   356                     User::Leave(KErrAbort);
       
   357                     }
       
   358                 }
       
   359             else
       
   360                 {
       
   361                 // no second space found. Invalid message.
       
   362                 User::Leave(KErrAbort);
       
   363                 }
       
   364             }
       
   365         else
       
   366             {
       
   367             // no space found before linefeed. Invalid message
       
   368             User::Leave(KErrAbort);
       
   369             }
       
   370         }
       
   371     else
       
   372         {
       
   373         // no linefeed found. Invalid message
       
   374         User::Leave(KErrAbort);
       
   375         }
       
   376 
       
   377     if ( endOfHeader != KErrNotFound )
       
   378         {
       
   379         TPtrC8 tempHeaderPointer;
       
   380         TPtrC8 finderIndexPointer;
       
   381         tempHeaderPointer.Set(aBuffer.Left(endOfHeader));
       
   382         
       
   383         
       
   384         // if header lenght is longer that 8k,cut headers after one that cross the line
       
   385         if (endOfHeader > KHeadersMaxSixe)
       
   386             {
       
   387             TInt afterLimit = tempHeaderPointer.Mid(KHeadersMaxSixe).Find(UpnpString::KLineFeed);
       
   388             if (afterLimit != KErrNotFound)
       
   389                 {
       
   390                 tempHeaderPointer.Set(tempHeaderPointer.Left(KHeadersMaxSixe + afterLimit));
       
   391                 }
       
   392             }    
       
   393         TInt index=0, indexLWS=0, indexCRLF=0;
       
   394         TBool FirstLine=ETrue;
       
   395         
       
   396         while (index != KErrNotFound)
       
   397             {
       
   398             // locate end-of-line, parse each line separately
       
   399         
       
   400             //RFC822 3.2 field-name  =  1*<any CHAR, excluding CTLs, SPACE, and ":">
       
   401             index = tempHeaderPointer.Find(UpnpString::KLineFeed);
       
   402             indexLWS = FindLWS(tempHeaderPointer);
       
   403             finderIndexPointer.Set(tempHeaderPointer);
       
   404             indexCRLF = index;
       
   405             //the length of the string for the end-line marker CRLF
       
   406             TInt headerCRLF = 2;
       
   407             while (indexCRLF == indexLWS && indexCRLF != KErrNotFound)
       
   408             {
       
   409                 //3 below =the length of the LWS string
       
   410                 finderIndexPointer.Set(finderIndexPointer.Right(finderIndexPointer.Length()-(indexCRLF+3)));
       
   411                 indexCRLF = finderIndexPointer.Find(UpnpString::KLineFeed);
       
   412                 if (indexCRLF == KErrNotFound)
       
   413                 {
       
   414                     //3 below =the length of the LWS string
       
   415                     index += finderIndexPointer.Length() + 3; 
       
   416                     indexLWS = finderIndexPointer.Length();
       
   417                     headerCRLF = 0;
       
   418                 }
       
   419                 else
       
   420                 {
       
   421                     index += indexCRLF+3;    
       
   422                     indexLWS = FindLWS(finderIndexPointer);
       
   423                 }
       
   424                 
       
   425                 
       
   426             }
       
   427             if(index != KErrNotFound)
       
   428                 {
       
   429                 TPtrC8 oneHeaderRow;
       
   430                 oneHeaderRow.Set(tempHeaderPointer.Left(index));
       
   431 
       
   432                 // To check if is the first line of message (e.g. GET / HTTP 1.1 etc.)
       
   433                 if (FirstLine)
       
   434                     {
       
   435                     ParseHeaderRowL( (TDesC8&) oneHeaderRow, ETrue);
       
   436                     FirstLine=EFalse;
       
   437                     }
       
   438                 else 
       
   439                     {
       
   440                     ParseHeaderRowL(oneHeaderRow, EFalse);
       
   441                     }
       
   442 
       
   443                 // To delete one header row + "\r\n" = length+2 to prepare for next row.
       
   444                 if (headerCRLF)
       
   445                     {
       
   446                     tempHeaderPointer.Set(tempHeaderPointer.Right(tempHeaderPointer.Length()-(index+headerCRLF)));    
       
   447                     
       
   448                     }
       
   449                     else
       
   450                     {
       
   451                         index = KErrNotFound;
       
   452                     }
       
   453                 }
       
   454             }
       
   455             
       
   456         if (FirstLine)
       
   457             {
       
   458             ParseHeaderRowL(tempHeaderPointer, ETrue);
       
   459             }
       
   460         else
       
   461             {
       
   462             ParseHeaderRowL(tempHeaderPointer, EFalse);
       
   463             }
       
   464         }
       
   465     // check if all HTTP/1 requests have HOST header
       
   466     if(!isResponse && RequestHTTPVersion() == KHttp11WithoutSpace() )
       
   467         {
       
   468         TBool exists;
       
   469         IsHeader(UpnpSSDP::KHdrHost(), exists);
       
   470         if (!exists) 
       
   471             User::Leave(KErrAbort);    
       
   472         }
       
   473     
       
   474     // Handle body:
       
   475     
       
   476     if(iTextBody)
       
   477         {
       
   478         delete iTextBody;
       
   479         iTextBody=NULL;
       
   480         }
       
   481     
       
   482     iTextBody=HBufC8::NewL(aBuffer.Length() - endOfHeader);
       
   483     iTextBody->Des().Zero();
       
   484     
       
   485     // Append rest of message to iTextBody. Leave out string "\r\n\r\n".
       
   486     iTextBody->Des().Append(aBuffer.Right(aBuffer.Length() - (endOfHeader + 4)));
       
   487     }
       
   488 // -----------------------------------------------------------------------------
       
   489 // CUpnpHttpMessage::ParseHeaderRowL
       
   490 // Parses one row of headers.
       
   491 // -----------------------------------------------------------------------------
       
   492 //
       
   493 EXPORT_C TInt CUpnpHttpMessage::FindLWS(const TDesC8& aText)
       
   494 {
       
   495     TInt indexSP = aText.Find(UpnpString::KCRLFSP);
       
   496     TInt indexHT = aText.Find(UpnpString::KCRLFHT);
       
   497     
       
   498     
       
   499     if (indexSP == KErrNotFound) 
       
   500         return indexHT;
       
   501     else if    (indexHT == KErrNotFound) 
       
   502         return indexSP;
       
   503     else if(indexSP < indexHT) 
       
   504         return indexSP;
       
   505     else
       
   506         return indexHT;
       
   507     
       
   508 }
       
   509 
       
   510 // -----------------------------------------------------------------------------
       
   511 // CUpnpHttpMessage::ParseHeaderRowL
       
   512 // Parses one row of headers.
       
   513 // -----------------------------------------------------------------------------
       
   514 //
       
   515 EXPORT_C void CUpnpHttpMessage::ParseHeaderRowL(const TDesC8& aBuffer, TBool aFirstLine)
       
   516     {
       
   517     TInt FirstColonPosition=0;
       
   518 
       
   519     // locate first colon. This separates header's name and value.
       
   520 
       
   521     FirstColonPosition = aBuffer.Find(UpnpString::KColon());
       
   522     if(aFirstLine)
       
   523         {
       
   524         AddPairL(aBuffer, KSpace8());
       
   525         }
       
   526     else
       
   527         {
       
   528         if (FirstColonPosition == KErrNotFound )
       
   529             {
       
   530                 User::Leave(KErrAbort);
       
   531             }
       
   532         else 
       
   533             {    
       
   534             HBufC8* TrimBuffer;
       
   535             TrimBuffer=HBufC8::NewLC(aBuffer.Length() - (FirstColonPosition + 1));
       
   536             TrimBuffer->Des().Zero();
       
   537             
       
   538             TrimBuffer->Des().Append(aBuffer.Right(aBuffer.Length() - (FirstColonPosition + 1)));
       
   539             TrimBuffer->Des().Trim();
       
   540             UnFoldHeader(TrimBuffer);
       
   541 
       
   542             TPtrC8 ptr = aBuffer.Left(FirstColonPosition);
       
   543             
       
   544             // if there are spaces, ignore them.
       
   545             TBool spaceFound = ETrue;
       
   546 
       
   547             while( spaceFound )
       
   548                 {
       
   549                 if(ptr.Find(KSpace()) == 0)
       
   550                     {
       
   551                     ptr.Set(ptr.Mid(1));
       
   552                     }
       
   553                 else
       
   554                     {
       
   555                     spaceFound = EFalse;
       
   556                     }
       
   557                 }
       
   558 
       
   559             AddPairL(ptr, *TrimBuffer);
       
   560             
       
   561             CleanupStack::PopAndDestroy();    
       
   562             }
       
   563         }
       
   564     }
       
   565 
       
   566 // -----------------------------------------------------------------------------
       
   567 // CUpnpHttpMessage::TimerEventL
       
   568 // Timer expired. For SSDP messages
       
   569 // -----------------------------------------------------------------------------
       
   570 //
       
   571 EXPORT_C void CUpnpHttpMessage::TimerEventL( CUpnpNotifyTimer* /*aTimer*/ )
       
   572     {
       
   573     // Cancel timer if exists.
       
   574     if( iTimer )
       
   575         {
       
   576         if( iTimer->IsActive() )
       
   577             {
       
   578             iTimer->Cancel();
       
   579             }
       
   580         }
       
   581     iMessageObserver->MessageExpiredL( this );
       
   582     }
       
   583 
       
   584 // -----------------------------------------------------------------------------
       
   585 // CUpnpHttpMessage::SetMessageTimeoutL
       
   586 // Set message timer timeout for SSDP messages.
       
   587 // -----------------------------------------------------------------------------
       
   588 //   
       
   589 EXPORT_C TInt CUpnpHttpMessage::SetMessageTimeoutL( MUpnpMessageObserver* aObserver, const TInt aTimeoutValue )
       
   590     {
       
   591     // check that request is valid.
       
   592     if( !aObserver )
       
   593         {
       
   594         return KErrNotFound;
       
   595         }
       
   596         
       
   597     iMessageObserver = aObserver;
       
   598 
       
   599     if( iTimer )
       
   600         {
       
   601         if( iTimer->IsActive() )
       
   602             {
       
   603             iTimer->Cancel();
       
   604             }
       
   605         }
       
   606     else
       
   607         {
       
   608         // setup timer;
       
   609         iTimer = CUpnpNotifyTimer::NewL( this );
       
   610         }
       
   611     iTimer->After( aTimeoutValue );
       
   612     return KErrNone;
       
   613     }
       
   614 
       
   615 // -----------------------------------------------------------------------------
       
   616 // CUpnpHttpMessage::CancelMessageTimeout
       
   617 // Set message timer timeout.
       
   618 // -----------------------------------------------------------------------------
       
   619 //   
       
   620 EXPORT_C void CUpnpHttpMessage::CancelMessageTimeout()
       
   621     {
       
   622     if ( iTimer )
       
   623         {
       
   624         iTimer->Cancel();
       
   625         // Deleting timer will also null the observer in the timer.
       
   626         delete iTimer;
       
   627         iTimer = NULL;
       
   628         }
       
   629     }
       
   630     
       
   631 // -----------------------------------------------------------------------------
       
   632 // CUpnpHttpMessage::AddPairL
       
   633 // Adds a Headerrow in this message.
       
   634 // -----------------------------------------------------------------------------
       
   635 //
       
   636 EXPORT_C void CUpnpHttpMessage::AddPairL(const TDesC8& aName, const TDesC8& aValue)
       
   637     {
       
   638     // first checking if given header already exists in the message
       
   639 
       
   640     CUpnpHttpHeader* chk = iHeaderList->First();
       
   641     while( chk != NULL )
       
   642         {
       
   643         if( chk->Name().CompareC( aName ) == 0 )
       
   644             {
       
   645             chk->SetValueL( aValue );
       
   646             // no delete to chk, it is owned by iHeaderList.
       
   647             return;
       
   648             }
       
   649         chk = iHeaderList->Next( chk );
       
   650         }
       
   651     
       
   652     // header name not found, adding it.
       
   653         
       
   654     CUpnpHttpHeader* hdr = CUpnpHttpHeader::NewL(aName, aValue);
       
   655     CleanupStack::PushL(hdr);
       
   656     iHeaderList->AddL(hdr);
       
   657     CleanupStack::Pop(hdr);
       
   658     }
       
   659     
       
   660     
       
   661 // -----------------------------------------------------------------------------
       
   662 // CUpnpHttpMessage::AddPairL
       
   663 // Adds a Headerrow in this message.
       
   664 // -----------------------------------------------------------------------------
       
   665 //
       
   666 EXPORT_C void CUpnpHttpMessage::RemovePairL(const TDesC8& aName)
       
   667     {
       
   668     // first checking if given header already exists in the message
       
   669 
       
   670     CUpnpHttpHeader* chk = iHeaderList->First();
       
   671     while( chk != NULL )
       
   672         {
       
   673         if( chk->Name().CompareC( aName ) == 0 )
       
   674             {
       
   675             // no delete to chk, it is owned by iHeaderList.
       
   676             iHeaderList->Remove(chk);
       
   677             delete chk;
       
   678             return;
       
   679             }
       
   680         chk = iHeaderList->Next( chk );
       
   681         }
       
   682     
       
   683     }
       
   684 
       
   685     
       
   686 
       
   687 // -----------------------------------------------------------------------------
       
   688 // CUpnpHttpMessage::SetBodyL
       
   689 // Sets the body of message.
       
   690 // -----------------------------------------------------------------------------
       
   691 //
       
   692 EXPORT_C void CUpnpHttpMessage::SetBodyL(const TDesC8& aBody)
       
   693     {
       
   694     delete iTextBody;
       
   695     iTextBody = NULL;
       
   696     iTextBody = aBody.AllocL();
       
   697     }
       
   698 
       
   699 // -----------------------------------------------------------------------------
       
   700 // CUpnpHttpMessage::Body
       
   701 // Getter for the body of message.
       
   702 // -----------------------------------------------------------------------------
       
   703 //
       
   704 EXPORT_C TDesC8& CUpnpHttpMessage::Body()
       
   705     {
       
   706     return *iTextBody;
       
   707     }
       
   708 
       
   709 // -----------------------------------------------------------------------------
       
   710 // CUpnpHttpMessage::HeadersToStringL
       
   711 // Returns message as HBufC8.
       
   712 // -----------------------------------------------------------------------------
       
   713 //
       
   714 EXPORT_C HBufC8* CUpnpHttpMessage::HeadersToStringL()
       
   715     {
       
   716     CUpnpHttpHeader* hdr = iHeaderList->First();
       
   717 
       
   718     HBufC8* headerBuf = NULL;
       
   719     headerBuf = HBufC8::NewL(0);
       
   720     headerBuf->Des().SetLength(0);
       
   721     TBool firstLine = ETrue;
       
   722     
       
   723     while (hdr != NULL)
       
   724         {
       
   725         CleanupStack::PushL( headerBuf );
       
   726         
       
   727         HBufC8* tempHeader = NULL;
       
   728     
       
   729         tempHeader=HBufC8::NewLC( hdr->Name().Length() +
       
   730                                     hdr->Value().Length() +
       
   731                                     4 ); // 4 for colon, space and linefeed
       
   732         tempHeader->Des().Zero();        
       
   733         tempHeader->Des().Append(hdr->Name());
       
   734 
       
   735 
       
   736         //first line is Request line (Request-Line   = Method SP Request-URI SP HTTP-Version CRLF)
       
   737         //block is needed for URI manipualtion, first line is ALSO added
       
   738         //-- can not be folded, DLNA says directly "Each HTTP header line"
       
   739 
       
   740 
       
   741         TInt posOfSpace = tempHeader->Des().Find(UpnpString::KSpace());
       
   742             TPtrC8 ptr;
       
   743             if (posOfSpace != KErrNotFound)
       
   744                 {
       
   745                 ptr.Set( 
       
   746                 tempHeader->Des().Right( tempHeader->Des().Length() - 
       
   747                                             (posOfSpace + 1)  )
       
   748                     );
       
   749                 }
       
   750             
       
   751             TInt posOfSecondSpace = ptr.Find( UpnpString::KSpace() );
       
   752             TPtrC8 ptr2;
       
   753             
       
   754             if (posOfSecondSpace != KErrNotFound)            
       
   755                 ptr2.Set( ptr.Left( posOfSecondSpace ) );
       
   756 
       
   757             HBufC8* url = ptr2.AllocLC();
       
   758 
       
   759             
       
   760         tempHeader->Des().Replace( posOfSpace+1,
       
   761                                           url->Des().Length(),
       
   762                                           *url );
       
   763 
       
   764             CleanupStack::PopAndDestroy( url );
       
   765             url = NULL;
       
   766             
       
   767 /*------if Content-Length is not at the beginning (can be some same string in value) so copy it, otherwise will be added and calcualted at the end----*/
       
   768 
       
   769         if(hdr->Name().FindC(UpnpHTTP::KHdrContentLength()) != 0)
       
   770 
       
   771             {
       
   772             if (hdr->Value().Length() > 0 && !firstLine)
       
   773                 {
       
   774                 tempHeader->Des().Append(UpnpString::KColon());
       
   775                 tempHeader->Des().Append(UpnpString::KSpace());
       
   776                 tempHeader->Des().Append(hdr->Value());
       
   777                 }
       
   778             else 
       
   779                 {
       
   780                 if (firstLine)
       
   781                     {
       
   782                     firstLine = EFalse;
       
   783                     }
       
   784                 else
       
   785                     {
       
   786                     tempHeader->Des().Append(UpnpString::KColon());
       
   787                     }
       
   788                 }
       
   789             //folding, we pass with lineFeed
       
   790             FoldHeaderL(tempHeader);                
       
   791             tempHeader->Des().Append(UpnpString::KLineFeed());
       
   792             }
       
   793 
       
   794         HBufC8* tempBuf;
       
   795         tempBuf = HBufC8::NewLC( headerBuf->Des().Length() +
       
   796                                  tempHeader->Des().Length() );
       
   797         tempBuf->Des().Zero();
       
   798         tempBuf->Des().Append( *headerBuf );
       
   799         
       
   800 
       
   801         if(hdr->Name().FindC(UpnpHTTP::KHdrContentLength()) != 0)
       
   802             {
       
   803             tempBuf->Des().Append(*tempHeader);
       
   804             }
       
   805         
       
   806         CleanupStack::Pop( tempBuf );
       
   807         CleanupStack::PopAndDestroy( tempHeader ); 
       
   808         CleanupStack::PopAndDestroy( headerBuf ); 
       
   809         
       
   810         tempHeader = NULL;
       
   811         headerBuf = NULL;
       
   812 
       
   813         headerBuf = tempBuf;
       
   814         tempBuf = NULL;
       
   815         
       
   816         hdr = iHeaderList->Next(hdr);    
       
   817         }
       
   818     
       
   819     AppendContentLengthToHeadersL(headerBuf);
       
   820     return headerBuf;
       
   821 }
       
   822 // -----------------------------------------------------------------------------
       
   823 // CUpnpHttpMessage::AppendContentLengthToHeadersL
       
   824 // Appends ContentLength when headers are dumped to string (using public method HeadersToStringL).
       
   825 // -----------------------------------------------------------------------------
       
   826 //
       
   827 EXPORT_C void CUpnpHttpMessage::AppendContentLengthToHeadersL(HBufC8*& aHeaders){
       
   828 
       
   829 /*------open file which keep message--------*/
       
   830     TInt bodyLength( 0 );
       
   831     CleanupStack::PushL( aHeaders );    
       
   832 
       
   833 
       
   834     if(iOutFilename->Length() > 0)
       
   835         {
       
   836         RFs fs;
       
   837         CleanupClosePushL(fs);
       
   838         RFile file;
       
   839         CleanupClosePushL(file);
       
   840 
       
   841         User::LeaveIfError( fs.Connect() );
       
   842         
       
   843         HBufC16* outFilename16 = UpnpString::ToUnicodeL( *iOutFilename);
       
   844         CleanupStack::PushL(outFilename16);
       
   845         
       
   846         User::LeaveIfError( file.Open(fs,*outFilename16,  EFileRead|EFileShareAny ) );
       
   847 
       
   848         TInt Filesize( 0 );
       
   849         User::LeaveIfError( file.Size( Filesize ) );
       
   850         
       
   851         CleanupStack::PopAndDestroy( outFilename16 );
       
   852         
       
   853         CleanupStack::PopAndDestroy();  //file.Close();
       
   854         outFilename16 = NULL;
       
   855         
       
   856         CleanupStack::PopAndDestroy(); //fs.Close();
       
   857                 
       
   858         bodyLength = Filesize;
       
   859         }
       
   860     else
       
   861         {
       
   862         iTextBody->Des().Trim();
       
   863         bodyLength=iTextBody->Des().Length();
       
   864         }
       
   865 
       
   866     TBuf8<20> tempBuf;
       
   867     tempBuf.Num( bodyLength );
       
   868 
       
   869     HBufC8* tempBuf2;
       
   870     tempBuf2=HBufC8::NewL( aHeaders->Des().Length() +
       
   871                             tempBuf.Length() +
       
   872                             UpnpHTTP::KHdrContentLength().Length() +
       
   873                             2 ); // +2 from colon and space
       
   874     tempBuf2->Des().Append( *aHeaders);
       
   875     
       
   876     CleanupStack::Pop(aHeaders);
       
   877     delete aHeaders;
       
   878     aHeaders=NULL;
       
   879 
       
   880     tempBuf2->Des().Append(UpnpHTTP::KHdrContentLength());
       
   881     tempBuf2->Des().Append(UpnpString::KColon());
       
   882     tempBuf2->Des().Append(UpnpString::KSpace());
       
   883     tempBuf2->Des().Append(tempBuf);
       
   884 
       
   885     aHeaders=tempBuf2;
       
   886     tempBuf2=NULL;
       
   887 
       
   888     }
       
   889 // -----------------------------------------------------------------------------
       
   890 // CUpnpHttpMessage::FoldHeaderL
       
   891 // Folds long header fields (without last CRLF)  - "MUST limit 998".
       
   892 // -----------------------------------------------------------------------------
       
   893 //
       
   894 EXPORT_C void CUpnpHttpMessage::FoldHeaderL(HBufC8*& aHeader){
       
   895 HBufC8* result = NULL;
       
   896 TInt length = aHeader->Length();
       
   897 
       
   898     if(length > KLineLengthLimit)
       
   899         {
       
   900         //Body can be only folded, so 1st we check if name is not too long
       
   901         if (aHeader->FindC(UpnpString::KColon()) > KLineLengthLimit-1)
       
   902             {
       
   903             User::Leave(KErrOverflow);
       
   904             #ifdef _DEBUG
       
   905             LOGS("[CUpnpHttpMessage::FoldHeaderL] name of header > KLineLengthLimit");
       
   906             #endif //_DEBUG
       
   907             }
       
   908         else
       
   909             {
       
   910             //RFC 2822 3.2.3 (check if any FWS already exist and remove them) comment in DLNA doesnt exist so there are not processing)
       
   911             UnFoldHeader(aHeader);
       
   912             aHeader->Des().TrimAll();
       
   913 
       
   914             //now proper folding
       
   915             //new length is estimated,
       
   916             //its faster way to estiamte max number (worst possible case) than calculate strict number
       
   917             //how estimation is calculate: HighLevel break (but not SP) in worst case will be in every half -1 in every maxLength string
       
   918             
       
   919             
       
   920             result = HBufC8::NewL(length + length/KLineLengthLimit*2*3 + 2);//CRLFSP + LineFeed
       
   921             CleanupStack::PushL(result);
       
   922             TInt x1 = 0, x2 = 0;
       
   923             TBool last = EFalse;
       
   924             while(ETrue)
       
   925                 {
       
   926                 length = aHeader->Length();
       
   927                 x2 = x1 + KLineLengthLimit;
       
   928                 if (x2 >= length) 
       
   929                     {
       
   930                     x2 = length-1;
       
   931                     last = ETrue;
       
   932                     }
       
   933                 else
       
   934                     {
       
   935                     TBool foundBreak = EFalse;
       
   936                     for (TInt j=0; j<KHigherLevelSintaticBreaks().Length(); j++)
       
   937                         {
       
   938                         x2 = x1 + KLineLengthLimit;
       
   939                         while (x2 > 0 && !foundBreak)
       
   940                             {
       
   941                             if (aHeader->Des()[x2] == KHigherLevelSintaticBreaks()[j])
       
   942                                 {
       
   943                                 foundBreak = ETrue;
       
   944                                 }
       
   945                             else
       
   946                                 {
       
   947                                 x2--;
       
   948                                 }
       
   949                                 
       
   950                             }
       
   951                         if (foundBreak) break;
       
   952                         }
       
   953                     if (!foundBreak)
       
   954                         {
       
   955                         User::Leave(KErrOverflow);
       
   956                         #ifdef _DEBUG
       
   957                         LOGS("[CUpnpHttpMessage::FoldHeaderL] value of header > KLineLengthLimit");
       
   958                         #endif //_DEBUG
       
   959                         }
       
   960                     }
       
   961                 //we will append in different way whether SP or other breaks
       
   962                 if (aHeader->Des()[x2] == UpnpString::KSpace()[0] || 
       
   963                     aHeader->Des()[x2] == UpnpString::KTab()[0])
       
   964                     {
       
   965                     result->Des().Append(aHeader->Des().Mid(x1, x2));
       
   966                     if (!last)
       
   967                         {
       
   968                         result->Des().Append(UpnpString::KLineFeed());
       
   969                         }
       
   970                     }
       
   971                 else
       
   972                     {
       
   973                     result->Des().Append(aHeader->Des().Mid(x1, x2+1));
       
   974                     if (!last)
       
   975                         {
       
   976                         result->Des().Append(UpnpString::KLineFeed());
       
   977                         result->Des().Append(UpnpString::KSpace());//additional space, HTTP req, also break reversibility (folding and unfolding will give new string)
       
   978                         }
       
   979                     }
       
   980                 aHeader->Des().Delete(x1, x2-x1);// from, length
       
   981                 if (last)
       
   982                     {
       
   983                     break;
       
   984                     }
       
   985                 
       
   986                 }
       
   987             CleanupStack::Pop(result);
       
   988             CleanupStack::PopAndDestroy(aHeader);
       
   989             aHeader = result;
       
   990             CleanupStack::PushL(aHeader);
       
   991             }
       
   992         }
       
   993     
       
   994  
       
   995 }
       
   996 // -----------------------------------------------------------------------------
       
   997 // CUpnpHttpMessage::ToStringL
       
   998 // Unfolds header by simply removing any CRLF that is immediately followed by WSP.
       
   999 // -----------------------------------------------------------------------------
       
  1000 //
       
  1001 EXPORT_C void CUpnpHttpMessage::UnFoldHeader(HBufC8*& aHeader){
       
  1002     TPtr8 ptr = aHeader->Des();
       
  1003     TInt pos = ptr.FindC(UpnpString::KLineFeed());
       
  1004     while(pos != KErrNotFound)
       
  1005     {
       
  1006         ptr.Delete(pos, 2);
       
  1007         pos = ptr.FindC(UpnpString::KLineFeed());
       
  1008     }
       
  1009 }
       
  1010 
       
  1011 // -----------------------------------------------------------------------------
       
  1012 // CUpnpHttpMessage::ToStringL
       
  1013 // Returns message as HBufC8.
       
  1014 // -----------------------------------------------------------------------------
       
  1015 //
       
  1016 EXPORT_C HBufC8* CUpnpHttpMessage::ToStringL()
       
  1017     {
       
  1018     HBufC8* buffer;
       
  1019     buffer=HeadersToStringL();
       
  1020     CleanupStack::PushL(buffer);
       
  1021 
       
  1022     HBufC8* returnBuf;
       
  1023     //4 added to the length of the buffer becasue of the additional 2 line feeds
       
  1024     returnBuf=HBufC8::NewL(buffer->Des().Length()+iTextBody->Des().Length()+4);
       
  1025     
       
  1026     returnBuf->Des().Append(*buffer);
       
  1027     CleanupStack::PopAndDestroy(buffer);
       
  1028     buffer=NULL;
       
  1029     //2 line feeds appended
       
  1030     returnBuf->Des().Append(UpnpString::KLineFeed);
       
  1031     returnBuf->Des().Append(UpnpString::KLineFeed);
       
  1032     
       
  1033     returnBuf->Des().Append(*iTextBody);
       
  1034     
       
  1035     return returnBuf;
       
  1036     }
       
  1037 
       
  1038 // -----------------------------------------------------------------------------
       
  1039 // CUpnpHttpMessage::SetMessageDateL
       
  1040 // Sets the date of message.
       
  1041 // -----------------------------------------------------------------------------
       
  1042 //
       
  1043 
       
  1044 EXPORT_C void CUpnpHttpMessage::SetMessageDateL(const TTime& aTime)
       
  1045 {   
       
  1046     HBufC8* timebuf = NULL;
       
  1047     timebuf = UpnpString::GetDateLC(aTime);
       
  1048     
       
  1049     CUpnpHttpHeader* hdr = iHeaderList->First();
       
  1050     
       
  1051     TBool HeaderFound=EFalse;
       
  1052     
       
  1053     while (hdr != NULL)
       
  1054         {
       
  1055         if (hdr->Name() == UpnpHTTP::KHdrDate() )
       
  1056             {
       
  1057             HeaderFound = ETrue;
       
  1058             hdr->SetValueL(*timebuf);
       
  1059             }
       
  1060         hdr = iHeaderList->Next(hdr);    
       
  1061         }
       
  1062     
       
  1063     if(!HeaderFound)
       
  1064         {
       
  1065         AddPairL(UpnpHTTP::KHdrDate(),*timebuf);
       
  1066         }
       
  1067     CleanupStack::PopAndDestroy(timebuf);
       
  1068 }
       
  1069 
       
  1070 // -----------------------------------------------------------------------------
       
  1071 // CUpnpHttpMessage::Sender
       
  1072 // Returns the IP address of the sender of the message.
       
  1073 // -----------------------------------------------------------------------------
       
  1074 //
       
  1075 EXPORT_C TInetAddr& CUpnpHttpMessage::Sender()
       
  1076     {
       
  1077     return iRemoteHost;
       
  1078     }
       
  1079 
       
  1080 // -----------------------------------------------------------------------------
       
  1081 // CUpnpHttpMessage::Receiver
       
  1082 // Returns the IP address of the receiver of the message.
       
  1083 // -----------------------------------------------------------------------------
       
  1084 //
       
  1085 EXPORT_C TInetAddr& CUpnpHttpMessage::Receiver()
       
  1086     {
       
  1087     return iRemoteHost;
       
  1088     }
       
  1089 
       
  1090 // -----------------------------------------------------------------------------
       
  1091 // CUpnpHttpMessage::SetDestinationPathL
       
  1092 // Sets the DestinationPath of the message.
       
  1093 // -----------------------------------------------------------------------------
       
  1094 //
       
  1095 EXPORT_C void CUpnpHttpMessage::SetDestinationPathL(const TDesC8& aDestinationPath)
       
  1096     {
       
  1097     if(iDestinationPath)
       
  1098         {
       
  1099         delete iDestinationPath;
       
  1100         iDestinationPath = NULL;
       
  1101         }
       
  1102         
       
  1103     iDestinationPath = aDestinationPath.AllocL();
       
  1104     }
       
  1105 
       
  1106 // -----------------------------------------------------------------------------
       
  1107 // CUpnpHttpMessage::DestinationPath
       
  1108 // Returns the DestinationPath of the message.
       
  1109 // -----------------------------------------------------------------------------
       
  1110 //
       
  1111 EXPORT_C TPtrC8 CUpnpHttpMessage::DestinationPath()
       
  1112     {
       
  1113     if(iDestinationPath->Length()>0)
       
  1114         {
       
  1115         return iDestinationPath->Des();
       
  1116         }
       
  1117     else
       
  1118         {
       
  1119         return (TDesC8&) KNullDesC8();
       
  1120         }
       
  1121     }
       
  1122 
       
  1123 // -----------------------------------------------------------------------------
       
  1124 // CUpnpHttpMessage::SetSenderPathL
       
  1125 // Sets the SourcePath of the message.
       
  1126 // -----------------------------------------------------------------------------
       
  1127 //
       
  1128 EXPORT_C void CUpnpHttpMessage::SetSenderPathL(const TDesC8& aSenderPath)
       
  1129     {
       
  1130     if(iSenderPath)
       
  1131         {
       
  1132         delete iSenderPath;
       
  1133         iSenderPath = NULL;
       
  1134         }
       
  1135         
       
  1136     iSenderPath = aSenderPath.AllocL();
       
  1137     }
       
  1138 
       
  1139 // -----------------------------------------------------------------------------
       
  1140 // CUpnpHttpMessage::SenderPath
       
  1141 // Returns the SenderPath of the message.
       
  1142 // -----------------------------------------------------------------------------
       
  1143 //
       
  1144 EXPORT_C TPtrC8 CUpnpHttpMessage::SenderPath()
       
  1145     {
       
  1146     if(iSenderPath->Length()>0)
       
  1147         {
       
  1148         return iSenderPath->Des();
       
  1149         }
       
  1150     else
       
  1151         {
       
  1152         return (TDesC8&) KNullDesC8();
       
  1153         }
       
  1154     }
       
  1155 
       
  1156 // -----------------------------------------------------------------------------
       
  1157 // CUpnpHttpMessage::SenderPathFromHeader
       
  1158 // Returns the SenderPath from Headers.
       
  1159 // -----------------------------------------------------------------------------
       
  1160 //
       
  1161 EXPORT_C const TPtrC8 CUpnpHttpMessage::SenderPathFromHeader()
       
  1162     {
       
  1163     CUpnpHttpHeader* hdr = iHeaderList->First();
       
  1164 
       
  1165     if (hdr != NULL)
       
  1166         {
       
  1167         TInt FirstSpacePosition=hdr->Name().Find(KSpace);
       
  1168             
       
  1169         if (FirstSpacePosition != KErrNotFound)
       
  1170             {
       
  1171             TPtrC8 tempPtr;
       
  1172             tempPtr.Set(hdr->Name().Right(hdr->Name().Length() - (FirstSpacePosition + 1)));
       
  1173             TInt SecondSpacePosition=tempPtr.Find(UpnpString::KSpace());
       
  1174             if (SecondSpacePosition != KErrNotFound)
       
  1175                 {
       
  1176                 TPtrC8 tempPtr2;
       
  1177                 tempPtr2.Set(tempPtr.Left(SecondSpacePosition));
       
  1178                 return tempPtr2;
       
  1179                 }
       
  1180             else
       
  1181                 return TPtrC8((unsigned char*)"", 0);
       
  1182     
       
  1183             }
       
  1184         else
       
  1185             return TPtrC8((unsigned char*)"", 0);
       
  1186         
       
  1187         }
       
  1188 
       
  1189     return TPtrC8((unsigned char*)"", 0);
       
  1190     }
       
  1191 
       
  1192 // -----------------------------------------------------------------------------
       
  1193 // CUpnpHttpMessage::SetPendingRequest
       
  1194 // Sets the private member iPendingRequest.
       
  1195 // -----------------------------------------------------------------------------
       
  1196 //
       
  1197 EXPORT_C void CUpnpHttpMessage::SetPendingRequest(TAny* aPointer)
       
  1198     {
       
  1199     iPendingRequest=aPointer;
       
  1200     }
       
  1201 
       
  1202 // -----------------------------------------------------------------------------
       
  1203 // CUpnpHttpMessage::PendingRequest
       
  1204 // Returns iPendingRequest pointer.
       
  1205 // -----------------------------------------------------------------------------
       
  1206 //
       
  1207 EXPORT_C TAny* CUpnpHttpMessage::PendingRequest()
       
  1208     {
       
  1209     return iPendingRequest;
       
  1210     }
       
  1211 
       
  1212 // -----------------------------------------------------------------------------
       
  1213 // CUpnpHttpMessage::SetInFilenameL
       
  1214 // Sets the filename where to save incoming content.
       
  1215 // -----------------------------------------------------------------------------
       
  1216 //
       
  1217 EXPORT_C void CUpnpHttpMessage::SetInFilenameL(const TDesC8& aFilename, TBool aOverwriteExisting)
       
  1218     {
       
  1219     if ( iInFilename )
       
  1220         {
       
  1221         delete iInFilename;
       
  1222         iInFilename = NULL;
       
  1223         }
       
  1224     
       
  1225     iInFilename=HBufC8::NewL(aFilename.Length());
       
  1226     iInFilename->Des().Zero();
       
  1227     iInFilename->Des().Append(aFilename);    
       
  1228 
       
  1229     iOverwriteExisting  = aOverwriteExisting;
       
  1230     }
       
  1231 
       
  1232 // -----------------------------------------------------------------------------
       
  1233 // CUpnpHttpMessage::InFilename
       
  1234 // Returns the name of file where to save incoming content.
       
  1235 // -----------------------------------------------------------------------------
       
  1236 //
       
  1237 EXPORT_C TPtrC8 CUpnpHttpMessage::InFilename()
       
  1238     {
       
  1239     if(iInFilename->Length()>0)
       
  1240         {
       
  1241         return iInFilename->Des();
       
  1242         }
       
  1243     else
       
  1244         {
       
  1245         return (TDesC8&) KNullDesC8();
       
  1246         }
       
  1247     }
       
  1248 
       
  1249 
       
  1250 // -----------------------------------------------------------------------------
       
  1251 // CUpnpHttpMessage::OverwriteExisting
       
  1252 // Returns if the existing file should be overwritten with the requested content.
       
  1253 // If not then the new file with name: aFilename_serialNumber will be created.
       
  1254 // -----------------------------------------------------------------------------
       
  1255 //
       
  1256 EXPORT_C TBool CUpnpHttpMessage::OverwriteExisting()
       
  1257     {
       
  1258     return iOverwriteExisting;        
       
  1259     }
       
  1260 
       
  1261 // -----------------------------------------------------------------------------
       
  1262 // CUpnpHttpMessage::SetRangeL
       
  1263 // Sets the range of remote filename which will be requested.
       
  1264 // -----------------------------------------------------------------------------
       
  1265 //
       
  1266 EXPORT_C void CUpnpHttpMessage::SetRangeL(TInt aOffset, TInt aLength, TBool aSaveAtOffset)
       
  1267     {
       
  1268     iOffset = aOffset;
       
  1269     iLength = aLength;
       
  1270     iSaveAtOffset = aSaveAtOffset;    
       
  1271 
       
  1272     
       
  1273     TPtrC8 method = Method();
       
  1274     // Check method, because sending POST with range is not supported.
       
  1275     if( method.Find( KHttpGet ) == 0 || method.Find( KHttpHead ) == 0)
       
  1276         {
       
  1277         // If one of those values are different from default then it means that 
       
  1278         // the Range header should be added.
       
  1279         if( iOffset != 0 || iLength != 0 ) 
       
  1280             {
       
  1281             TBuf8<KMaxIntegerLength> num;
       
  1282             HBufC8* rangeValue = HBufC8::NewLC(    UpnpHTTP::KBytes().Length() +
       
  1283                                                 UpnpString::KEqual().Length() +
       
  1284                                                 KMaxIntegerLength + 
       
  1285                                                    UpnpString::KMinus().Length() +
       
  1286                                                    KMaxIntegerLength );
       
  1287             rangeValue->Des().Zero();
       
  1288             
       
  1289             rangeValue->Des().Append( UpnpHTTP::KBytes() );
       
  1290             rangeValue->Des().Append( UpnpString::KEqual() );
       
  1291             
       
  1292             num.Num( iOffset );
       
  1293             rangeValue->Des().Append( num );
       
  1294             rangeValue->Des().Append( UpnpString::KMinus() );
       
  1295             
       
  1296             // If length == 0 and offset is specified then it should looks: offset-
       
  1297             if( iLength )
       
  1298                 {
       
  1299                 // In the Range header the second value specyfies last byte position
       
  1300                 // so there must be done simple transformation last-byte-pos = offset+lenght-1.
       
  1301                 // There is 1 subtracted because we inlucde the byte indicated by offset
       
  1302                 TInt lastBytePos = iOffset + iLength - 1; 
       
  1303                 num.Num( lastBytePos );
       
  1304                 rangeValue->Des().Append( num );
       
  1305                 }
       
  1306             
       
  1307             AddPairL( UpnpHTTP::KHdrRange(), *rangeValue );
       
  1308                                                
       
  1309             CleanupStack::PopAndDestroy( rangeValue );
       
  1310             }
       
  1311         else if( iOffset == 0 && iLength == 0 && !iSaveAtOffset ) 
       
  1312             {
       
  1313             // Set values indicate that there should be no Range header, so remove it.
       
  1314             CUpnpHttpHeader* hdr = iHeaderList->First();
       
  1315     
       
  1316             while ( hdr != NULL )
       
  1317                 {
       
  1318                 if( hdr->Name().Length() == UpnpHTTP::KHdrRange().Length() )
       
  1319                     {
       
  1320                     if (hdr->Name().FindC( UpnpHTTP::KHdrRange() ) == 0)
       
  1321                         {
       
  1322                         // Header was found so remove it and exit function.
       
  1323                         iHeaderList->Remove( hdr );
       
  1324                         delete hdr;
       
  1325                         return;
       
  1326                         }
       
  1327                     }
       
  1328                 hdr = iHeaderList->Next( hdr );
       
  1329                 }
       
  1330             }
       
  1331         }
       
  1332     else
       
  1333         {
       
  1334         User::Leave( KErrGeneral );
       
  1335         }
       
  1336     }
       
  1337     
       
  1338 // -----------------------------------------------------------------------------
       
  1339 // CUpnpHttpMessage::Offset
       
  1340 // Returns the offset of the file that should be requested from server.
       
  1341 // -----------------------------------------------------------------------------
       
  1342 //
       
  1343 EXPORT_C TInt CUpnpHttpMessage::Offset()
       
  1344     {
       
  1345     return iOffset;    
       
  1346     }
       
  1347 
       
  1348 // -----------------------------------------------------------------------------
       
  1349 // CUpnpHttpMessage::Length
       
  1350 // Returns the length of file content to be requested.
       
  1351 // -----------------------------------------------------------------------------
       
  1352 //
       
  1353 EXPORT_C TInt CUpnpHttpMessage::Length()
       
  1354     {
       
  1355     return iLength;        
       
  1356     }
       
  1357 
       
  1358 // -----------------------------------------------------------------------------
       
  1359 // CUpnpHttpMessage::InFilename
       
  1360 // Return if the requested offset of the remote file should be saved at physical offset of
       
  1361 // the local file.
       
  1362 // -----------------------------------------------------------------------------
       
  1363 //
       
  1364 EXPORT_C TBool CUpnpHttpMessage::SaveAtOffset()
       
  1365     {
       
  1366     return iSaveAtOffset;        
       
  1367     }
       
  1368     
       
  1369 // -----------------------------------------------------------------------------
       
  1370 // CUpnpHttpMessage::SetOutFilenameL
       
  1371 // Sets the filename which will be used as message body.
       
  1372 // -----------------------------------------------------------------------------
       
  1373 //
       
  1374 EXPORT_C void CUpnpHttpMessage::SetOutFilenameL(const TDesC8& aFilename)
       
  1375     {
       
  1376 
       
  1377     if(iOutFilename)
       
  1378         {
       
  1379         delete iOutFilename;
       
  1380         iOutFilename=NULL;
       
  1381         }
       
  1382     
       
  1383     iOutFilename=HBufC8::NewL(aFilename.Length());
       
  1384     iOutFilename->Des().Zero();
       
  1385     iOutFilename->Des().Append(aFilename);    
       
  1386     }
       
  1387 
       
  1388 // -----------------------------------------------------------------------------
       
  1389 // CUpnpHttpMessage::OutFilename
       
  1390 // Returns the name of file which will be set as body of message to send.
       
  1391 // -----------------------------------------------------------------------------
       
  1392 //
       
  1393 EXPORT_C TPtrC8 CUpnpHttpMessage::OutFilename()
       
  1394     {
       
  1395     if(iOutFilename->Length()>0)
       
  1396         {
       
  1397         return iOutFilename->Des();
       
  1398         }
       
  1399     else
       
  1400         {
       
  1401         return (TDesC8&) KNullDesC8();
       
  1402         }
       
  1403     }
       
  1404 
       
  1405 // -----------------------------------------------------------------------------
       
  1406 // CUpnpHttpMessage::GetHeaderValue
       
  1407 // Returns value of the header.
       
  1408 // -----------------------------------------------------------------------------
       
  1409 //
       
  1410 EXPORT_C TDesC8& CUpnpHttpMessage::GetHeaderValue(const TDesC8& aHeaderName)
       
  1411     {
       
  1412     CUpnpHttpHeader* hdr = iHeaderList->First();
       
  1413     
       
  1414     while (hdr != NULL)
       
  1415         {
       
  1416         if(hdr->Name().Length() == aHeaderName.Length())
       
  1417             {
       
  1418             if (hdr->Name().FindC(aHeaderName) == 0)
       
  1419                 {
       
  1420                 return hdr->Value();
       
  1421                 }
       
  1422             }
       
  1423         hdr = iHeaderList->Next(hdr);
       
  1424         }
       
  1425     
       
  1426     return (TDesC8&) KNullDesC8();
       
  1427     }
       
  1428 
       
  1429 // -----------------------------------------------------------------------------
       
  1430 //    Check if header exists, also return value of header if exists
       
  1431 //    @param aHeaderName Name of the header.
       
  1432 //    @param aExist True if header exist, false if not.
       
  1433 //    @result Value of the header (if exist, otherwise KNullDesC).
       
  1434 // -----------------------------------------------------------------------------
       
  1435 
       
  1436 EXPORT_C TDesC8& CUpnpHttpMessage::IsHeader(const TDesC8& aHeaderName, TBool& aExist)
       
  1437 { 
       
  1438     CUpnpHttpHeader* hdr = iHeaderList->First();
       
  1439     aExist = EFalse;
       
  1440     while (hdr != NULL)
       
  1441         {
       
  1442         if(hdr->Name().Length() == aHeaderName.Length())
       
  1443             {
       
  1444             if (hdr->Name().FindC(aHeaderName) == 0)
       
  1445                 {
       
  1446                 aExist = ETrue;
       
  1447                 return hdr->Value();
       
  1448                 }
       
  1449             }
       
  1450         hdr = iHeaderList->Next(hdr);
       
  1451         }
       
  1452     return ( TDesC8& )KNullDesC8();
       
  1453 }
       
  1454 
       
  1455 
       
  1456 // -----------------------------------------------------------------------------
       
  1457 // CUpnpHttpMessage::SetSessionId
       
  1458 // Sets messages Session id.
       
  1459 // -----------------------------------------------------------------------------
       
  1460 //
       
  1461 EXPORT_C void CUpnpHttpMessage::SetSessionId(TInt aId)
       
  1462     {
       
  1463     iSessionId = aId;
       
  1464     }
       
  1465 
       
  1466 // -----------------------------------------------------------------------------
       
  1467 // CUpnpHttpMessage::SessionId
       
  1468 // Returns the SessionId of the message.
       
  1469 // -----------------------------------------------------------------------------
       
  1470 //
       
  1471 EXPORT_C TInt CUpnpHttpMessage::SessionId() const
       
  1472     {
       
  1473     return iSessionId;
       
  1474     }
       
  1475 
       
  1476 // -----------------------------------------------------------------------------
       
  1477 // CUpnpHttpMessage::NewSessionIdL
       
  1478 // Creates new, unused Session id value.
       
  1479 // -----------------------------------------------------------------------------
       
  1480 //
       
  1481 EXPORT_C TInt CUpnpHttpMessage::NewSessionIdL()
       
  1482     {
       
  1483     TInt id;
       
  1484     TInt r;
       
  1485     TBool newID=EFalse;
       
  1486 
       
  1487     RSemaphore accessSemaphore;        
       
  1488     
       
  1489     r=accessSemaphore.OpenGlobal(KSessionIdAccessSemaphoreName());
       
  1490     //if failed to open
       
  1491     if(r!=KErrNone)
       
  1492         {
       
  1493         User::LeaveIfError (accessSemaphore.CreateGlobal(KSessionIdAccessSemaphoreName(), 0) );
       
  1494         accessSemaphore.Signal();
       
  1495         }
       
  1496     
       
  1497             
       
  1498           
       
  1499     accessSemaphore.Wait();
       
  1500     
       
  1501     // Use Publish and Subscribe to generate new session ID. 
       
  1502     RProperty idCounter;
       
  1503     
       
  1504     // Attach to the idCounter, property defined in MessageHandler
       
  1505     r = idCounter.Attach(KUPnPUtilsCat,EUPnPUtilsCounter);
       
  1506     if (r == KErrNone) 
       
  1507         {
       
  1508         r = idCounter.Get(id);
       
  1509         }
       
  1510 
       
  1511     if (r == KErrNone) 
       
  1512         {
       
  1513         // Increment id and save
       
  1514         id++;
       
  1515         r=idCounter.Set(id);
       
  1516         if (r==KErrNone) 
       
  1517             {
       
  1518             newID = ETrue; 
       
  1519             }
       
  1520         }
       
  1521 
       
  1522     accessSemaphore.Signal();
       
  1523     accessSemaphore.Close();       
       
  1524 
       
  1525     // Close the idCounter property
       
  1526     idCounter.Close();      
       
  1527     
       
  1528     
       
  1529     if(!newID)
       
  1530         User::Leave(r);
       
  1531 
       
  1532     return id;
       
  1533     }
       
  1534 
       
  1535 // -----------------------------------------------------------------------------
       
  1536 // CUpnpHttpMessage::SessionIdMatch
       
  1537 // Compares if two messages have same session id.
       
  1538 // -----------------------------------------------------------------------------
       
  1539 //
       
  1540 EXPORT_C TBool CUpnpHttpMessage::SessionIdMatch(const CUpnpHttpMessage& aFirst, const CUpnpHttpMessage& aSecond)
       
  1541     {
       
  1542     return aFirst.iSessionId == aSecond.iSessionId;
       
  1543     }
       
  1544 
       
  1545 // -----------------------------------------------------------------------------
       
  1546 // CUpnpHttpMessage::BodyLength
       
  1547 // Returns length of message body.
       
  1548 // -----------------------------------------------------------------------------
       
  1549 //
       
  1550 EXPORT_C TInt CUpnpHttpMessage::BodyLength() const
       
  1551     {
       
  1552     return iTextBody->Length();
       
  1553     }
       
  1554 
       
  1555 // -----------------------------------------------------------------------------
       
  1556 // CUpnpHttpMessage::DevicePath
       
  1557 // Returns the service used from http message, for example MediaServer:1 
       
  1558 // from Mediaserver:1/ContentDirectory.
       
  1559 // -----------------------------------------------------------------------------
       
  1560 //
       
  1561 EXPORT_C const TPtrC8 CUpnpHttpMessage::DevicePath()
       
  1562     {
       
  1563 
       
  1564     CUpnpHttpHeader* hdr = iHeaderList->First();
       
  1565     
       
  1566     if (hdr != NULL)
       
  1567         {
       
  1568         TInt FirstSlashIndex = hdr->Name().Find(UpnpString::KSlash());
       
  1569         if (FirstSlashIndex == KErrNotFound)
       
  1570             {
       
  1571             return KNullDesC8();
       
  1572             }
       
  1573         TPtrC8 tempPtr;
       
  1574         tempPtr.Set(hdr->Name().Right(hdr->Name().Length() - (FirstSlashIndex + 1)));
       
  1575         TInt SecondSlashIndex = tempPtr.Find(UpnpString::KSlash());
       
  1576         if (SecondSlashIndex == KErrNotFound)
       
  1577             {
       
  1578             return KNullDesC8();
       
  1579             }
       
  1580         TPtrC8 tempPtr2;
       
  1581         tempPtr2.Set(tempPtr.Left(SecondSlashIndex));
       
  1582         return tempPtr2;
       
  1583         }
       
  1584     
       
  1585     return KNullDesC8();
       
  1586     }
       
  1587 
       
  1588 // -----------------------------------------------------------------------------
       
  1589 // CUpnpHttpMessage::ServicePath
       
  1590 // Returns the service used from http message, for example ContentDirectory 
       
  1591 // from Mediaserver:1/ContentDirectory.
       
  1592 // -----------------------------------------------------------------------------
       
  1593 //
       
  1594 EXPORT_C const TPtrC8 CUpnpHttpMessage::ServicePath() const
       
  1595     {
       
  1596     TInt firstSlashIndex(-1);
       
  1597     
       
  1598     TInt httpSchema  = iDestinationPath->Find( UpnpHTTP::KHTTPUrl() );
       
  1599     if( httpSchema != KErrNotFound)
       
  1600     {
       
  1601         TPtrC8 schemaPtr( iDestinationPath->Mid( UpnpHTTP::KHTTPUrl().Length() ) );    
       
  1602         TInt relativePath = schemaPtr.Find( UpnpString::KSlash() );        
       
  1603         firstSlashIndex = relativePath + UpnpHTTP::KHTTPUrl().Length() ;
       
  1604     }    
       
  1605     else
       
  1606     {
       
  1607         firstSlashIndex = iDestinationPath->Find(UpnpString::KSlash());
       
  1608     }
       
  1609     
       
  1610     if(firstSlashIndex == KErrNotFound)
       
  1611         return KNullDesC8();    
       
  1612     
       
  1613     TPtrC8 devicePtr(iDestinationPath->Right(iDestinationPath->Length() - (firstSlashIndex + 1)));
       
  1614 
       
  1615     TInt secondSlashIndex = devicePtr.Find(UpnpString::KSlash());
       
  1616     TPtrC8 servicePtr(devicePtr.Right(devicePtr.Length() - (secondSlashIndex + 1)));
       
  1617     TInt third = servicePtr.Find(UpnpString::KSlash());
       
  1618     TInt sp = servicePtr.Find(UpnpString::KSpace());
       
  1619 
       
  1620     if (third != KErrNotFound && ((third < sp && sp != KErrNotFound) || sp == KErrNotFound))
       
  1621         {
       
  1622         return servicePtr.Left(third);
       
  1623         }
       
  1624     else
       
  1625         {
       
  1626         TInt space = servicePtr.Find(UpnpString::KSpace());
       
  1627         if (space != KErrNotFound)
       
  1628             {
       
  1629             return servicePtr.Left(space);
       
  1630             }
       
  1631         return servicePtr;
       
  1632         }    
       
  1633     }
       
  1634 
       
  1635 // -----------------------------------------------------------------------------
       
  1636 // CUpnpHttpMessage::IsSoap
       
  1637 // Checks if message is SOAP message.
       
  1638 // -----------------------------------------------------------------------------
       
  1639 //
       
  1640 EXPORT_C TBool CUpnpHttpMessage::IsSoap() const
       
  1641     {
       
  1642     
       
  1643     TInt envelope = iTextBody->Find(KEnvelope());
       
  1644     if( envelope == KErrNotFound )
       
  1645         {
       
  1646         CUpnpHttpHeader* hdr = iHeaderList->First();
       
  1647     
       
  1648         while (hdr != NULL)
       
  1649             {
       
  1650             if ( hdr->Value().FindC( UpnpSSDP::KUPnPServiceSchema() ) != KErrNotFound && hdr->Name().FindC( KSoapAction() ) != KErrNotFound )
       
  1651                 {
       
  1652                 return ETrue;
       
  1653                 }
       
  1654 
       
  1655             hdr = iHeaderList->Next(hdr);
       
  1656             }
       
  1657         return EFalse;
       
  1658         }
       
  1659     else
       
  1660         {
       
  1661         return ETrue;
       
  1662         }
       
  1663     }
       
  1664 
       
  1665 // -----------------------------------------------------------------------------
       
  1666 // CUpnpHttpMessage::IsGena
       
  1667 // Checks if message is GENA message.
       
  1668 // -----------------------------------------------------------------------------
       
  1669 //
       
  1670 EXPORT_C TBool CUpnpHttpMessage::IsGena()
       
  1671     {
       
  1672 
       
  1673     if (Method().CompareC(UpnpGENA::KGenaSubscribe()) == 0)
       
  1674         {
       
  1675         return ETrue;
       
  1676         }
       
  1677     else if (Method().CompareC(UpnpGENA::KGenaUnSubscribe()) == 0)
       
  1678         {
       
  1679         return ETrue;
       
  1680         }
       
  1681     else if (Method().CompareC(UpnpGENA::KGenaNotify()) == 0)
       
  1682         {
       
  1683         return ETrue;
       
  1684         }
       
  1685 
       
  1686     CUpnpHttpHeader* hdr = iHeaderList->First();
       
  1687     
       
  1688     while (hdr != NULL)
       
  1689         {
       
  1690         if (hdr->Name().CompareC(UpnpGENA::KSid()) == 0)
       
  1691             {
       
  1692             return ETrue;
       
  1693             }
       
  1694 
       
  1695         hdr = iHeaderList->Next(hdr);
       
  1696         }    
       
  1697     return EFalse;
       
  1698     }
       
  1699 
       
  1700 // -----------------------------------------------------------------------------
       
  1701 // CUpnpHttpMessage::Method
       
  1702 // Returns the method of message, like GET, POST etc.
       
  1703 // -----------------------------------------------------------------------------
       
  1704 //
       
  1705 EXPORT_C const TPtrC8 CUpnpHttpMessage::Method()
       
  1706     {
       
  1707     TBool ValueFound=EFalse;
       
  1708     CUpnpHttpHeader* hdr = iHeaderList->First();
       
  1709 
       
  1710     TPtrC8 returnPtr;
       
  1711     
       
  1712     if (hdr != NULL)
       
  1713         {
       
  1714         TInt index = hdr->Name().Find(UpnpString::KSpace());
       
  1715         if    (index!= KErrNotFound)
       
  1716         {
       
  1717         returnPtr.Set(hdr->Name().Left(index));
       
  1718         ValueFound=ETrue;    
       
  1719         }
       
  1720         
       
  1721         }
       
  1722     
       
  1723     if(!ValueFound)
       
  1724         {
       
  1725         returnPtr.Set(KNullDesC8);
       
  1726         }
       
  1727     return returnPtr;
       
  1728     }
       
  1729 // -----------------------------------------------------------------------------
       
  1730 // CUpnpHttpMessage::HTTPVersion
       
  1731 //Returns version of HTTP, like HTTP/1.1, HTTP/1.0 etc.
       
  1732 //-----------------------------------------------------------------------------
       
  1733 //
       
  1734 EXPORT_C const TPtrC8 CUpnpHttpMessage::RequestHTTPVersion()
       
  1735     {
       
  1736     CUpnpHttpHeader* hdr = iHeaderList->First();
       
  1737     TPtrC8 returnPtr;
       
  1738 
       
  1739     if (hdr != NULL)
       
  1740         {
       
  1741         TInt index = hdr->Name().LocateReverse(UpnpString::KSpace()[0]);
       
  1742         if (index >= 0)
       
  1743             {
       
  1744                 returnPtr.Set(hdr->Name().Right(hdr->Name().Length()-index-1));    
       
  1745             }
       
  1746             else
       
  1747             {
       
  1748                 returnPtr.Set(KNullDesC8);
       
  1749             }
       
  1750         }
       
  1751         else
       
  1752         {
       
  1753             returnPtr.Set(KNullDesC8);
       
  1754         }
       
  1755     return returnPtr;
       
  1756     }
       
  1757 
       
  1758 // -----------------------------------------------------------------------------
       
  1759 // CUpnpHttpMessage::HeaderList
       
  1760 // Returns a pointer to this message's headerlist.
       
  1761 // -----------------------------------------------------------------------------
       
  1762 //
       
  1763 EXPORT_C CUpnpHttpHeaderList* CUpnpHttpMessage::HeaderList()
       
  1764     {
       
  1765     return iHeaderList;
       
  1766     }
       
  1767 
       
  1768 // -----------------------------------------------------------------------------
       
  1769 // CUpnpHttpMessage::SetType
       
  1770 // Sets the type of message. Used by ControlPoint
       
  1771 // -----------------------------------------------------------------------------
       
  1772 //
       
  1773 EXPORT_C void CUpnpHttpMessage::SetType(THTTPMsgType aType)
       
  1774     {
       
  1775     iType = aType;
       
  1776     }
       
  1777 
       
  1778 // -----------------------------------------------------------------------------
       
  1779 // CUpnpHttpMessage::Type
       
  1780 // Returns the Http message type, used by controlpoint.
       
  1781 // -----------------------------------------------------------------------------
       
  1782 //
       
  1783 EXPORT_C THTTPMsgType CUpnpHttpMessage::Type() const
       
  1784     {
       
  1785     return iType;
       
  1786     }
       
  1787 
       
  1788 // -----------------------------------------------------------------------------
       
  1789 // CUpnpHttpMessage::UpnpError
       
  1790 // Returns textual presentation of the given error.
       
  1791 // -----------------------------------------------------------------------------
       
  1792 //
       
  1793 EXPORT_C const TDesC8& CUpnpHttpMessage::UpnpError(TUpnpErrorCode aError)
       
  1794     {
       
  1795     switch(aError)    
       
  1796         {    
       
  1797         case EHttpOk:
       
  1798             return KHttpOk();
       
  1799             
       
  1800         case EBadRequest:
       
  1801             return KBadRequest();
       
  1802         case EInvalidAction:
       
  1803             return KInvalidAction();
       
  1804         case EInvalidArgs:
       
  1805             return KInvalidArgs();
       
  1806         case EInvalidVar:
       
  1807             return KInvalidVar();
       
  1808         case EPreconditionFailed:
       
  1809             return KPreconditionFailed();
       
  1810             
       
  1811         case EInternalServerError:
       
  1812             return KInternalServerError();
       
  1813         case EActionFailed:
       
  1814             return KActionFailed();
       
  1815             
       
  1816         // 600-699 Common action errors:    
       
  1817         case EArgumentValue:
       
  1818             return KArgumentValue();
       
  1819         case EArgumentRange:
       
  1820             return KArgumentRange();
       
  1821         case ENotImplemented:
       
  1822             return KNotImplemented();
       
  1823         case EOutOfMemory:
       
  1824             return KOutOfMemory();
       
  1825         case EHumanIntervention:
       
  1826             return KHumanIntervention();
       
  1827         case EStringTooLong:
       
  1828             return KStringTooLong();
       
  1829         case ENotAuthorized:
       
  1830             return KNotAuthorized();
       
  1831         case ESignatureFailure:
       
  1832             return KSignatureFailure();
       
  1833         case ESignatureMissing:
       
  1834             return KSignatureMissing();
       
  1835         case ENotEncrypted:
       
  1836             return KNotEncrypted();
       
  1837         case EInvalidSequence:
       
  1838             return KInvalidSequence();
       
  1839         case EInvalidUrl:
       
  1840             return KInvalidUrl();
       
  1841         case ENoSession:
       
  1842             return KNoSession();
       
  1843             
       
  1844         // 700-799 Action specific errors:    
       
  1845         case ENoSuchObject:
       
  1846             return KNoSuchObject();
       
  1847         case EInvalidCurrentTag:
       
  1848             return KInvalidCurrentTag();
       
  1849         case EInvalidNewTag:
       
  1850             return KInvalidNewTag();
       
  1851         case ERequiredTag:
       
  1852             return KRequiredTag();
       
  1853         case EReadOnlyTag:
       
  1854             return KReadOnlyTag();
       
  1855         case EParameterMismatch:
       
  1856             return KParameterMismatch();
       
  1857         case EInvalidSearch:
       
  1858             return KInvalidSearch();
       
  1859         case EInvalidSort:
       
  1860             return KInvalidSort();
       
  1861         case ENoContainer:
       
  1862             return KNoContainer();
       
  1863         case ERestrictedObject:
       
  1864             return KRestrictedObject();
       
  1865         case EBadMetadata:
       
  1866             return KBadMetadata();
       
  1867         case ERestrictedParentObject:
       
  1868             return KRestrictedParentObject();
       
  1869         case ENoSourceResource:
       
  1870             return KNoSourceResource();
       
  1871         case ESourceAccess:
       
  1872             return KSourceAccess();
       
  1873         case ETransferBusy:
       
  1874             return KTransferBusy();
       
  1875         case ENoFileTransfer:
       
  1876             return KNoFileTransfer();
       
  1877         case ENoDestinationResource:
       
  1878             return KNoDestinationResource();
       
  1879         case EDestinationAccess:
       
  1880             return KDestinationAccess();
       
  1881         case ECannotProcess:
       
  1882             return KCannotProcess();
       
  1883         default:
       
  1884             return KNullDesC8();
       
  1885         }    
       
  1886     }
       
  1887 
       
  1888 // -----------------------------------------------------------------------------
       
  1889 // CUpnpHttpMessage::UpnpErrorL
       
  1890 // Returns textual presentation of the given error.
       
  1891 // -----------------------------------------------------------------------------
       
  1892 //
       
  1893 EXPORT_C HBufC8* CUpnpHttpMessage::UpnpErrorL(TUpnpErrorCode aError)
       
  1894     {
       
  1895     return UpnpError(aError).AllocL();
       
  1896     }
       
  1897 
       
  1898 // -----------------------------------------------------------------------------
       
  1899 // CUpnpHttpMessage::HttpError
       
  1900 // Returns the textual error message of given error code.
       
  1901 // -----------------------------------------------------------------------------
       
  1902 //
       
  1903 EXPORT_C const TDesC8& CUpnpHttpMessage::HttpError(THttpStatusCode aError)
       
  1904     {
       
  1905     switch(aError)    
       
  1906         {    
       
  1907             // 100
       
  1908         case EHttpContinue:
       
  1909             return KHttpContinue();
       
  1910         case EHttpSwitchingProtocols:
       
  1911             return KHttpSwitchingProtocols();
       
  1912             
       
  1913             // 200
       
  1914         case EHttp200Ok:
       
  1915             return KHttpOk();
       
  1916         case EHttpCreated:
       
  1917             return KHttpCreated();
       
  1918         case EHttpAccepted:
       
  1919             return KHttpAccepted();
       
  1920         case EHttpNonAuthoritative:
       
  1921             return KHttpNonAutohorative();
       
  1922         case EHttpNoContent:
       
  1923             return KHttpNoContent();
       
  1924         case EHttpResetContent:
       
  1925             return KHttpResetContent();
       
  1926         case EHttpPartialContent:
       
  1927             return KHttpPartialContent();
       
  1928         
       
  1929             // 300
       
  1930 
       
  1931         case EHttpMultipleChoises:
       
  1932             return     KHttpMultipleChoises();
       
  1933         case EHttpMovedPermanently:
       
  1934             return KHttpMovedPermanently();
       
  1935         case EHttpFound:
       
  1936             return KHttpFound();
       
  1937         case EHttpSeeOther:
       
  1938             return KHttpSeeOther();
       
  1939         case EHttpNotModified:
       
  1940             return KHttpNotModified();
       
  1941         case EHttpUseProxy:
       
  1942             return KHttpUseProxy();
       
  1943         case EHttpTemporaryRedirect:
       
  1944             return KHttpTemporaryRedirect();
       
  1945             
       
  1946             // 400
       
  1947             
       
  1948         case EHttpBadRequest:
       
  1949             return KHttpBadRequest();
       
  1950         case EHttpUnAuthorized:
       
  1951             return KHttpUnauthorized();
       
  1952         case EHttpPaymentRequired:
       
  1953             return KHttpPaymentRequired();
       
  1954         case EHttpForbidden:
       
  1955             return KHttpForbidden();
       
  1956         case EHttpNotFound:
       
  1957             return KHttpNotFound();
       
  1958         case EHttpMethodNotAllowed:
       
  1959             return KHttpMethodNotAllowed();
       
  1960         case EHttpNotAcceptable:
       
  1961             return KHttpNotAcceptable();
       
  1962         case EHttpProxyAuthenticationRequired:
       
  1963             return KHttpProxyAuthenticationRequired();
       
  1964             
       
  1965         case EHttpRequestTimeout:
       
  1966             return KHttpRequestTimeout();
       
  1967         case EHttpConflict:
       
  1968             return KHttpConflict();
       
  1969         case EHttpGone:
       
  1970             return KHttpGone();
       
  1971         case EHttpLengthRequired:
       
  1972             return KHttpLengthRequired();
       
  1973         case EHttpPreconditionFailed:
       
  1974             return KHttpPreconditionFailed();
       
  1975         case EHttpEntityTooLarge:
       
  1976             return KHttpEntityTooLarge();
       
  1977         case EHttpUriTooLong:
       
  1978             return KHttpUriTooLarge();
       
  1979         case EHttpUnsupportedMediaType:
       
  1980             return KHttpUnsupprotedMediaType();
       
  1981         case EHttpRequestedRangeNotSatisfiable:
       
  1982             return KHttpRequestedRangeNotSatisfiable();
       
  1983         case EHttpExpectationFailed:
       
  1984             return KHttpExpectationFailed();
       
  1985 
       
  1986             // 500                
       
  1987         case EHttpInternalServerError:
       
  1988             return KHttpInternalServerError();
       
  1989         case EHttpNotImplemented:
       
  1990             return KHttpNotImplemented();
       
  1991         case EHttpBadGateway:
       
  1992             return KHttpBadGateway();
       
  1993         case EHttpServiceUnavailable:
       
  1994             return KHttpServiceUnavailable();
       
  1995         case EHttpGatewayTimeout:
       
  1996             return KHttpGatewayTimeout();
       
  1997         case EHttpVersionNotSupported:
       
  1998             return KHttpVersionNotSupported();
       
  1999         case EHttpInsufficientStorage:
       
  2000             return KHttpInsufficientStorage();
       
  2001             
       
  2002         default:
       
  2003             return KNullDesC8();
       
  2004         }    
       
  2005     }
       
  2006 
       
  2007 // -----------------------------------------------------------------------------
       
  2008 // CUpnpHttpMessage::Error
       
  2009 // Returns the error code of the message.
       
  2010 // -----------------------------------------------------------------------------
       
  2011 //
       
  2012 EXPORT_C TInt CUpnpHttpMessage::Error()
       
  2013     {
       
  2014     if(iHeaderList && iHeaderList->Count())
       
  2015         {
       
  2016         CUpnpHttpHeader* hdr = iHeaderList->First();
       
  2017 
       
  2018         if (hdr != NULL)
       
  2019             {            
       
  2020             TDesC8& first = hdr->Name();
       
  2021         
       
  2022             if(first.Length() == 0)
       
  2023                 {
       
  2024                 return KErrNotFound;
       
  2025                 }
       
  2026 
       
  2027             TInt space1 = first.Find(KSpace8());
       
  2028 
       
  2029             if (space1 != KErrNotFound)
       
  2030                 {
       
  2031                 TPtrC8 right = first.Mid(space1+1);
       
  2032                 TInt space2 = right.Find(KSpace8());
       
  2033 
       
  2034                 if (space2 != KErrNotFound)
       
  2035                     {
       
  2036                     TLex8 lex(right.Left(space2));
       
  2037 
       
  2038                     TInt error;
       
  2039                     lex.Val(error);
       
  2040 
       
  2041                     return error;                
       
  2042                     }
       
  2043                 }
       
  2044             }
       
  2045         }
       
  2046     return KErrNotFound;
       
  2047     }
       
  2048 
       
  2049 // -----------------------------------------------------------------------------
       
  2050 // CUpnpHttpMessage::Is3xx
       
  2051 // Returns True if message is a 3xx response
       
  2052 // -----------------------------------------------------------------------------
       
  2053 //
       
  2054 EXPORT_C TBool CUpnpHttpMessage::Is3xx()
       
  2055     { TInt err = Error();
       
  2056         return (err>=300 && err<400);
       
  2057     
       
  2058     }
       
  2059 
       
  2060 // -----------------------------------------------------------------------------
       
  2061 // CUpnpHttpMessage::Is1xx
       
  2062 // Returns True if message is a 1xx response
       
  2063 // -----------------------------------------------------------------------------
       
  2064 //
       
  2065 EXPORT_C TBool CUpnpHttpMessage::Is1xx()
       
  2066     { TInt err = Error();
       
  2067         return (err>=100 && err<200);
       
  2068     
       
  2069     }
       
  2070 
       
  2071 // -----------------------------------------------------------------------------
       
  2072 // CUpnpHttpMessage::Is2xx
       
  2073 // Returns True if message is a 2xx response
       
  2074 // -----------------------------------------------------------------------------
       
  2075 //
       
  2076 EXPORT_C TBool CUpnpHttpMessage::Is2xx()
       
  2077     { TInt err = Error();
       
  2078         return (err>=200 && err<300);
       
  2079     
       
  2080     }
       
  2081 
       
  2082 // -----------------------------------------------------------------------------
       
  2083 // CUpnpHttpMessage::AddrOutput
       
  2084 // Sets the aBuf as string presentation of aAddr
       
  2085 // -----------------------------------------------------------------------------
       
  2086 //
       
  2087 EXPORT_C void CUpnpHttpMessage::AddrOutput(const TInetAddr& aAddr, TDes8& aBuf)
       
  2088     {
       
  2089     aBuf.SetLength(0);
       
  2090     if (aAddr.Family() == KAfInet || aAddr.Family() == KAfInet6)
       
  2091         {
       
  2092         TUint32 a = aAddr.Address();
       
  2093         aBuf.Format(_L8("%d.%d.%d.%d"), a>>24, (a>>16)&0xff, (a>>8)&0xff, a&0xff);
       
  2094         }
       
  2095     
       
  2096     }
       
  2097 
       
  2098 // -----------------------------------------------------------------------------
       
  2099 // CUpnpHttpMessage::AddrInput
       
  2100 // Sets the TInetAddr object value to given aBuf.
       
  2101 // -----------------------------------------------------------------------------
       
  2102 //
       
  2103 EXPORT_C void CUpnpHttpMessage::AddrInput(TInetAddr& aAddr, const TDesC8& aBuf)
       
  2104     {
       
  2105     
       
  2106     TPtrC8 ptr(aBuf);
       
  2107     TInt addr[4] = {0, 0, 0, 0};
       
  2108     for (TInt i=0; i<4; i++)
       
  2109         {
       
  2110         TInt posOfDot=ptr.Find(UpnpString::KDot8);
       
  2111         if(posOfDot != KErrNotFound)
       
  2112             {
       
  2113             TLex8 lex(ptr.Left(posOfDot));
       
  2114             lex.Val(addr[i]);    
       
  2115             ptr.Set(ptr.Mid(posOfDot+1));
       
  2116             }
       
  2117         else
       
  2118             {
       
  2119             if(i==3)
       
  2120                 {
       
  2121                 TLex8 lex(ptr);
       
  2122                 lex.Val(addr[i]);                
       
  2123                 }
       
  2124             }
       
  2125 
       
  2126         }    
       
  2127     aAddr.SetAddress((addr[0]<<24) | (addr[1]<<16) | (addr[2]<<8) | addr[3]);
       
  2128     }
       
  2129 
       
  2130 // -----------------------------------------------------------------------------
       
  2131 // CUpnpHttpMessage::RetryCounter
       
  2132 // Returns the current iRetryCounter value.
       
  2133 // -----------------------------------------------------------------------------
       
  2134 //
       
  2135 EXPORT_C TInt CUpnpHttpMessage::RetryCounter()
       
  2136     {
       
  2137     return iRetryCounter;
       
  2138     }
       
  2139 
       
  2140 // -----------------------------------------------------------------------------
       
  2141 // CUpnpHttpMessage::SetRetryCounter
       
  2142 // Sets the retry counter value
       
  2143 // -----------------------------------------------------------------------------
       
  2144 //
       
  2145 EXPORT_C void CUpnpHttpMessage::SetRetryCounter(TInt aValue)
       
  2146     {
       
  2147     iRetryCounter=aValue;
       
  2148     }
       
  2149 
       
  2150 // -----------------------------------------------------------------------------
       
  2151 // CUpnpHttpMessage::SetHttpPriority
       
  2152 // Sets the priority on session sending this message
       
  2153 // -----------------------------------------------------------------------------
       
  2154 //
       
  2155 EXPORT_C void CUpnpHttpMessage::SetHttpPriority( TThreadPriority aPriority )
       
  2156     {
       
  2157     iSessionPriority = aPriority;
       
  2158     }
       
  2159 
       
  2160 // -----------------------------------------------------------------------------
       
  2161 // CUpnpHttpMessage::HttpPriority
       
  2162 // Returns the priority of this message
       
  2163 // -----------------------------------------------------------------------------
       
  2164 //
       
  2165 EXPORT_C TThreadPriority CUpnpHttpMessage::HttpPriority()
       
  2166     {
       
  2167     return iSessionPriority;
       
  2168     }
       
  2169 
       
  2170 // -----------------------------------------------------------------------------
       
  2171 // CUpnpHttpMessage::SetOutUri
       
  2172 // Sets the uri to find the local file.
       
  2173 // -----------------------------------------------------------------------------
       
  2174 //
       
  2175 EXPORT_C void CUpnpHttpMessage::SetOutUriL( const TDesC8& aUri )
       
  2176     {
       
  2177     if( iOutUri )
       
  2178         {
       
  2179         delete iOutUri;
       
  2180         iOutUri = NULL;
       
  2181         }
       
  2182     iOutUri = HBufC8::NewL( aUri.Length() );
       
  2183     iOutUri->Des().Zero();
       
  2184     iOutUri->Des().Append( aUri );
       
  2185     }
       
  2186 
       
  2187 // -----------------------------------------------------------------------------
       
  2188 // CUpnpHttpMessage::OutUri
       
  2189 // Returns the value of OutUri.
       
  2190 // -----------------------------------------------------------------------------
       
  2191 //
       
  2192 EXPORT_C const TDesC8& CUpnpHttpMessage::OutUri()
       
  2193     {
       
  2194     if( iOutUri )
       
  2195         {
       
  2196         return *iOutUri;
       
  2197         }
       
  2198     else
       
  2199         {
       
  2200         return KNullDesC8();
       
  2201         }
       
  2202     }
       
  2203 
       
  2204 // -----------------------------------------------------------------------------
       
  2205 // CUpnpHttpMessage::SetLocal
       
  2206 // Sets if message is a local requests
       
  2207 // -----------------------------------------------------------------------------
       
  2208 //
       
  2209 EXPORT_C void CUpnpHttpMessage::SetLocal( TBool aLocal )
       
  2210     {
       
  2211     iLocal = aLocal;
       
  2212     }
       
  2213 
       
  2214 // -----------------------------------------------------------------------------
       
  2215 // CUpnpHttpMessage::Local
       
  2216 // Returns if message is a local requests.
       
  2217 // -----------------------------------------------------------------------------
       
  2218 //
       
  2219 EXPORT_C TBool CUpnpHttpMessage::Local()
       
  2220     {
       
  2221     return iLocal;
       
  2222     }
       
  2223 // -----------------------------------------------------------------------------
       
  2224 // CUpnpHttpMessage::SetClientRequest
       
  2225 // Sets if message is a client request
       
  2226 // -----------------------------------------------------------------------------
       
  2227 //
       
  2228 EXPORT_C void CUpnpHttpMessage::SetClientRequest( TBool aClientRequest )
       
  2229     {
       
  2230     iClientRequest = aClientRequest;
       
  2231     }
       
  2232 
       
  2233 // -----------------------------------------------------------------------------
       
  2234 // CUpnpHttpMessage::Local
       
  2235 // Returns if message is a client request.
       
  2236 // -----------------------------------------------------------------------------
       
  2237 //
       
  2238 EXPORT_C TBool CUpnpHttpMessage::ClientRequest()
       
  2239     {
       
  2240     return iClientRequest;
       
  2241     }
       
  2242 // -----------------------------------------------------------------------------
       
  2243 // CUpnpHttpMessage::SetTimeout
       
  2244 // Sets the value for a TCP timeout (valid for cleint sessions)
       
  2245 // -----------------------------------------------------------------------------
       
  2246 //
       
  2247 EXPORT_C void CUpnpHttpMessage::SetTcpTimeout( TInt aTimeout )
       
  2248     {
       
  2249     iTcpTimeout = aTimeout;
       
  2250     }
       
  2251 
       
  2252 // -----------------------------------------------------------------------------
       
  2253 // CUpnpHttpMessage::Timeout
       
  2254 // Returns the value of TCP timeout
       
  2255 // -----------------------------------------------------------------------------
       
  2256 //
       
  2257 EXPORT_C TInt CUpnpHttpMessage::TcpTimeout()
       
  2258     {
       
  2259     return iTcpTimeout;
       
  2260     }
       
  2261 // -----------------------------------------------------------------------------
       
  2262 // CUpnpHttpMessage::SetInternalError
       
  2263 // Sets internal error code
       
  2264 // -----------------------------------------------------------------------------
       
  2265 //
       
  2266 EXPORT_C void CUpnpHttpMessage::SetInternalError(TInt aErrorCode)
       
  2267     {
       
  2268     iInternalError = aErrorCode;
       
  2269     }    
       
  2270 // -----------------------------------------------------------------------------
       
  2271 // CUpnpHttpMessage::SetInternalError
       
  2272 // Sets internal error code
       
  2273 // -----------------------------------------------------------------------------
       
  2274 //
       
  2275 EXPORT_C TInt CUpnpHttpMessage::InternalError()
       
  2276     {
       
  2277     return iInternalError;
       
  2278     }        
       
  2279 //  End of File