OSDN Git Service

get difference data instead of entire data.
authorikemo <ikemo@56b19765-1e22-0410-a548-a0f45d66c51a>
Sun, 4 Jan 2004 04:24:31 +0000 (04:24 +0000)
committerikemo <ikemo@56b19765-1e22-0410-a548-a0f45d66c51a>
Sun, 4 Jan 2004 04:24:31 +0000 (04:24 +0000)
git-svn-id: svn+ssh://svn.sourceforge.jp/svnroot/kita/kita/trunk@780 56b19765-1e22-0410-a548-a0f45d66c51a

ChangeLog
TODO
kita/src/libkita/thread.cpp
kita/src/libkita/thread.h

index 50e429f..a533dad 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2004-01-04  Hideki Ikemoto  <ikemo@users.sourceforge.jp>
+
+       * get difference data instead of entire data.
+
 2004-01-01  Hideki Ikemoto  <ikemo@users.sourceforge.jp>
 
        * save color pref.
diff --git a/TODO b/TODO
index 962c6c9..d8ff8ea 100644 (file)
--- a/TODO
+++ b/TODO
 ¡¦¤ªµ¤¤ËÆþ¤ê¤ò¥Ä¥ê¡¼¤Ëɽ¼¨
 
 ¥Ð¥°
+¡¦http¤Î¥­¥ã¥Ã¥·¥å¤È´ûÆÉ¿ô¤ÎÀ°¹çÀ­¤¬¼è¤ì¤Æ¤¤¤Ê¤¤¡£
+¡¦1¥ì¥¹¤À¤±¼èÆÀ¤·¤¿¸å900¥ì¥¹Ì¤Æɤ¬¤¢¤ë¤Ègzip¤»¤º¤Ëº¹Ê¬¼èÆÀ¤¹¤ë¤Î¤Ç¡¢
+Á´Éô¼èÆÀ¤¹¤ë¤è¤êÃÙ¤¯¤Ê¤ë¤¬¡¢¤³¤ì¤ò¤Ê¤ó¤È¤«¤·¤¿¤¤
+¡¦¤¢¤Ü¡¼¤ó¤¬Æþ¤ë¤È¥­¥ã¥Ã¥·¥å¤¬¤ª¤«¤·¤¯¤Ê¤ë¤Î¤Ç¤Ê¤ó¤È¤«¤·¤¿¤¤¡£
 ¡¦¥¤¥é¥Í¤ÎAA¤¬²õ¤ì¤Æ¤¤¤ë
 ¡¦XML¤Î¥¹¥ì̾¤Ë>>¤È¤«Æþ¤Ã¤Æ¤ë¤È¥À¥á(¥¨¥¹¥±¡¼¥×¤·¤Æ¤¤¤Ê¤¤)
 ¡¦½ñ¤­¹þ¤ß³Îǧ¤Î¥Ñ¥Í¥ë¤¬½Ð¤ë¤È(Cookie̤ÀßÄê)¡¢log.txt¤Ë½ñ¤«¤ì¤ëURL¤¬¤ª¤«¤·¤¯¤Ê¤ë¡£
index 1c218e5..be3d4bf 100644 (file)
@@ -14,6 +14,9 @@
 
 #include <kurl.h>
 #include <kdebug.h>
+#include <kprotocolmanager.h>
+#include <kglobal.h>
+#include <kstandarddirs.h>
 
 #include <kio/slaveconfig.h>
 #include <kio/jobclasses.h>
@@ -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<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(),
@@ -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"
index ad7b9be..29aa52e 100644 (file)
@@ -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 );