Exemple #1
0
/**
  This method will ...
*
@param [inout] reqData: ...
@param [out] error: error description for an invalid request
*
@return: can we serve this request?
*******************************************************************************/
std::string CuteHttpParser::makeOkResp(CuteSrvRequest& reqData, const std::string& respStr)
{
    QHttpResponseHeader ok;

    ok.setStatusLine(200);
    ok.addValue("Content-Type", "text/html");
    ok.setContentLength(respStr.size());  

    string resp = ok.toString().toLatin1().constData();;

    // add content
    resp.append(respStr);
    resp.append(c_httpLineEnd);

    return resp;
}
Exemple #2
0
/**
  This method will ...
*
@param [inout] reqData: ...
@param [out] error: error description for an invalid request
*
@return: can we serve this request?
*******************************************************************************/
std::string CuteHttpParser::makeErrorResp(CuteSrvRequest& reqData, int errCode,
                                          const std::string& errStr)
{
    // format err string:
    // OPEN TODO:: error pages???
    string errPage("<html><body><h2>");
    errPage.append(errStr);
    errPage.append("</h2></body></html>");

    QHttpResponseHeader err;

    err.setStatusLine(errCode, "");
    err.addValue("Content-Type", "text/html");
    err.setContentLength(errPage.size());    

    string resp = err.toString().toLatin1().constData();

    // add content
    resp.append(errPage);
    resp.append(c_httpLineEnd);

    return resp;
}
/*!
 * \reimp
 */
void QxtHttpSessionManager::processEvents()
{
    if (QThread::currentThreadId() != qxt_d().mainThread)
    {
        QMetaObject::invokeMethod(this, "processEvents", Qt::QueuedConnection);
        return;
    }
    QxtHttpSessionManagerPrivate& d = qxt_d();
    QMutexLocker locker(&d.eventLock);
    if (!d.eventQueue.count()) return;

    int ct = d.eventQueue.count(), sessionID = 0, requestID = 0, pagePos = -1;
    QxtWebRedirectEvent* re = 0;
    QxtWebPageEvent* pe = 0;
    for (int i = 0; i < ct; i++)
    {
        if (d.eventQueue[i]->type() != QxtWebEvent::Page && d.eventQueue[i]->type() != QxtWebEvent::Redirect) continue;
        pagePos = i;
        sessionID = d.eventQueue[i]->sessionID;
        if (d.eventQueue[pagePos]->type() == QxtWebEvent::Redirect)
        {
            re = static_cast<QxtWebRedirectEvent*>(d.eventQueue[pagePos]);
        }
        pe = static_cast<QxtWebPageEvent*>(d.eventQueue[pagePos]);
        requestID = pe->requestID;
        break;
    }
    if (pagePos == -1) return; // no pages to send yet

    QHttpResponseHeader header;
    QList<int> removeIDs;
    QxtWebEvent* e = 0;
    for (int i = 0; i < pagePos; i++)
    {
        if (d.eventQueue[i]->sessionID != sessionID) continue;
        e = d.eventQueue[i];
        if (e->type() == QxtWebEvent::StoreCookie)
        {
            QxtWebStoreCookieEvent* ce = static_cast<QxtWebStoreCookieEvent*>(e);
            QString cookie = ce->name + '=' + ce->data;
            if (!ce->path.isEmpty())
                cookie += "; path=" + ce->path;
            if (ce->expiration.isValid())
            {
                cookie += "; max-age=" + QString::number(QDateTime::currentDateTime().secsTo(ce->expiration))
                          + "; expires=" + ce->expiration.toUTC().toString("ddd, dd-MMM-YYYY hh:mm:ss GMT");
            }
            header.addValue("set-cookie", cookie);
            removeIDs.push_front(i);
        }
        else if (e->type() == QxtWebEvent::RemoveCookie)
        {
            QxtWebRemoveCookieEvent* ce = static_cast<QxtWebRemoveCookieEvent*>(e);
            QString path;
            if(!ce->path.isEmpty()) path = "path=" + ce->path + "; ";
            header.addValue("set-cookie", ce->name + "=; "+path+"max-age=0; expires=" + QDateTime(QDate(1970, 1, 1)).toString("ddd, dd-MMM-YYYY hh:mm:ss GMT"));
            removeIDs.push_front(i);
        }
    }
    removeIDs.push_front(pagePos);

    QIODevice* device = connector()->getRequestConnection(requestID);
    QxtWebContent* content = qobject_cast<QxtWebContent*>(device);
    // TODO: This should only be invoked when pipelining occurs
    // In theory it shouldn't cause any problems as POST is specced to not be pipelined
    if (content) content->ignoreRemainingContent();
    QHash<QPair<int,int>,QxtWebRequestEvent*>::iterator iPending =
	qxt_d().pendingRequests.find(QPair<int,int>(sessionID, requestID));
    if(iPending != qxt_d().pendingRequests.end()){
	delete *iPending;
	qxt_d().pendingRequests.erase(iPending);
    }

    QxtHttpSessionManagerPrivate::ConnectionState& state = qxt_d().connectionState[connector()->getRequestConnection(requestID)];
    QIODevice* source;
    header.setStatusLine(pe->status, pe->statusMessage, state.httpMajorVersion, state.httpMinorVersion);

    if (re)
    {
        header.setValue("location", re->destination);
    }

    // Set custom header values
    for (QMultiHash<QString, QString>::iterator it = pe->headers.begin(); it != pe->headers.end(); ++it)
    {
        header.setValue(it.key(), it.value());
    }

    header.setContentType(pe->contentType);
    if (state.httpMajorVersion == 0 || (state.httpMajorVersion == 1 && state.httpMinorVersion == 0))
        pe->chunked = false;

    source = pe->dataSource;
    state.finishedTransfer = false;
    bool emptyContent = !source->bytesAvailable() && !pe->streaming;
    state.readyRead = source->bytesAvailable();
    state.streaming = pe->streaming;

    if (emptyContent)
    {
        header.setValue("connection", "close");
        connector()->writeHeaders(device, header);
        closeConnection(requestID);
    }
    else
    {
        pe->dataSource = 0;     // so that it isn't destroyed when the event is deleted
        state.clearHandlers();  // disconnect old handlers

        if (!pe->chunked)
        {
            state.keepAlive = false;
            state.onBytesWritten = QxtMetaObject::bind(this, SLOT(sendNextBlock(int, QObject*)), Q_ARG(int, requestID), Q_ARG(QObject*, source));
            state.onReadyRead = QxtMetaObject::bind(this, SLOT(blockReadyRead(int, QObject*)), Q_ARG(int, requestID), Q_ARG(QObject*, source));
            state.onAboutToClose = QxtMetaObject::bind(this, SLOT(closeConnection(int)), Q_ARG(int, requestID));
        }
        else
        {