2010-12-22 18 views
6

He estado intentando todo este día sin éxito. Por favor ayuda a resolver el problema. En google encontré que muchos usuarios tenían este problema pero en ninguna parte pude encontrar una solución.QT HTTP Publicar problema cuando el servidor requiere cookies

que estoy tratando de hacer HTTP POST en QT C++ & ya he intentado haciendo que en Python (Mi pregunta no es una pregunta pitón, por lo que los profesionales de Qt favor ayuda) .. Lo sé, estoy en algún lugar equivocado en manejo de cookies y todo, así que por favor ayuda. Por favor, brinde soluciones probables.

En python, el código es limpio y simple. He eliminado el manejo de errores y todas las cosas adicionales para hacerlo simple.

url = 'http://www.example.com/' 
data = 'username=abc&password=passwd' 
cj = cookielib.CookieJar() 
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj)) 
usock = opener.open(url, data) 
#>>>>>> NOW, I have the cookiejar <<<<<<<<< 

opener.addheaders = [('Referer','http://www.example.com/xyz.php'),('User-Agent','Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20091020 Ubuntu/9.10 (karmic) Firefox/3.5.3 GTB7.0')] 
data_to_send = 'ABCDEFGH' 
url_send = "http://www.example.com/xyz.php" 
send = opener.open(url_send,data_to_send) 

el equivalente QT he hecho: -

void SmsSender::sendToMyCantos() 
{ 
    manager = new QNetworkAccessManager(this); 
    manager->setCookieJar(new QNetworkCookieJar(manager)); 
    connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(replyFinished(QNetworkReply*))); 
    request.setUrl(QUrl("http://www.mycantos.com")); 
    postData.append("username=abc&password=passwd"); 
    manager->post(request,postData); 
    //>>>>>> So, I feel that I have CookieJar now to make POST <<<<<<< 

    request.setRawHeader("Referer","http://www.example.com/xyz.php"); 
    request.setRawHeader("User-Agent","Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20091020 Ubuntu/9.10 (karmic) Firefox/3.5.3 GTB7.0"); 

    postData.clear(); 
    postData.append("ABCDEFGH"); 
    request.setUrl(QUrl("http://www.example.com/xyz.php")); 

    manager->post(request,postData); 
} 

Ahora el problema es que no soy capaz de hacer lo mismo en QT. Problemas que estoy enfrentando:

  1. galletas de manipulación
  2. Manejo de redirecciones (HTTP 302)
  3. retención cookies para hacer futuro post

Todo esto se hace en automagicamente pitón. A continuación, el código no está directamente relacionado, pero esta codificado para permitir redirecciones en el puesto .. El código es very similar to the link I used to make it..

QUrl SmsSender::redirectUrl(const QUrl& possibleRedirectUrl, 
           const QUrl& oldRedirectUrl) const { 
     //Checking infinite resursions 
     QUrl redirectUrl; 
     if(!possibleRedirectUrl.isEmpty() && 
      possibleRedirectUrl != oldRedirectUrl) { 
       redirectUrl = possibleRedirectUrl; 
     } 
     return redirectUrl; 
} 

void SmsSender::replyFinished(QNetworkReply *reply) 
{ 
    QVariant possibleRedirectUrl = 
      reply->attribute(QNetworkRequest::RedirectionTargetAttribute); 
    QVariant data_size = reply->header(QNetworkRequest::ContentLengthHeader); 
    qDebug()<<data_size.toFloat(); 
    qDebug()<<manager->cookieJar()->cookiesForUrl(QUrl("http://www.example.com")); 

    /* We'll deduct if the redirection is valid in the redirectUrl function */ 
    _urlRedirectedTo = this->redirectUrl(possibleRedirectUrl.toUrl(), 
             _urlRedirectedTo); 

    /* If the URL is not empty, we're being redirected. */ 
    if(!_urlRedirectedTo.isEmpty()) { 
      QString text = QString("SmsSender::replyFinished: Redirected to ") 
            .append(_urlRedirectedTo.toString()); 
    qDebug(text.toAscii()); 

    // Do again in case we have more redirections 

    this->_qnam->get(QNetworkRequest(_urlRedirectedTo)); 
    } 
    else 
    { 
     QString text = QString("SmsSender::replyFinished: Arrived to ") 
            .append(reply->url().toString()); 
     qDebug(text.toAscii()); 
     _urlRedirectedTo.clear(); 
    } 

} 

QNetworkAccessManager* SmsSender::createQNAM() { 
     QNetworkAccessManager* qnam = new QNetworkAccessManager(this); 
     /* We'll handle the finished reply in replyFinished */ 
     connect(qnam, SIGNAL(finished(QNetworkReply*)), 
       this, SLOT(replyFinished(QNetworkReply*))); 
     return qnam; 
} 
+0

Este es mi primer intento de usar QT para hacer una aplicación, así que por favor tengan paciencia si no es correcto según los estándares. –

Respuesta

7

Lo utilizo para obtener una cookie:

SomeDialog::SomeDialog(QWidget *parent) 
    : QDialog(parent) 
     , urlSearch("www.someotherurlyoumightneed.com") 
    , urlCookie("www.urltogetcookie.from") 
{ 
    ui.setupUi(this); 

    //manager is a QNetworkAccessManager 
    manager.setCookieJar(new QNetworkCookieJar); 
    connect(&manager, SIGNAL(finished(QNetworkReply*)), 
     SLOT(slotReplyFinished(QNetworkReply*))); 

    //this is a QNetworkRequest 
    //here i tell how the post methods are encoded 
    searchReq.setUrl(urlSearch); 
    searchReq.setHeader(QNetworkRequest::ContentTypeHeader,"application/x-www-form-urlencoded"); 

    //get cookie 
    manager.get(QNetworkRequest(urlCookie)); 
    lblStatus->setText("Getting cookie"); 
} 

void SomeDialog::slotReplyFinished(QNetworkReply* reply){ 
    reply->deleteLater(); 

    if(reply->error() != QNetworkReply::NoError){ 
     QMessageBox::warning(this,QString(), tr("Error while downloading information!\n%1").arg(reply->errorString())); 

     return; 
    } 

    //Here i check if there is a cookie for me in the reply and extract it 
    QList<QNetworkCookie> cookies = qvariant_cast<QList<QNetworkCookie>>(reply->header(QNetworkRequest::SetCookieHeader)); 
    if(cookies.count() != 0){ 
     //you must tell which cookie goes with which url 
     manager.cookieJar()->setCookiesFromUrl(cookies, urlSearch); 
    } 

    //here you can check for the 302 or whatever other header i need 
    QVariant newLoc = reply->header(QNetworkRequest::LocationHeader); 
    if(newLoc.isValid()){ 
     //if it IS a reloc header, get the url it points to 
     QUrl url(newLoc.toString()); 
     _req.setUrl(url); 
     _pendingReq.insert(_manager.get(_req)); 
     return; 
    } 

    //if you have multiple urls you are waiting for replys 
    //you can check which one this one belongs to with 
    if(reply->url() == urlSearch){ 
     //do something 
    } 
} 

void SomeDialog::slotSearch(){ 
    //Here we set the data needed for a post request 
    QList<QNetworkCookie> cookies = manager.cookieJar()->cookiesForUrl(urlSearch); 
    for(auto it = cookies.begin(); it != cookies.end(); ++it){ 
     searchReq.setHeader(QNetworkRequest::CookieHeader, QVariant::fromValue(*it)); 
    } 

    QUrl post; 
    post.addQueryItem("firstParameter", s); 
    post.addQueryItem("secondParameter", "O"); 
    QByteArray ba; 
    ba.remove(0,1); //must remove last & 

    searchReq.setUrl(urlSearch); 
    pendingReq.insert(manager.post(searchReq, ba)); 
} 

Espero que esto ayude.

0

Creo que las galletas están vinculados a las direcciones URL que se obtienen a partir. Por lo tanto, en su segundo POST con una URL diferente, las cookies del primer POST no se envían con la solicitud.