[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kfm-devel
Subject:    Re: content-disposition in HTTP headers
From:       Allan Sandfeld Jensen <kde () carewolf ! com>
Date:       2006-03-13 15:45:21
Message-ID: 200603131645.22174.kde () carewolf ! com
[Download RAW message or body]

Ok. Further testing showed that content-disposition: attachment is indeed not 
honoured, but my patch didn't fix it either. I've reopened bug #31662 
(http://bugs.kde.org/show_bug.cgi?id=31662)

The attached patch is updated and fixes the bug as far as I can tell, and 
should be safe for KDE 3.5.2. 

content-disposition headers are still not cached though.

Regards
`Allan

["contentdisposition.diff" (text/x-diff)]

Index: kdelibs/kioslave/http/http.cc
===================================================================
--- kdelibs/kioslave/http/http.cc	(revision 517591)
+++ kdelibs/kioslave/http/http.cc	(working copy)
@@ -2710,7 +2710,8 @@
   QCString locationStr; // In case we get a redirect.
   QCString cookieStr; // In case we get a cookie.
 
-  QString disposition; // Incase we get a Content-Disposition
+  QString dispositionType; // In case we get a Content-Disposition type
+  QString dispositionFilename; // In case we get a Content-Disposition filename
   QString mediaValue;
   QString mediaAttribute;
 
@@ -3245,7 +3246,7 @@
               dispositionBuf--;
 
             if ( dispositionBuf > bufStart )
-              disposition = QString::fromLatin1( bufStart, dispositionBuf-bufStart \
); +              dispositionFilename = QString::fromLatin1( bufStart, \
dispositionBuf-bufStart );  
             break;
           }
@@ -3258,7 +3259,7 @@
             dispositionBuf++;
 
           if ( dispositionBuf > bufStart )
-            disposition = QString::fromLatin1( bufStart, dispositionBuf-bufStart \
).stripWhiteSpace(); +            dispositionType = QString::fromLatin1( bufStart, \
dispositionBuf-bufStart ).stripWhiteSpace();  
           while ( *dispositionBuf == ';' || *dispositionBuf == ' ' )
             dispositionBuf++;
@@ -3267,15 +3268,15 @@
 
       // Content-Dispostion is not allowed to dictate directory
       // path, thus we extract the filename only.
-      if ( !disposition.isEmpty() )
+      if ( !dispositionFilename.isEmpty() )
       {
-        int pos = disposition.findRev( '/' );
+        int pos = dispositionFilename.findRev( '/' );
 
         if( pos > -1 )
-          disposition = disposition.mid(pos+1);
+          dispositionFilename = dispositionFilename.mid(pos+1);
 
-        kdDebug(7113) << "(" << m_pid << ") Content-Disposition: "
-                      << disposition<< endl;
+        kdDebug(7113) << "(" << m_pid << ") Content-Disposition: filename="
+                      << dispositionFilename<< endl;
       }
     }
     else if (strncasecmp(buf, "Proxy-Connection:", 17) == 0)
@@ -3748,12 +3749,20 @@
   }
 #endif
 
-  if( !disposition.isEmpty() )
+  if( !dispositionType.isEmpty() )
   {
-    kdDebug(7113) << "(" << m_pid << ") Setting Content-Disposition metadata to: "
-                  << disposition << endl;
-    setMetaData("content-disposition", disposition);
+    kdDebug(7113) << "(" << m_pid << ") Setting Content-Disposition type to: "
+                  << dispositionType << endl;
+    setMetaData("content-disposition-type", dispositionType);
   }
+  if( !dispositionFilename.isEmpty() )
+  {
+    kdDebug(7113) << "(" << m_pid << ") Setting Content-Disposition filename to: "
+                  << dispositionFilename << endl;
+    // ### KDE4:  setting content-disposition to filename for pre 3.5.2 \
compatability +    setMetaData("content-disposition", dispositionFilename);
+    setMetaData("content-disposition-filename", dispositionFilename);
+  }
 
   if (!m_request.lastModified.isEmpty())
     setMetaData("modified", m_request.lastModified);
Index: kdelibs/kparts/browserrun.h
===================================================================
--- kdelibs/kparts/browserrun.h	(revision 517591)
+++ kdelibs/kparts/browserrun.h	(working copy)
@@ -75,22 +75,29 @@
 
         //KParts::URLArgs urlArgs() const { return m_args; }
         //KParts::ReadOnlyPart* part() const { return m_part; }
-	
+
 	/**
 	 * @return the URL we're probing
 	 */
         KURL url() const { return m_strURL; }
-	
+
 	/**
 	 * @return true if no dialog will be shown in case of errors
 	 */
         bool hideErrorDialog() const;
-        
+
         /**
-	 * @return Suggested filename given by the server (e.g. HTTP content-disposition)
+	 * @return Suggested filename given by the server (e.g. HTTP content-disposition \
                filename)
 	 */
         QString suggestedFilename() const { return m_suggestedFilename; }
-        
+
+        /**
+	 * @return Suggested disposition by the server (e.g. HTTP content-disposition)
+	 */
+        QString contentDisposition() const;
+
+        bool serverSuggestsSave() const { return contentDisposition() == \
"attachment"; }; +
         enum AskSaveResult { Save, Open, Cancel };
         /**
          * Ask the user whether to save or open a url in another application.
@@ -101,6 +108,8 @@
          * @return Save, Open or Cancel.
          */
         static AskSaveResult askSave( const KURL & url, KService::Ptr offer, const \
QString& mimeType, const QString & suggestedFilename = QString::null ); +
+        enum AskEmbedOrSaveFlags { InlineDisposition = 0, AttachmentDisposition = 1 \
};  /**
          * Similar to askSave() but for the case where the current application is
          * able to embed the url itself (instead of passing it to another app).
Index: kdelibs/kparts/browserrun.cpp
===================================================================
--- kdelibs/kparts/browserrun.cpp	(revision 517591)
+++ kdelibs/kparts/browserrun.cpp	(working copy)
@@ -36,6 +36,7 @@
 {
 public:
   bool m_bHideErrorDialog;
+  QString contentDisposition;
 };
 
 BrowserRun::BrowserRun( const KURL& url, const KParts::URLArgs& args,
@@ -185,7 +186,8 @@
   m_strURL = job->url();
   kdDebug(1000) << "slotBrowserMimetype: found " << type << " for " << \
m_strURL.prettyURL() << endl;  
-  m_suggestedFilename = job->queryMetaData("content-disposition");
+  m_suggestedFilename = job->queryMetaData("content-disposition-filename");
+  d->contentDisposition = job->queryMetaData("content-disposition-type");
   //kdDebug(1000) << "m_suggestedFilename=" << m_suggestedFilename << endl;
 
   // Make a copy to avoid a dead reference
@@ -316,7 +318,7 @@
 }
 
 //static
-BrowserRun::AskSaveResult BrowserRun::askEmbedOrSave( const KURL & url, const \
QString& mimeType, const QString & suggestedFilename, int /*flags*/ ) \
+BrowserRun::AskSaveResult BrowserRun::askEmbedOrSave( const KURL & url, const \
QString& mimeType, const QString & suggestedFilename, int flags )  {
     // SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC SYNC
     // NOTE: Keep this funcion in sync with \
kdebase/kcontrol/filetypes/filetypedetails.cpp @@ -332,13 +334,14 @@
     // - multipart/* ("server push", see kmultipart)
     // - other strange 'internal' mimetypes like print/manager...
     // KEEP IN SYNC!!!
-    if ( mime->is( "text/html" ) ||
+    if (flags != (int)AttachmentDisposition && (
+         mime->is( "text/html" ) ||
          mime->is( "text/xml" ) ||
          mime->is( "inode/directory" ) ||
          mimeType.startsWith( "image" ) ||
          mime->is( "multipart/x-mixed-replace" ) ||
          mime->is( "multipart/replace" ) ||
-         mimeType.startsWith( "print" ) )
+         mimeType.startsWith( "print" ) ) )
         return Open;
 
     QString question = makeQuestion( url, mimeType, suggestedFilename );
@@ -507,4 +510,8 @@
     return d->m_bHideErrorDialog;
 }
 
+QString BrowserRun::contentDisposition() const {
+    return d->contentDisposition;
+}
+
 #include "browserrun.moc"
Index: kdebase/konqueror/konq_run.cc
===================================================================
--- kdebase/konqueror/konq_run.cc	(revision 517591)
+++ kdebase/konqueror/konq_run.cc	(working copy)
@@ -79,12 +79,11 @@
   m_req.args = m_args;
 
   bool tryEmbed = true;
+
   // One case where we shouldn't try to embed, is when the server asks us to save
-  // ####### only if content-disposition doesn't say inline
-#if 0
-  if ( !m_suggestedFilename.isEmpty() )
+  if ( serverSuggestsSave() )
      tryEmbed = false;
-#endif
+
   if ( KonqMainWindow::isMimeTypeAssociatedWithSelf( mimeType ) )
       m_req.forceAutoEmbed = true;
 
@@ -115,8 +114,13 @@
 
   if ( !m_bFinished && // only if we're going to open
        KonqMainWindow::isMimeTypeAssociatedWithSelf( mimeType ) ) {
-    KMessageBox::error( m_pMainWindow, i18n( "There appears to be a configuration \
error. You have associated Konqueror with %1, but it cannot handle this file type." \
                ).arg( mimeType ) );
-    m_bFinished = true;
+
+    if (!tryEmbed) // try now
+        m_bFinished = m_pMainWindow->openView( mimeType, m_strURL, m_pView, m_req );
+    if (!m_bFinished) {
+        KMessageBox::error( m_pMainWindow, i18n( "There appears to be a \
configuration error. You have associated Konqueror with %1, but it cannot handle this \
file type." ).arg( mimeType ) ); +        m_bFinished = true;
+    }
   }
 
   if ( m_bFinished ) {
Index: kdebase/konqueror/konq_mainwindow.cc
===================================================================
--- kdebase/konqueror/konq_mainwindow.cc	(revision 517591)
+++ kdebase/konqueror/konq_mainwindow.cc	(working copy)
@@ -851,11 +851,14 @@
               QString suggestedFilename;
 
               KonqRun* run = childView->run();
-              if (run)
+              int attachment = 0;
+              if (run) {
                   suggestedFilename = run->suggestedFilename();
+                  attachment = (run->serverSuggestsSave()) ? \
KParts::BrowserRun::AttachmentDisposition : KParts::BrowserRun::InlineDisposition; +  \
}  
               KParts::BrowserRun::AskSaveResult res = \
                KParts::BrowserRun::askEmbedOrSave(
-                  url, serviceType, suggestedFilename );
+                  url, serviceType, suggestedFilename, attachment );
               if ( res == KParts::BrowserRun::Open )
                   forceAutoEmbed = true;
               else if ( res == KParts::BrowserRun::Cancel )
@@ -1396,7 +1399,7 @@
   QStringList args = QStringList::split(' ', term);
   for ( QStringList::iterator it = args.begin(); it != args.end(); ++it )
     cmd << *it;
-  
+
   kdDebug(1202) << "slotOpenTerminal: directory " << dir
 		<< ", terminal:" << term << endl;
   cmd.start(KProcess::DontCare);



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic