@ -1,7 +1,7 @@
/*
/*
* Bittorrent Client using Qt and libtorrent .
* Bittorrent Client using Qt and libtorrent .
* Copyright ( C ) 2014 Vladimir Golovnev < glassez @ yandex . ru >
* Copyright ( C ) 2014 Vladimir Golovnev < glassez @ yandex . ru >
* Copyright ( C ) 2006 Ishan Arora and Christophe Dumez
* Copyright ( C ) 2006 Ishan Arora and Christophe Dumez < chris @ qbittorrent . org >
*
*
* This program is free software ; you can redistribute it and / or
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* modify it under the terms of the GNU General Public License
@ -25,16 +25,15 @@
* modify file ( s ) , you may extend this exception to your version of the file ( s ) ,
* modify file ( s ) , you may extend this exception to your version of the file ( s ) ,
* but you are not obligated to do so . If you do not wish to do so , delete this
* but you are not obligated to do so . If you do not wish to do so , delete this
* exception statement from your version .
* exception statement from your version .
*
* Contact : chris @ qbittorrent . org
*/
*/
# include "requestparser.h"
# include <QDebug>
# include <QDir>
# include <QStringList>
# include <QStringList>
# include <QUrl>
# include <QUrl>
# include <QUrlQuery>
# include <QUrlQuery>
# include <QDir>
# include <QDebug>
# include "requestparser.h"
const QByteArray EOL ( " \r \n " ) ;
const QByteArray EOL ( " \r \n " ) ;
const QByteArray EOH ( " \r \n \r \n " ) ;
const QByteArray EOH ( " \r \n \r \n " ) ;
@ -64,37 +63,37 @@ RequestParser::ErrorCode RequestParser::parseHttpRequest(const QByteArray& data,
m_request = Request ( ) ;
m_request = Request ( ) ;
// Parse HTTP request header
// Parse HTTP request header
const int header_e nd = data . indexOf ( EOH ) ;
const int headerE nd = data . indexOf ( EOH ) ;
if ( header_e nd < 0 ) {
if ( headerE nd < 0 ) {
qDebug ( ) < < Q_FUNC_INFO < < " incomplete request " ;
qDebug ( ) < < Q_FUNC_INFO < < " incomplete request " ;
return IncompleteRequest ;
return IncompleteRequest ;
}
}
if ( ! parseHttpHeader ( data . left ( header_e nd ) ) ) {
if ( ! parseHttpHeader ( data . left ( headerE nd ) ) ) {
qWarning ( ) < < Q_FUNC_INFO < < " header parsing error " ;
qWarning ( ) < < Q_FUNC_INFO < < " header parsing error " ;
return BadRequest ;
return BadRequest ;
}
}
// Parse HTTP request message
// Parse HTTP request message
if ( m_request . headers . contains ( " content-length " ) ) {
if ( m_request . headers . contains ( " content-length " ) ) {
int content_l ength = m_request . headers [ " content-length " ] . toInt ( ) ;
int contentL ength = m_request . headers [ " content-length " ] . toInt ( ) ;
if ( content_l ength < 0 ) {
if ( contentL ength < 0 ) {
qWarning ( ) < < Q_FUNC_INFO < < " bad request: content-length negative " ;
qWarning ( ) < < Q_FUNC_INFO < < " bad request: content-length is negative " ;
return BadRequest ;
return BadRequest ;
}
}
if ( content_l ength > static_cast < int > ( m_maxContentLength ) ) {
if ( contentL ength > static_cast < int > ( m_maxContentLength ) ) {
qWarning ( ) < < Q_FUNC_INFO < < " bad request: message too long " ;
qWarning ( ) < < Q_FUNC_INFO < < " bad request: message too long " ;
return BadRequest ;
return BadRequest ;
}
}
QByteArray content = data . mid ( header_e nd + EOH . length ( ) , content_l ength ) ;
QByteArray content = data . mid ( headerE nd + EOH . length ( ) , contentL ength ) ;
if ( content . length ( ) < content_l ength ) {
if ( content . length ( ) < contentL ength ) {
qDebug ( ) < < Q_FUNC_INFO < < " incomplete request " ;
qDebug ( ) < < Q_FUNC_INFO < < " incomplete request " ;
return IncompleteRequest ;
return IncompleteRequest ;
}
}
if ( ( content_l ength > 0 ) & & ! parseContent ( content ) ) {
if ( ( contentL ength > 0 ) & & ! parseContent ( content ) ) {
qWarning ( ) < < Q_FUNC_INFO < < " message parsing error " ;
qWarning ( ) < < Q_FUNC_INFO < < " message parsing error " ;
return BadRequest ;
return BadRequest ;
}
}
@ -102,7 +101,7 @@ RequestParser::ErrorCode RequestParser::parseHttpRequest(const QByteArray& data,
// qDebug() << Q_FUNC_INFO;
// qDebug() << Q_FUNC_INFO;
// qDebug() << "HTTP Request header:";
// qDebug() << "HTTP Request header:";
// qDebug() << data.left(header_e nd) << "\n";
// qDebug() << data.left(headerE nd) << "\n";
request = m_request ;
request = m_request ;
return NoError ;
return NoError ;
@ -243,14 +242,14 @@ Content-Disposition: form-data; name=\"Upload\"
Submit Query
Submit Query
- - cH2ae0GI3KM7GI3Ij5ae0ei4Ij5Ij5 - -
- - cH2ae0GI3KM7GI3Ij5ae0ei4Ij5Ij5 - -
* */
* */
QString content_t ype = m_request . headers [ " content-type " ] ;
QString contentT ype = m_request . headers [ " content-type " ] ;
if ( content_t ype . startsWith ( " multipart/form-data " ) ) {
if ( contentT ype . startsWith ( " multipart/form-data " ) ) {
const QRegExp boundaryRegexQuoted ( " boundary= \" ([ \\ w'() + , - \ \ . / : = \ \ ? ] + ) \ " " ) ;
const QRegExp boundaryRegexQuoted ( " boundary= \" ([ \\ w'() + , - \ \ . / : = \ \ ? ] + ) \ " " ) ;
const QRegExp boundaryRegexNotQuoted ( " boundary=([ \\ w'() + , - \ \ . / : = \ \ ? ] + ) " ) ;
const QRegExp boundaryRegexNotQuoted ( " boundary=([ \\ w'() + , - \ \ . / : = \ \ ? ] + ) " ) ;
QByteArray boundary ;
QByteArray boundary ;
if ( boundaryRegexQuoted . indexIn ( content_t ype ) < 0 ) {
if ( boundaryRegexQuoted . indexIn ( contentT ype ) < 0 ) {
if ( boundaryRegexNotQuoted . indexIn ( content_t ype ) < 0 ) {
if ( boundaryRegexNotQuoted . indexIn ( contentT ype ) < 0 ) {
qWarning ( ) < < " Could not find boundary in multipart/form-data header! " ;
qWarning ( ) < < " Could not find boundary in multipart/form-data header! " ;
return false ;
return false ;
}
}
@ -274,21 +273,21 @@ Submit Query
return true ;
return true ;
}
}
qWarning ( ) < < Q_FUNC_INFO < < " unknown content type: " < < qPrintable ( content_t ype ) ;
qWarning ( ) < < Q_FUNC_INFO < < " unknown content type: " < < qPrintable ( contentT ype ) ;
return false ;
return false ;
}
}
bool RequestParser : : parseFormData ( const QByteArray & data )
bool RequestParser : : parseFormData ( const QByteArray & data )
{
{
// Parse form data header
// Parse form data header
const int header_e nd = data . indexOf ( EOH ) ;
const int headerE nd = data . indexOf ( EOH ) ;
if ( header_e nd < 0 ) {
if ( headerE nd < 0 ) {
qDebug ( ) < < " Invalid form data: \n " < < data ;
qDebug ( ) < < " Invalid form data: \n " < < data ;
return false ;
return false ;
}
}
QString header_s tr = QString : : fromUtf8 ( data . left ( header_e nd ) ) ;
QString headerS tr = QString : : fromUtf8 ( data . left ( headerE nd ) ) ;
QStringList lines = header_s tr . trimmed ( ) . split ( EOL ) ;
QStringList lines = headerS tr . trimmed ( ) . split ( EOL ) ;
QStringMap headers ;
QStringMap headers ;
foreach ( const QString & line , lines ) {
foreach ( const QString & line , lines ) {
QPair < QString , QString > header ;
QPair < QString , QString > header ;
@ -302,7 +301,7 @@ bool RequestParser::parseFormData(const QByteArray& data)
if ( ! headers . contains ( " content-disposition " )
if ( ! headers . contains ( " content-disposition " )
| | ! parseHeaderValue ( headers [ " content-disposition " ] , disposition )
| | ! parseHeaderValue ( headers [ " content-disposition " ] , disposition )
| | ! disposition . contains ( " name " ) ) {
| | ! disposition . contains ( " name " ) ) {
qDebug ( ) < < " Invalid form data header: \n " < < header_s tr ;
qDebug ( ) < < " Invalid form data header: \n " < < headerS tr ;
return false ;
return false ;
}
}
@ -310,12 +309,12 @@ bool RequestParser::parseFormData(const QByteArray& data)
UploadedFile ufile ;
UploadedFile ufile ;
ufile . filename = disposition [ " filename " ] ;
ufile . filename = disposition [ " filename " ] ;
ufile . type = disposition [ " content-type " ] ;
ufile . type = disposition [ " content-type " ] ;
ufile . data = data . mid ( header_e nd + EOH . length ( ) ) ;
ufile . data = data . mid ( headerE nd + EOH . length ( ) ) ;
m_request . files . append ( ufile ) ;
m_request . files . append ( ufile ) ;
}
}
else {
else {
m_request . posts [ disposition [ " name " ] ] = QString : : fromUtf8 ( data . mid ( header_e nd + EOH . length ( ) ) ) ;
m_request . posts [ disposition [ " name " ] ] = QString : : fromUtf8 ( data . mid ( headerE nd + EOH . length ( ) ) ) ;
}
}
return true ;
return true ;