webengine/osswebengine/WebCore/platform/network/symbian/DataConnection.cpp
changeset 0 dd21522fd290
child 1 7c90e6132015
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2 * Copyright (c) 2007 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 the License "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:  
       
    15 *
       
    16 */
       
    17 
       
    18 #include <f32file.h>
       
    19 #include <uri8.h>
       
    20 #include <EscapeUtils.h>
       
    21 #include <apmrec.h>
       
    22 #include <apgcli.h>
       
    23 #include <imcvcodc.h>
       
    24 #include "ResourceHandle.h"
       
    25 #include "ResourceRequest.h"
       
    26 #include "DataConnection.h"
       
    27 #include "FileReader.h"
       
    28 #include "ResourceHandleManagerSymbian.h"
       
    29 #include "StaticObjectsContainer.h"
       
    30 
       
    31 // EXTERNAL DATA STRUCTURES
       
    32 
       
    33 // EXTERNAL FUNCTION PROTOTYPES
       
    34 
       
    35 // CONSTANTS
       
    36 _LIT8( KDefaultCharset, "iso-8859-1" );
       
    37 _LIT8( KDefaultContentType, "text/plain" );
       
    38 _LIT8( KDataScheme, "data:" );
       
    39 _LIT8( KContentTypeKey, "content type:" );
       
    40 _LIT8( KCharsetKey, "charset=" );
       
    41 
       
    42 // MACROS
       
    43 
       
    44 // LOCAL CONSTANTS AND MACROS
       
    45 
       
    46 // MODULE DATA STRUCTURES
       
    47 
       
    48 // LOCAL FUNCTION PROTOTYPES
       
    49 
       
    50 // FORWARD DECLARATIONS
       
    51 
       
    52 static int s_dataTransactionsCount = 0;
       
    53 
       
    54 using namespace WebCore;
       
    55 
       
    56 DataConnection::DataConnection(ResourceHandle* _handle) : MUrlConnection(_handle)
       
    57 {
       
    58     s_dataTransactionsCount++;
       
    59     m_scheduler = NULL;
       
    60     m_maxSize = 0;
       
    61 }
       
    62 
       
    63 DataConnection::~DataConnection()
       
    64 {
       
    65     s_dataTransactionsCount--;
       
    66     if (m_scheduler) {
       
    67         m_scheduler->Cancel();
       
    68         delete m_scheduler;
       
    69     }
       
    70 }
       
    71 
       
    72 int DataConnection::submit()
       
    73 {
       
    74     TRAPD(error, submitL());
       
    75     return error;
       
    76 }
       
    77 
       
    78 void DataConnection::submitL()
       
    79 {
       
    80     m_scheduler = CPeriodic::NewL( CActive::EPriorityStandard );
       
    81     m_scheduler->Start( 0, 0, TCallBack( &sendResponseCb, this ) );
       
    82 }
       
    83 
       
    84 void DataConnection::parseUrlLC(HBufC8*& contentType, HBufC8*& encoding, HBufC8*& body)
       
    85 {
       
    86     TPtrC8 url = m_handle->request().url().des();
       
    87     // set content type and content encoding
       
    88     // parse url to get header information
       
    89     // http://www.faqs.org/rfcs/rfc2397.html
       
    90     // 3. Syntax
       
    91 
       
    92     // dataurl    := "data:" [ mediatype ] [ ";base64" ] "," data
       
    93     // mediatype  := [ type "/" subtype ] *( ";" parameter )
       
    94     // data       := *urlchar
       
    95     // parameter  := attribute "=" value
       
    96     //
       
    97     // data:text/plain;charset=iso-8859-7,%be%fg%be
       
    98 
       
    99     TPtrC8 urlPtr8 =  m_handle->request().url().des();
       
   100     TInt colonPos( urlPtr8.Locate( ',' ) );
       
   101     if( colonPos != KErrNotFound ) {
       
   102         // set header including ,
       
   103         TPtrC8 headersStr( urlPtr8.Left( colonPos + 1 ) );
       
   104         // cut off scheme data:
       
   105         headersStr.Set( headersStr.Mid( KDataScheme().Length() ) );
       
   106         // check for ;base64
       
   107         TBool base64( headersStr.Find( _L8( ";base64" ) ) != KErrNotFound );
       
   108         // check for ;
       
   109         TInt semicolonPos;
       
   110         do {
       
   111             semicolonPos = headersStr.Locate( ';' );
       
   112             // no semicolon means one mediatype. set semiPos to the end of the str
       
   113             // unless we are at the end of the string
       
   114             if( headersStr.Length() > 1 ) {
       
   115                 semicolonPos = semicolonPos == -1 ? headersStr.Length() - 1 : semicolonPos;
       
   116             }
       
   117             if( semicolonPos != -1 ) {
       
   118                 // str = text/plain
       
   119                 TPtrC8 str( headersStr.Left( semicolonPos ) );
       
   120                 if( str.Locate( '/' ) != KErrNotFound ) {
       
   121                     contentType = str.AllocLC();
       
   122                 }
       
   123                 else if( str.Find( KCharsetKey ) == 0 ) {
       
   124                     encoding = (str.Mid( KCharsetKey().Length()).AllocLC());
       
   125                 }
       
   126                 // headersStr = charset=iso-8859-7,%be%fg%be
       
   127                 headersStr.Set( headersStr.Mid( semicolonPos + 1 ) );
       
   128             }
       
   129         }
       
   130         while( semicolonPos != KErrNotFound );
       
   131         // simulate header strings
       
   132         // content type: text/html
       
   133         // charset: iso-8859-1
       
   134         if (contentType == NULL) {
       
   135             contentType = KDefaultContentType().AllocLC();
       
   136         }
       
   137         if (encoding == NULL) {
       
   138             encoding = KDefaultCharset().AllocLC();
       
   139         }
       
   140 
       
   141         // make sure there is stuff to decode
       
   142         if( ( colonPos + 1 ) < urlPtr8.Length() ) {
       
   143             TBool ok( EFalse );
       
   144             TPtrC8 data( urlPtr8.Mid( colonPos + 1 ) );
       
   145             // decode body
       
   146             if( base64 ) {
       
   147                 // allocate twice as big buffer for decoded string
       
   148                 body = HBufC8::NewLC( 2 * data.Length() );
       
   149                 TPtr8 decodedBody( body->Des() );
       
   150                 // urlPtr8
       
   151                 TImCodecB64 codec;
       
   152                 codec.Initialise();
       
   153                 ok = codec.Decode( data, decodedBody );
       
   154             }
       
   155             if( !ok ) { // if not base64, simple copy
       
   156                 if( !body ) {
       
   157                     body = HBufC8::NewLC( data.Length() );
       
   158                 }
       
   159                 body->Des().Copy( data );
       
   160             }
       
   161         }
       
   162     }
       
   163     m_maxSize = body->Length();
       
   164 }
       
   165 
       
   166 void DataConnection::cancel()
       
   167 {
       
   168     if (m_scheduler) {
       
   169         m_scheduler->Cancel();
       
   170         delete m_scheduler;
       
   171         m_scheduler = NULL;
       
   172     }
       
   173 }
       
   174 
       
   175 void DataConnection::download(WebCore::ResourceHandle* handle,
       
   176                               const WebCore::ResourceRequest& request,
       
   177                               const WebCore::ResourceResponse& response)
       
   178 {
       
   179     __ASSERT_ALWAYS(EFalse, User::Panic(_L("Resource Loader"), KErrArgument));
       
   180 }
       
   181 
       
   182 TInt DataConnection::sendResponseCb(TAny* aPtr)
       
   183 {
       
   184     DataConnection* self = static_cast<DataConnection*>(aPtr);
       
   185     TRAPD(error, self->sendResponseL());
       
   186     if (error != KErrNone) {
       
   187         CResourceHandleManager::self()->receivedFinished(self->m_handle, error, self);
       
   188     }
       
   189     return KErrNone;
       
   190 }
       
   191 
       
   192 void DataConnection::sendResponseL()
       
   193 {
       
   194     m_scheduler->Cancel();
       
   195     delete m_scheduler;
       
   196     m_scheduler = NULL;
       
   197 
       
   198     HBufC8* contentType = NULL;
       
   199     HBufC8* encoding = NULL;
       
   200     HBufC8* body = NULL;
       
   201     parseUrlLC(contentType, encoding, body);
       
   202 
       
   203     ResourceResponse response(m_handle->request().url().des(), contentType->Des(), body->Length(), encoding->Des(), String() );
       
   204     CResourceHandleManager::self()->receivedResponse(m_handle, response, this);
       
   205     CResourceHandleManager::self()->receivedData(m_handle, body->Des(), body->Length(), this);
       
   206     CResourceHandleManager::self()->receivedFinished(m_handle, KErrNone, this);
       
   207     CleanupStack::PopAndDestroy(3); // contentType, encoding, body
       
   208     derefHandle();
       
   209     }
       
   210 
       
   211 // end of file