upnp/upnpstack/dlnawebserver/inc/upnphttpsession.h
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 02 Feb 2010 01:12:20 +0200
changeset 0 f5a58ecadc66
child 8 92b4d337bbaf
permissions -rw-r--r--
Revision: 201003

/** @file
* Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies). 
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies  this distribution, and is available 
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  HttpSession is class that is used to handle single 
*                 connections to HttpServer
*
*/


#ifndef C_CUPNPHTTPSESSION_H
#define C_CUPNPHTTPSESSION_H

// INCLUDES

#include <e32base.h>
#include <f32file.h>
#include <apasvst.h>
#include <apaflrec.h>
#include <e32std.h>

#include "upnphttpmessage.h"
#include "upnptcpsession.h"


// FORWARD DECLARATIONS

class CFileReader;
class CUpnpHttpBuffer;
class CUpnpHttpServer;
class CUpnpHttpFileAccess;
class CUpnpHttpServerTransaction;

// CONSTANTS

_LIT8( KMedia,  "\\MEDIA\\" );
_LIT8( KLog,    "\\LOG\\" );              
_LIT( KPercent,   "%" );

static const TInt KDefaultLastActionSize = 2048;
static const TInt KMaxRedirectCount=5;

// CLASS DECLARATION

/**
*  @brief HttpSession is class that is used to handle single connections to HttpServer.  
*
*  @since Series60 2.6
*/
NONSHARABLE_CLASS (CUpnpHttpSession) : public CUpnpTcpSession
    {
    
public: // Construtors and destructor

    /**
    * Constructor function. This constructor is used when connection is iniatiated
    *  from network.
    * @param aSocket Pointer to new socket.
    * @param aServer Pointer to owning HttpServer.
    * @param aSessionId Session id of this session.
    * @param aPriority Priority of this session
    * @return A new CUpnpHttpServer instance.
    **/
    static CUpnpHttpSession* NewL( RSocket aSocket, 
                               CUpnpHttpServer* aServer,
                               TInt aSessionId,
                               TThreadPriority aPriority );

    /**
    * Virtual Destructor function.
    */
    virtual ~CUpnpHttpSession();

public: // From CUpnpTcpSession
    /**
    * Callback function from TcpSession. Session has received aBuffer 
    *  from network.
    * @since Series60 2.6
    * @param aBuffer Buffer that has been received.
    * @return None.
    **/
    void BufferReceivedL( TDesC8& aBuffer );

public: // New functions

    /**
    * Sends aMessage to session's remote host.
    * @since Series60 2.6
    * @param aMessage Message to be sent.
    **/
    void SendL( CUpnpHttpMessage* aMessage );

    /**
    * Deletes current session.
    * @since Series60 2.6
    * @param aSession Session to b deleted.
    **/
    void DeleteThisSessionL( CUpnpTcpSession* aSession );
    
    /**
    * Deletes a file named aFilename if it exists. Used in receiving files
    * to delete file if it already exists.
    * @since Series60 2.6
    * @param aFilename File to be deleted.
    * @return None.
    **/
    void DeleteFileIfExists( TDesC16& aFilename );

    /**
    * Returns a pointer to file transfer object of this session.
    * @since Series60 2.6
    * @return Pointer to file transfer object.
    **/
    CUpnpHttpFileAccess* FileAccess();
       
    /**
    * Should the existing local file be overwritten with the requested content.
    *  If not then the new file with name: iInFilename_serialNumber will be created
    *  to save incoming content. It's connected only with download.
    * @return Should the local in-file be overwritten with incoming content.
    **/
    TBool OverwriteExisting();
    
    // Range request parameters, only used for GET and HEAD requests with Range HTTP header.
    /**
    * Returns offset of the file that should be requested from server. 
    * @return offset to save content at.
    **/
    TInt Offset();
    
    /**
    * Returns the length of file content to be requested.
    * @return Length of file content to be requested.
    **/
    TInt Length(); 
    
    /**
    * Returns if should the requested offset of the remote file be 
    *  saved at physical offset of existing local file.
    *  Only for Range requests
    * @return Should the requested offset of the remote file be saved at 
    *  physical offset of existing local file.
    */
    TBool SaveAtOffset();
    
    /**
    * Notifies upper layers that there is a HTTP error.
    * @since Series60 3.2
    * @param the HTTP error code
    **/
    void NotifyErrorL(TInt aError, TInt aInternalError = KErrNone);
    
    /**
    * Returns ETrue when message is totally downloaded [completed]
    * @since Series60 3.2
    * @return ETrue if message is completed
    **/
    TBool IsMsgReady();
    
    /**
    * Increments the redirect counter
    * @since Series60 3.2
    * @return ETrue if the number of Redirecting has exceeded the maximum
    **/
    TBool SetRedirectCount();

    /**
    * Returns HttpServer pointer
    * @since Series60 3.2
    **/    
    CUpnpHttpServer* HttpServer();
    
    /**
    * Deletes the FileAccess of this session.
    * @since Series60 2.6
    * @return None.
    **/ 
    void DeleteServeFileL();

protected: // New functions
    
    void DestroyIt(CUpnpTcpSession* aSession );
    
    /**
    * Returns ETrue, if fileserve exists.
    * @since Series60 2.6
    * @return ETrue, if fileserve exists; EFalse otherwise.
    **/
    TBool FileServeExists();
   
    /**
    * Returns the port of this HttpSession.
    * @since Series60 2.6
    * @return Number of server port.
    **/   
    TInt ServerPort();
    
private: // Constructors

    /**
    * First phase constructor. This constructor is used when connection is
    *  iniatiated from network.
    * @since Series60 2.6
    * @param aSocket Pointer to new socket.
    * @param aServer Pointer to owning HttpServer.
    * @param aSessionId Session id of this session.
    * @param aPriority Priority of this session
    **/
    CUpnpHttpSession( RSocket aSocket, 
                  CUpnpHttpServer* aServer, 
                  TInt aSessionId,
                  TThreadPriority aPriority );
    
    /**
    * Symbian constructor
    */
    void ConstructL();

    /**
    * Received buffer processing from network.
    * @since Series60 2.6
    * @param aBuffer Buffer that has been received.
    * @return None.
    **/
    void BufferReceivedProcessL( TDesC8& aBuffer );

/**
    * Received buffer checking headers for a message coming from network.
    * @since Series60 2.6
    * @param aBuffer Buffer that has been received.
    * @return None.
    **/
    void BufferReceivedCheckingHeadersL( TDesC8& aBuffer );


    /**
    * Single POST buffer processing
    *  
    * @since Series60 2.6
    * @param aBuffer Buffer that has been received.
    * @return None.
    **/
    void CUpnpHttpSession::SinglePostBufferReceivedL( TDesC8& aBuffer ); 
    
    

    TInt PrepareRangeHeaderL( CUpnpHttpMessage* aMsg,
        TBool aServingOutFileName,
        TInt aFileSize, CUpnpHttpServerTransaction &aTransaction, TInt& aRangeStatus,
        TInt& aStartPos, TInt& aEndPos );

    
private: // New funtions

    enum THttpInvalidMessage
        {
        EMessageOk = 0,
        EUnknownMethod
        };
    
    /**
    * Matches an error to a proper HTTP error code
    * @error to be matched
    * @return HTTP error code.
    **/
    TInt MatchHttpError( TInt error );
    /**
    * Checks message validity. Returns type of error.
    * @since Series60 2.6
    * @param aMsg Message to check.
    * @return Errorcode.
    **/
    THttpInvalidMessage IsValidMessage( CUpnpHttpMessage* aMsg );

    
    /**
    * Decides what to do with the message, should it be sent to upper layer,        
    * Takes ownership of a parameter (it should be popped from cleanup stack
    * before call
    * @since Series60 2.6
    * @param aMsg Message to check.
    **/
    void HandleQueryL( CUpnpHttpMessage* aMsg );


    /**
    * Repsonse with HTTP error mesage to remoteServer
    * @since Series60 2.6
    * @param aStatus Number of status code
    **/
    void ResponseErrorL(TInt aStatus);

    
  

    /**
    * Prepares serve a file. Checks that file exists and paths are correct. 
    *  Checks filesize and so on.
    * @since Series60 2.6
    * @param aMsg Message to check.
    * @return error code
    **/
    TInt PrepareToServeFileL( CUpnpHttpMessage* aMsg );

    /**
    * Notifies upper layers that session has disconnected.
    * @since Series60 2.6
    * @param aAddr Address of remote host to which the connection has been
    *  disconnected.
    **/
    void NotifyDisconnectL( TInetAddr aAddr );
    
    /**
    * Notifies upper layers that session has expired
    * @since Series60 3.2        
    **/
    void NotifyTimeoutL();
    
    /**
    * File Transfer Reader callback when upload done
    * @since Series60 3.2        
    **/
    void FileTransferReaderDoneL();
    
    /**
    * File Transfer Reader callback when upload with error
    * @since Series60 3.2        
    * @param error        
    **/    
    void FileTransferReaderErrorL(TInt aError);
    
    /**
    * Resets settings after upload
    * @since Series60 3.2            
    **/
    void ResetSettingsL();
    
    
    /**
    * File Transfer Writer callback when download done
    * @since Series60 3.2                 
    **/
    void FileTransferWriterDoneL();
    
    /**
    * File Transfer Writer callback for handling more downloads
    * @since Series60 3.2               
    **/
    void FileTransferWriterHandleMoreL();
    
    /**
    * Checks session and message against persistence
    * @since Series60 3.2                 
    **/
    void CheckSessionPersistence(CUpnpHttpMessage* aMsg);
    
    /**
    * Notifies upper layers that Socket Server is unable to handle any more data by \
    *  sending Expectation failed HTTP error to upper layers.
    * @since Series60 2.6
    * @param aAddr Address of remote host to which the connection has been tried to connect
    **/
    void SocketServerBusyL( const TInetAddr& aAddr );
    
     /**
    * Notifies upper layers with error message. Method guarantee destrustion of parameter
    * (even when leave ocure), and parameter should be poped from cleanupstack
    * @since Series60 2.6
    * @param aMessage message that will be sent to upper layer.
    **/
    void NotifyUpperLayerLD( CUpnpHttpMessage* aMessage );
    
    /**
    * Checks if session uses Connection close communication.
    * @since Series60 2.6
    **/ 
    void CheckConnectionCloseL();

    /**
    * Callback function. Informs upper layers that HTTP POST has been started 
    *  by sending HTTP error code 801 message to upper layers.
    * @since Series60 2.6
    **/
    void NotifyUpperLayersOnPostL();

    /**
    * Callback function. Informs upper layers that HTTP POST has been finished.
    * @since Series60 2.6
    **/
    void PostingFileCompleteL();
    
    void WriteMsgAndHeaderL( CUpnpHttpMessage* aMsg, const TDesC8& aHeaderToWrite,
        const TDesC& aPathWithNewMethod, TInt aFileSize, TInt aRangeStatus,
        const TInt aStartPos, const TInt aEndPos );
    
    /**
    * Function to cut Ip and port from absoulute Uri in get request, it only cuts them when 
    * they are same as http server ones
    * @since S60 5.1
    **/    
    TPtrC8 PrepareRelativeUriL( const TDesC8& aUri );
    
private: 

    // Request type of last sent message. This is used to store CHttpMessages type. 
    // This information is used by upper layers, not by HttpServer.
    THTTPMsgType iRequestType;

    // Resend counter. This information is used by upper layers, not by HttpServer.
    TInt iRetryCounter;

    // Pointer to owning HttpServer.
    CUpnpHttpServer* iServer;

    // Used to check that notification of receiving of large files has been 
    // sent on this session.
    TBool iRequestedTransferNotifySent;

    // Used to check if session uses Connection close.
    TBool iUsesConnectionClose;

    // Buffer that contains the filename of file, that is meant to be 
    // received and saved.
    HBufC8* iInFilename;
      
    // Should the existing local file be overwritten with the requested content.
    // If not then the new file with name: iInFilename_serialNumber will be created
    // to save incoming content. It's connected only with download.
    TBool iOverwriteExisting;
    
    /* Range request parameters, only used for GET and HEAD requests with 
       Range HTTP header. 
    */
    // Offset of the file that should be requested from server. 
    TInt iOffset;
    
    //Length of file content to be requested.
    TInt iLength; 
    
    // Should the requested offset of the remote file be saved at physical 
    // offset of existing local file.
    // Only for Range requests!
    TBool iSaveAtOffset;
    /**/

    // Buffer that contains the filename of file, that is meant to be sent 
    // out as body of CUpnpHttpMessage.
    HBufC8* iOutFilename;

    // Buffer that contains the name of destination service. Used by upper 
    // layer, not by CUpnpHttpServer
    HBufC8* iDestinationPath;

    // Buffer that contains the name of destination service. Used by upper
    // layer, not by CUpnpHttpServer
    HBufC8* iSenderPath;

    // Pointer used by upper layer, not by CUpnpHttpServer.
    TAny* iPendingRequest;

    // Requests that have not yet been served.
    RPointerArray<CUpnpHttpMessage>* iPendingRequests;

    // Pointer to this session's file access object.
    CUpnpHttpFileAccess* iFileServe;

    // Variable that is used to check if we can delete this session after 
    // we get response from remote end.
    TBool iSessionIsDeletedAfterResponse;
    
    // Flag informing if content-length of incoming message was checked
    // and it's value is not bigger than maximum size allowed.
    TBool iMaximumSizeChecked;
    
    // Flag informing session if message headers were checked
    TBool iHeadersCompleted;

    //error has been notified to the remote client
    TBool iErrorNotified;
    //if received message is chunked-encoded
    TBool iIsChunked;
    };

#endif // C_CUPNPHTTPSESSION_H

// End Of File