utilities/downloadmanager/src/httpdownloadbackend.cpp
author hgs
Fri, 15 Oct 2010 17:30:59 -0400
changeset 16 3c88a81ff781
permissions -rw-r--r--
201041
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
16
hgs
parents:
diff changeset
     1
/**
hgs
parents:
diff changeset
     2
   This file is part of CWRT package **
hgs
parents:
diff changeset
     3
hgs
parents:
diff changeset
     4
   Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). **
hgs
parents:
diff changeset
     5
hgs
parents:
diff changeset
     6
   This program is free software: you can redistribute it and/or modify
hgs
parents:
diff changeset
     7
   it under the terms of the GNU (Lesser) General Public License as 
hgs
parents:
diff changeset
     8
   published by the Free Software Foundation, version 2.1 of the License. 
hgs
parents:
diff changeset
     9
   This program is distributed in the hope that it will be useful, but
hgs
parents:
diff changeset
    10
   WITHOUT ANY WARRANTY; without even the implied warranty of 
hgs
parents:
diff changeset
    11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
hgs
parents:
diff changeset
    12
   (Lesser) General Public License for more details. You should have 
hgs
parents:
diff changeset
    13
   received a copy of the GNU (Lesser) General Public License along 
hgs
parents:
diff changeset
    14
   with this program. If not, see <http://www.gnu.org/licenses/>.
hgs
parents:
diff changeset
    15
*/
hgs
parents:
diff changeset
    16
hgs
parents:
diff changeset
    17
#include "clientdownload.h"
hgs
parents:
diff changeset
    18
#include "downloadmanager.h"
hgs
parents:
diff changeset
    19
#include "downloadcore.h"
hgs
parents:
diff changeset
    20
#include "downloadstore.h"
hgs
parents:
diff changeset
    21
#include "httpdownloadbackend.h"
hgs
parents:
diff changeset
    22
#include "filestorage.h"
hgs
parents:
diff changeset
    23
#include "dmcommoninternal.h"
hgs
parents:
diff changeset
    24
#include <QFileInfo>
hgs
parents:
diff changeset
    25
#include <QString>
hgs
parents:
diff changeset
    26
#include <QMap>
hgs
parents:
diff changeset
    27
#include <QIODevice>
hgs
parents:
diff changeset
    28
hgs
parents:
diff changeset
    29
// private implementation
hgs
parents:
diff changeset
    30
class HttpDownloadBackendPrivate
hgs
parents:
diff changeset
    31
{
hgs
parents:
diff changeset
    32
    DM_DECLARE_PUBLIC(HttpDownloadBackend);
hgs
parents:
diff changeset
    33
public:
hgs
parents:
diff changeset
    34
    HttpDownloadBackendPrivate();
hgs
parents:
diff changeset
    35
    ~HttpDownloadBackendPrivate();
hgs
parents:
diff changeset
    36
    DownloadCore *m_downloadCore; // for network operations
hgs
parents:
diff changeset
    37
    DownloadStore *m_storage; // responsible for handling the storage
hgs
parents:
diff changeset
    38
    ClientDownload *m_download; // not owned
hgs
parents:
diff changeset
    39
};  
hgs
parents:
diff changeset
    40
hgs
parents:
diff changeset
    41
HttpDownloadBackendPrivate::HttpDownloadBackendPrivate()
hgs
parents:
diff changeset
    42
{
hgs
parents:
diff changeset
    43
    m_downloadCore = 0; 
hgs
parents:
diff changeset
    44
    m_storage = 0;
hgs
parents:
diff changeset
    45
    m_download = 0;
hgs
parents:
diff changeset
    46
}
hgs
parents:
diff changeset
    47
hgs
parents:
diff changeset
    48
HttpDownloadBackendPrivate::~HttpDownloadBackendPrivate()
hgs
parents:
diff changeset
    49
{
hgs
parents:
diff changeset
    50
    if(m_storage)
hgs
parents:
diff changeset
    51
    {
hgs
parents:
diff changeset
    52
        delete m_storage;
hgs
parents:
diff changeset
    53
        m_storage = 0;
hgs
parents:
diff changeset
    54
    }
hgs
parents:
diff changeset
    55
}
hgs
parents:
diff changeset
    56
hgs
parents:
diff changeset
    57
HttpDownloadBackend::HttpDownloadBackend(DownloadCore *dlCore, ClientDownload *dl, DownloadStore* store)
hgs
parents:
diff changeset
    58
    :DownloadBackend(dlCore, dl)
hgs
parents:
diff changeset
    59
{
hgs
parents:
diff changeset
    60
    DM_INITIALIZE(HttpDownloadBackend);
hgs
parents:
diff changeset
    61
    priv->m_downloadCore = dlCore;
hgs
parents:
diff changeset
    62
    priv->m_storage = store; 
hgs
parents:
diff changeset
    63
    priv->m_download = dl;
hgs
parents:
diff changeset
    64
    setValue(DownloadInfo::EFinalPath, dl->attributes().value(DlDestPath).toString());
hgs
parents:
diff changeset
    65
hgs
parents:
diff changeset
    66
    QString fileName;
hgs
parents:
diff changeset
    67
    if(dl->isCreatedByDlInfo())
hgs
parents:
diff changeset
    68
    {
hgs
parents:
diff changeset
    69
        getValue(DownloadInfo::EFileName, fileName);
hgs
parents:
diff changeset
    70
        dl->attributes().insert(DlFileName, fileName);
hgs
parents:
diff changeset
    71
        priv->m_storage->open(QIODevice::Append);           
hgs
parents:
diff changeset
    72
    }
hgs
parents:
diff changeset
    73
    else
hgs
parents:
diff changeset
    74
    {
hgs
parents:
diff changeset
    75
        fileName = dl->attributes().value(DlFileName).toString();
hgs
parents:
diff changeset
    76
        // if filename is not set, take it from url
hgs
parents:
diff changeset
    77
        if(fileName.length() == 0) {
hgs
parents:
diff changeset
    78
            fileName = priv->m_downloadCore->fileNameFromContentDispositionHeader();
hgs
parents:
diff changeset
    79
            if(fileName.length() == 0) {
hgs
parents:
diff changeset
    80
                QUrl url(priv->m_downloadCore->url());
hgs
parents:
diff changeset
    81
                QFileInfo fileUrl(url.path());
hgs
parents:
diff changeset
    82
                fileName = fileUrl.fileName();     
hgs
parents:
diff changeset
    83
            }         
hgs
parents:
diff changeset
    84
        }
hgs
parents:
diff changeset
    85
        dl->attributes().insert(DlFileName, fileName);
hgs
parents:
diff changeset
    86
        // create the new storage
hgs
parents:
diff changeset
    87
        priv->m_storage->createStore();      
hgs
parents:
diff changeset
    88
    }
hgs
parents:
diff changeset
    89
    setValue(DownloadInfo::EFileName, download()->attributes().value(DlFileName).toString());
hgs
parents:
diff changeset
    90
}
hgs
parents:
diff changeset
    91
hgs
parents:
diff changeset
    92
HttpDownloadBackend::~HttpDownloadBackend()
hgs
parents:
diff changeset
    93
{
hgs
parents:
diff changeset
    94
    DM_UNINITIALIZE(HttpDownloadBackend);
hgs
parents:
diff changeset
    95
}
hgs
parents:
diff changeset
    96
hgs
parents:
diff changeset
    97
int HttpDownloadBackend::resume()
hgs
parents:
diff changeset
    98
{
hgs
parents:
diff changeset
    99
    DM_PRIVATE(HttpDownloadBackend);
hgs
parents:
diff changeset
   100
    // Open the file in append mode as we need to append the received chunks    
hgs
parents:
diff changeset
   101
    if(downloadState() != DlCancelled)
hgs
parents:
diff changeset
   102
    {
hgs
parents:
diff changeset
   103
        priv->m_storage->open(QIODevice::Append);               
hgs
parents:
diff changeset
   104
    }
hgs
parents:
diff changeset
   105
    else
hgs
parents:
diff changeset
   106
    {
hgs
parents:
diff changeset
   107
        QString fileName = download()->attributes().value(DlFileName).toString();
hgs
parents:
diff changeset
   108
        // if filename is not set, take it from url 
hgs
parents:
diff changeset
   109
        if(fileName.length() == 0) {
hgs
parents:
diff changeset
   110
            fileName = priv->m_downloadCore->fileNameFromContentDispositionHeader();
hgs
parents:
diff changeset
   111
            if(fileName.length() == 0) {
hgs
parents:
diff changeset
   112
                QUrl url(priv->m_downloadCore->url());
hgs
parents:
diff changeset
   113
                QFileInfo fileUrl(url.path());
hgs
parents:
diff changeset
   114
                fileName = fileUrl.fileName();     
hgs
parents:
diff changeset
   115
            }         
hgs
parents:
diff changeset
   116
        }
hgs
parents:
diff changeset
   117
        download()->attributes().insert(DlFileName, fileName);
hgs
parents:
diff changeset
   118
        // create the new storage
hgs
parents:
diff changeset
   119
        priv->m_storage->createStore(); 
hgs
parents:
diff changeset
   120
    }
hgs
parents:
diff changeset
   121
    setValue(DownloadInfo::EFileName, download()->attributes().value(DlFileName).toString());
hgs
parents:
diff changeset
   122
    return DownloadBackend::resume();
hgs
parents:
diff changeset
   123
}
hgs
parents:
diff changeset
   124
hgs
parents:
diff changeset
   125
void HttpDownloadBackend::store(QByteArray data, bool lastChunk)
hgs
parents:
diff changeset
   126
{
hgs
parents:
diff changeset
   127
    DM_PRIVATE(HttpDownloadBackend); 
hgs
parents:
diff changeset
   128
    // write the chunks to the storage
hgs
parents:
diff changeset
   129
    priv->m_storage->write(data, lastChunk); 
hgs
parents:
diff changeset
   130
}
hgs
parents:
diff changeset
   131
hgs
parents:
diff changeset
   132
void HttpDownloadBackend::deleteStore()
hgs
parents:
diff changeset
   133
{
hgs
parents:
diff changeset
   134
    DM_PRIVATE(HttpDownloadBackend);
hgs
parents:
diff changeset
   135
    if(priv->m_storage)
hgs
parents:
diff changeset
   136
    {
hgs
parents:
diff changeset
   137
        priv->m_storage->deleteStore();
hgs
parents:
diff changeset
   138
    }
hgs
parents:
diff changeset
   139
}
hgs
parents:
diff changeset
   140
hgs
parents:
diff changeset
   141
qint64 HttpDownloadBackend::storedDataSize()
hgs
parents:
diff changeset
   142
{
hgs
parents:
diff changeset
   143
    DM_PRIVATE(HttpDownloadBackend);
hgs
parents:
diff changeset
   144
    // size of stored data chunk
hgs
parents:
diff changeset
   145
    return priv->m_storage->storedDataSize();
hgs
parents:
diff changeset
   146
}
hgs
parents:
diff changeset
   147
hgs
parents:
diff changeset
   148
QVariant HttpDownloadBackend::getAttribute(DownloadAttribute attr)
hgs
parents:
diff changeset
   149
{
hgs
parents:
diff changeset
   150
    DM_PRIVATE(HttpDownloadBackend);
hgs
parents:
diff changeset
   151
    switch(attr)
hgs
parents:
diff changeset
   152
    {
hgs
parents:
diff changeset
   153
        case DlFileName:
hgs
parents:
diff changeset
   154
        {
hgs
parents:
diff changeset
   155
            if(priv->m_download)
hgs
parents:
diff changeset
   156
                return priv->m_download->attributes().value(attr);
hgs
parents:
diff changeset
   157
        }
hgs
parents:
diff changeset
   158
        case DlDestPath:
hgs
parents:
diff changeset
   159
        {
hgs
parents:
diff changeset
   160
            if(priv->m_download)
hgs
parents:
diff changeset
   161
                return priv->m_download->attributes().value(attr);
hgs
parents:
diff changeset
   162
        }
hgs
parents:
diff changeset
   163
        default:
hgs
parents:
diff changeset
   164
            break;
hgs
parents:
diff changeset
   165
    }  
hgs
parents:
diff changeset
   166
    return DownloadBackend::getAttribute(attr);
hgs
parents:
diff changeset
   167
}
hgs
parents:
diff changeset
   168
hgs
parents:
diff changeset
   169
int HttpDownloadBackend::setAttribute(DownloadAttribute attr, const QVariant& value)
hgs
parents:
diff changeset
   170
{
hgs
parents:
diff changeset
   171
    return DownloadBackend::setAttribute(attr, value);
hgs
parents:
diff changeset
   172
}
hgs
parents:
diff changeset
   173
hgs
parents:
diff changeset
   174
void HttpDownloadBackend::headerReceived()
hgs
parents:
diff changeset
   175
{
hgs
parents:
diff changeset
   176
    DM_PRIVATE(HttpDownloadBackend);
hgs
parents:
diff changeset
   177
    DlEventAttributeMap* attrMap = NULL;
hgs
parents:
diff changeset
   178
    HttpStatusCode status = (HttpStatusCode) priv->m_downloadCore->reply()->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
hgs
parents:
diff changeset
   179
    switch(status)
hgs
parents:
diff changeset
   180
    {
hgs
parents:
diff changeset
   181
        case HttpOK:                    // OK
hgs
parents:
diff changeset
   182
        case HttpCreated:               // Created
hgs
parents:
diff changeset
   183
        case HttpAccepted:              // Accepted
hgs
parents:
diff changeset
   184
        case HttpNonAuthorativeInfo:    // Non-Authorative Information
hgs
parents:
diff changeset
   185
        case HttpNoContent:             // No Content
hgs
parents:
diff changeset
   186
        case HttpResetContent:          // Reset Conetent
hgs
parents:
diff changeset
   187
        {
hgs
parents:
diff changeset
   188
            // get the content type and save it in dl info
hgs
parents:
diff changeset
   189
            QString contentType = priv->m_downloadCore->contentType();
hgs
parents:
diff changeset
   190
            setValue(DownloadInfo::EContentType, contentType);
hgs
parents:
diff changeset
   191
            setDownloadState(DlInprogress);
hgs
parents:
diff changeset
   192
            break;
hgs
parents:
diff changeset
   193
        }
hgs
parents:
diff changeset
   194
hgs
parents:
diff changeset
   195
        case HttpPartialContent:        // Partial Conetent Download
hgs
parents:
diff changeset
   196
        {
hgs
parents:
diff changeset
   197
            setDownloadState(DlInprogress);
hgs
parents:
diff changeset
   198
            break;
hgs
parents:
diff changeset
   199
        }
hgs
parents:
diff changeset
   200
        
hgs
parents:
diff changeset
   201
        case HttpPreconditionFailed:    // Precondition Failed
hgs
parents:
diff changeset
   202
        {
hgs
parents:
diff changeset
   203
            // attrMap will be deleted in destructor of DownloadEventPrivate class
hgs
parents:
diff changeset
   204
            attrMap = new DlEventAttributeMap ;
hgs
parents:
diff changeset
   205
            attrMap->insert(HeaderReceivedStatusCode, QVariant(status));
hgs
parents:
diff changeset
   206
            break;
hgs
parents:
diff changeset
   207
        }
hgs
parents:
diff changeset
   208
hgs
parents:
diff changeset
   209
        default:
hgs
parents:
diff changeset
   210
           break;
hgs
parents:
diff changeset
   211
    }
hgs
parents:
diff changeset
   212
hgs
parents:
diff changeset
   213
    postEvent(HeaderReceived, attrMap);
hgs
parents:
diff changeset
   214
}
hgs
parents:
diff changeset
   215
hgs
parents:
diff changeset
   216
hgs
parents:
diff changeset
   217