HTTP status code and custom URL schemes



  • Hi all,
    I have to add support for a custom scheme to QWebView so that a javascript call to XMLHttpRequest([custom scheme URL]) returns the HTTP status code, even if the URL doesn't have an HTTP scheme.

    In a similar way as described in "Adding New Protocols" http://doc.qt.digia.com/qq/32/qq32-webkit-protocols.html, I subclass QNetworkAccessManager and reimplement its createRequest() function to check for URLs with my custom scheme.
    I also subclass QNetworkReply to reimplement bytesAvailable() and readData().

    When the content at the custom URL is available I set the headers
    @setAttribute(QNetworkRequest::HttpStatusCodeAttribute,QVariant(200));
    setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/html; charset=UTF-8"));
    setHeader(QNetworkRequest::ContentLengthHeader, QVariant((uint)new_content_size));@

    and emit readRead and finished
    @QTimer::singleShot( 0, this, SIGNAL(readyRead()) );
    QTimer::singleShot( 0, this, SIGNAL(finished()) );@

    but XMLHttpRequest dosn't return the HTTP status code I set with
    @setAttribute(QNetworkRequest::HttpStatusCodeAttribute,QVariant(200));@

    I suspect this happens because in QNetworkReplyHandler.cpp (void QNetworkReplyHandler::sendResponseIfNeeded()) the URL is tested against "url.protocolInHTTPFamily()" before setting the HTTP status code in the response. Is my understanding correct?

    Is there a way to force my Reply to return the HTTP status code, when the URL scheme is not actually HTTP?

    Thanks


  • Moderators

    what happens if you additionally do this on the response?
    @
    setRawHeader("Status","200 OK");
    @



  • Thanks a lot raven-worx,

    I am about to give it a go, but I already have the feeling it's not going to help.
    The reason why I think so is because in the file I mentioned (QNetworkReplyHandler.cpp) the same test that skips the status code setting, also skips the raw header setting:

    @
    if (url.protocolInHTTPFamily()) {
    String suggestedFilename = filenameFromHTTPContentDisposition(QString::fromLatin1(m_replyWrapper->reply()->rawHeader("Content-Disposition")));

    if (!suggestedFilename.isEmpty())
    response.setSuggestedFilename(suggestedFilename);
    else
    response.setSuggestedFilename(url.lastPathComponent());
    response.setHTTPStatusCode(statusCode);
    response.setHTTPStatusText(
    m_replyWrapper->reply()->attribute(
    QNetworkRequest::HttpReasonPhraseAttribute
    ).toByteArray().constData()
    );

    // Add remaining headers.
    foreach (const QNetworkReply::RawHeaderPair& pair,
    m_replyWrapper->reply()->rawHeaderPairs()
    )
    response.setHTTPHeaderField(
    QString::fromLatin1(pair.first), QString::fromLatin1(pair.second)
    );
    }
    @

    So the HTTPHeaderField is set with the pairs in the RawHeader only for HTTP URLs, hence should be skipped in all the custom scheme URLs.

    Thanks


  • Moderators

    ok got you.
    Since you anyway reimplemented QNAM::createRequest(), can't you just replace the protocol (of the url) to http after you've checked for your custom protocol?



  • Hi raven-worx,

    It's been a while before I could try it but your suggestion does work!

    Thanks a lot,
    Sergio


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.