#include <kurl.h>
#include <kdebug.h>
+#include <kprotocolmanager.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
#include <kio/slaveconfig.h>
#include <kio/jobclasses.h>
}
NullThread::NullThread()
-{
-}
+{}
NullThread::~NullThread()
-{
-}
+{}
ThreadXmlParser::ThreadXmlParser()
: m_boardParser( 0 ), m_inBoard( false ), m_isValid( false ), m_inThread( false )
return true;
}
+// copied from http.cc
+QString ThreadAccess::getCachePath( const KURL& url )
+{
+ const QChar seperator = '_';
+
+ QString CEF = url.path();
+
+ int p = CEF.find( '/' );
+
+ while ( p != -1 ) {
+ CEF[ p ] = seperator;
+ p = CEF.find( '/', p );
+ }
+
+ QString host = url.host().lower();
+ CEF = host + CEF + '_';
+
+ QString dir;
+ if ( url.protocol() == "k2ch" ) {
+ dir = KGlobal::dirs() ->saveLocation( "cache", "k2ch" );
+ } else {
+ dir = KProtocolManager::cacheDir();
+ }
+ kdDebug( 7103 ) << "dir = " << dir << endl;
+ if ( dir[ dir.length() - 1 ] != '/' )
+ dir += "/";
+
+ int l = host.length();
+ for ( int i = 0; i < l; i++ ) {
+ if ( host[ i ].isLetter() && ( host[ i ] != 'w' ) ) {
+ dir += host[ i ];
+ break;
+ }
+ }
+ if ( dir[ dir.length() - 1 ] == '/' )
+ dir += "0";
+
+ unsigned long hash = 0x00000000;
+ QCString u = url.url().latin1();
+ for ( int i = u.length(); i--; ) {
+ hash = ( hash * 12211 + u[ i ] ) % 2147483563;
+ }
+
+ QString hashString;
+ hashString.sprintf( "%08lx", hash );
+
+ CEF = CEF + hashString;
+
+ CEF = dir + "/" + CEF;
+
+ return CEF;
+}
+
+// copied from http.cc
+// ¥¥ã¥Ã¥·¥å¤¬¤¢¤ë¤È¤¤Ï¤½¤ÎÆâÍƤòmalloc¤·¤¿Îΰè¤Ë¥³¥Ô¡¼¤·¤ÆÊÖ¤¹¡£
+// ¥¥ã¥Ã¥·¥å¤¬¤Ê¤¤¤È¤¤Ï0¤òÊÖ¤¹¡£
+char* ThreadAccess::getCacheData( const KURL& url )
+{
+ QString cachePath = getCachePath( url );
+
+ FILE *fs = fopen( QFile::encodeName( cachePath ), "r" );
+ if ( !fs ) {
+ return 0;
+ }
+
+ char buffer[ 401 ];
+ bool ok = true;
+
+ // CacheRevision
+ if ( ok && ( !fgets( buffer, 400, fs ) ) )
+ ok = false;
+ if ( ok && ( strcmp( buffer, "7\n" ) != 0 ) )
+ ok = false;
+
+ // URL
+ if ( ok && ( !fgets( buffer, 400, fs ) ) )
+ ok = false;
+ if ( ok ) {
+ int l = strlen( buffer );
+ if ( l > 0 )
+ buffer[ l - 1 ] = 0; // Strip newline
+ if ( url.url() != buffer ) {
+ ok = false; // Hash collision
+ }
+ }
+
+ // Creation Date
+ if ( ok && ( !fgets( buffer, 400, fs ) ) )
+ ok = false;
+
+ // Expiration Date
+ if ( ok && ( !fgets( buffer, 400, fs ) ) )
+ ok = false;
+
+ // ETag
+ if ( ok && ( !fgets( buffer, 400, fs ) ) )
+ ok = false;
+
+ // Last-Modified
+ if ( ok && ( !fgets( buffer, 400, fs ) ) )
+ ok = false;
+
+ // Mime-Type
+ if ( ok && ( !fgets( buffer, 400, fs ) ) )
+ ok = false;
+
+ // Charset
+ if ( ok && ( !fgets( buffer, 400, fs ) ) )
+ ok = false;
+
+ if ( ok ) {
+ struct stat buf;
+ ::stat( QFile::encodeName( cachePath ), &buf );
+ int pos = ftell( fs );
+ int datasize = buf.st_size - pos;
+
+ char* ret = static_cast<char *>( malloc( datasize + 1 ) );
+ fread( ret, datasize, 1, fs );
+ ret[ datasize ] = '\0';
+ fclose( fs );
+ return ret;
+ }
+
+ fclose( fs );
+ unlink( QFile::encodeName( cachePath ) );
+ return 0;
+}
+
+// ¥¥ã¥Ã¥·¥å¤Ë½ñ¤¹þ¤ß¡£
+// partial data¤¬Æþ¤Ã¤Æ¤ë¤Î¤Ç¤½¤ì¤ò½ñ¤´¹¤¨¤ë¡£
+void ThreadAccess::writeCacheData( const KURL& url )
+{
+ QString cachePath = getCachePath( url );
+
+ FILE *fs = fopen( QFile::encodeName( cachePath ), "r+" );
+ if ( !fs ) {
+ return ;
+ }
+
+ char buffer[ 401 ];
+ bool ok = true;
+
+ // CacheRevision
+ if ( ok && ( !fgets( buffer, 400, fs ) ) )
+ ok = false;
+ if ( ok && ( strcmp( buffer, "7\n" ) != 0 ) )
+ ok = false;
+
+ // URL
+ if ( ok && ( !fgets( buffer, 400, fs ) ) )
+ ok = false;
+ if ( ok ) {
+ int l = strlen( buffer );
+ if ( l > 0 )
+ buffer[ l - 1 ] = 0; // Strip newline
+ if ( url.url() != buffer ) {
+ ok = false; // Hash collision
+ }
+ }
+
+ // Creation Date
+ if ( ok && ( !fgets( buffer, 400, fs ) ) )
+ ok = false;
+
+ // Expiration Date
+ if ( ok && ( !fgets( buffer, 400, fs ) ) )
+ ok = false;
+
+ // ETag
+ if ( ok && ( !fgets( buffer, 400, fs ) ) )
+ ok = false;
+
+ // Last-Modified
+ if ( ok && ( !fgets( buffer, 400, fs ) ) )
+ ok = false;
+
+ // Mime-Type
+ if ( ok && ( !fgets( buffer, 400, fs ) ) )
+ ok = false;
+
+ // Charset
+ if ( ok && ( !fgets( buffer, 400, fs ) ) )
+ ok = false;
+
+ if ( ok ) {
+ if ( m_orgData && responseCode() == 206 ) {
+ QCString orgData = QCString( m_orgData, strlen( m_orgData ) );
+ m_threadData = orgData + m_threadData;
+ }
+ fwrite( m_threadData, m_threadData.size(), 1, fs );
+ fclose( fs );
+
+ if ( m_orgData ) {
+ free( m_orgData );
+ m_orgData = 0;
+ }
+ return ;
+ }
+
+ fclose( fs );
+ unlink( QFile::encodeName( cachePath ) );
+ return ;
+}
+
QString ThreadAccess::get()
{
+ m_orgData = getCacheData( m_thread->datURL() );
+
if ( KURL( m_thread->datURL() ).protocol() != "k2ch" ) {
KIO::SlaveConfig::self() ->setConfigData( "http",
KURL( m_thread->datURL() ).host(),
// use 'HTTP-Headers' metadata.
job->addMetaData( "PropagateHttpHeader", "true" );
+ if ( m_orgData ) {
+ job->addMetaData( "resume", QString::number( strlen( m_orgData ) - 1 ) );
+ job->addMetaData( "AllowCompressedPage", "false" );
+ }
enter_loop();
+ writeCacheData( m_thread->datURL() );
+
QCp932Codec codec;
return codec.toUnicode( m_threadData );
}
}
}
+int ThreadAccess::responseCode()
+{
+ // parse HTTP headers
+ QStringList headerList = QStringList::split( "\n", m_header );
+ QRegExp regexp( "HTTP/1\\.[01] ([0-9]+) .*" );
+ QString dateStr = headerList.grep( regexp ) [ 0 ];
+ if ( regexp.search( dateStr ) == -1 ) {
+ // invalid response
+ return 0;
+ } else {
+ return regexp.cap( 1 ).toInt();
+ }
+}
+
#include "thread.moc"