From: ikemo Date: Sun, 4 Jan 2004 04:24:31 +0000 (+0000) Subject: get difference data instead of entire data. X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=7bf36dcf434c2a6fea40dc4f506b90f5f3a71e87;p=kita%2Fkita.git get difference data instead of entire data. git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/kita/kita/trunk@780 56b19765-1e22-0410-a548-a0f45d66c51a --- diff --git a/ChangeLog b/ChangeLog index 50e429f..a533dad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2004-01-04 Hideki Ikemoto + + * get difference data instead of entire data. + 2004-01-01 Hideki Ikemoto * save color pref. diff --git a/TODO b/TODO index 962c6c9..d8ff8ea 100644 --- a/TODO +++ b/TODO @@ -25,6 +25,10 @@ ¡¦¤ªµ¤¤ËÆþ¤ê¤ò¥Ä¥ê¡¼¤Ëɽ¼¨ ¥Ð¥° +¡¦http¤Î¥­¥ã¥Ã¥·¥å¤È´ûÆÉ¿ô¤ÎÀ°¹çÀ­¤¬¼è¤ì¤Æ¤¤¤Ê¤¤¡£ +¡¦1¥ì¥¹¤À¤±¼èÆÀ¤·¤¿¸å900¥ì¥¹Ì¤Æɤ¬¤¢¤ë¤Ègzip¤»¤º¤Ëº¹Ê¬¼èÆÀ¤¹¤ë¤Î¤Ç¡¢ +Á´Éô¼èÆÀ¤¹¤ë¤è¤êÃÙ¤¯¤Ê¤ë¤¬¡¢¤³¤ì¤ò¤Ê¤ó¤È¤«¤·¤¿¤¤ +¡¦¤¢¤Ü¡¼¤ó¤¬Æþ¤ë¤È¥­¥ã¥Ã¥·¥å¤¬¤ª¤«¤·¤¯¤Ê¤ë¤Î¤Ç¤Ê¤ó¤È¤«¤·¤¿¤¤¡£ ¡¦¥¤¥é¥Í¤ÎAA¤¬²õ¤ì¤Æ¤¤¤ë ¡¦XML¤Î¥¹¥ì̾¤Ë>>¤È¤«Æþ¤Ã¤Æ¤ë¤È¥À¥á(¥¨¥¹¥±¡¼¥×¤·¤Æ¤¤¤Ê¤¤) ¡¦½ñ¤­¹þ¤ß³Îǧ¤Î¥Ñ¥Í¥ë¤¬½Ð¤ë¤È(Cookie̤ÀßÄê)¡¢log.txt¤Ë½ñ¤«¤ì¤ëURL¤¬¤ª¤«¤·¤¯¤Ê¤ë¡£ diff --git a/kita/src/libkita/thread.cpp b/kita/src/libkita/thread.cpp index 1c218e5..be3d4bf 100644 --- a/kita/src/libkita/thread.cpp +++ b/kita/src/libkita/thread.cpp @@ -14,6 +14,9 @@ #include #include +#include +#include +#include #include #include @@ -164,12 +167,10 @@ void Thread::setName( const QString& datURL, const QString& threadName ) } NullThread::NullThread() -{ -} +{} NullThread::~NullThread() -{ -} +{} ThreadXmlParser::ThreadXmlParser() : m_boardParser( 0 ), m_inBoard( false ), m_isValid( false ), m_inThread( false ) @@ -243,8 +244,214 @@ bool ThreadXmlParser::characters( const QString& ch ) 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( 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(), @@ -262,9 +469,15 @@ QString ThreadAccess::get() // 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 ); } @@ -333,4 +546,18 @@ int ThreadAccess::serverTime() } } +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" diff --git a/kita/src/libkita/thread.h b/kita/src/libkita/thread.h index ad7b9be..29aa52e 100644 --- a/kita/src/libkita/thread.h +++ b/kita/src/libkita/thread.h @@ -112,11 +112,16 @@ namespace Kita private: void enter_loop(); + QString getCachePath( const KURL& url ); + char* getCacheData( const KURL& url ); + void writeCacheData( const KURL& url ); + int responseCode(); const Thread* m_thread; KIO::Job* m_currentJob; QCString m_threadData; QString m_header; + char* m_orgData; private slots: void slotReceiveThreadData( KIO::Job* job, const QByteArray& data );