[prev in list] [next in list] [prev in thread] [next in thread]
List: konq-e
Subject: Re: How to implement user protocols?
From: "Paul Chitescu" <Paul.Chitescu () IMC-Group ! org>
Date: 2002-06-24 9:40:45
[Download RAW message or body]
"Sebastian Stoecklein" <stoecklein@web.de> wrote:
> Hi,
>
> > As soon as I manage to build from CVS sources I'll integrate some of my
> > patches. I really don't want to modify the CVS without being fairly
> > confident it won't screw up something else.
> I'm not sure if you got my question: Will it be possible to implement a
user
> defined protocol after installing your patches?
> If so - could you send me your patches right now? I need to program that
> protocol for my studies at university within the next two weeks :-(
>
> in advance,
> Sebastian Stoecklein
Use the attached patch or update from CVS.
The patch has 1 configuration feature (JPEG cross-compilation related) more
than the current CVS.
NOTE:
The protocols are NOT enabled by default. I also disabled FTP by default
(takes about 50KB of code on a i386). Use configure with the --enable-cgi
and/or --enable-ftp options.
You must create a [Local Protocols] section for CGI-based protocols.
[Local Protocols]
home=/homedir/
about=*/usr/local/about-data/
cgi=*/usr/local/cgi-bin/
man=!/usr/local/special/manpages.cgi
In the example above "home" is a simple file prefixer without execution,
"about" and "cgi" also allow cgi-like script execution (non executables are
returned raw) while "man" provides a single handler executable for the
entire protocol (this MUST be executable).
For security reasons URLs that result in pathnames including "/../" or
ending with "/.." are not allowed. This shouldn't happen in relative links
since the URLs are simplified by the higher level routines.
NOTE:
Passing headers is not currently supported. Only data is passed up the kio,
however the image detection routines will work. Your CGIs must create only
text/html or image/* data.
--
Paul Chitescu
pchitescu@null.ro http://pchitescu.null.ro/ ICQ:22641673
Any spammers will be painfully squeezed into /dev/null
["konqe-proto-mime-early.patch" (application/octet-stream)]
--- ./konq-embed/dropin/kio/krun.cpp.orig Sun Jan 27 20:23:42 2002
+++ ./konq-embed/dropin/kio/krun.cpp Sat Jun 22 22:11:03 2002
@@ -61,12 +61,19 @@
QString externalHandler = KProtocolManager::externalProtocolHandler( m_strURL.protocol() );
if ( !externalHandler.isEmpty() )
{
- exec( externalHandler, m_strURL.url() );
-
- emit error(); // stop the spinning wheel, err, the enabled stop button
-
- delete this; // pretend you don't see this :)
- return;
+ if (externalHandler.left(1) == "@")
+ {
+ m_strURL=externalHandler.mid(1)+m_strURL.url().mid(m_strURL.url().find(':')+1);
+ }
+ else
+ {
+ exec( externalHandler, m_strURL.url().mid(m_strURL.url().find(':')+1) );
+
+ emit error(); // stop the spinning wheel, err, the enabled stop button
+
+ delete this; // pretend you don't see this :)
+ return;
+ }
}
// eeeeek!
@@ -102,12 +109,18 @@
KURL url = transferJob->url();
- QString mtype = QString::fromLatin1( "text/html" );
+ QString mtype = transferJob->mimetype();
- QBuffer buffer( data );
- buffer.open( IO_ReadOnly );
- if ( QImageIO::imageFormat( &buffer ) != 0 )
- mtype = QString::fromLatin1( "image/*" ); // ###
+ // if no MIME type is available attempt to guess it
+ if ( mtype.isEmpty() )
+ {
+ mtype = QString::fromLatin1( "text/html" );
+
+ QBuffer buffer( data );
+ buffer.open( IO_ReadOnly );
+ if ( QImageIO::imageFormat( &buffer ) != 0 )
+ mtype = QString::fromLatin1( "image/*" ); // ###
+ }
transferJob->detach( data );
--- ./konq-embed/dropin/kio/kio_file.cpp.orig Fri Oct 12 02:03:54 2001
+++ ./konq-embed/dropin/kio/kio_file.cpp Sun Jun 23 00:20:25 2002
@@ -21,18 +21,25 @@
*/
+#include <config.h>
+
#include "kio_file.h"
#include <qdir.h>
#include <qfileinfo.h>
#include <qtextstream.h>
+#include <unistd.h>
+#include <errno.h>
+#include <kglobal.h>
+#include <kconfig.h>
+
using namespace KIO;
#define MAX_IPC_SIZE (1024*32)
-File::File()
- : SlaveBase( "file" )
+File::File( const QString &prot )
+ : SlaveBase( prot.local8Bit() )
{
}
@@ -43,6 +50,33 @@
void File::get( const KURL &url )
{
QString path = url.path();
+#if defined(ENABLE_CGI)
+ bool mayExec = FALSE;
+ bool asProxy = FALSE;
+ {
+ KConfig *config = KGlobal::config();
+ KConfigGroupSaver saver( config, QString::fromLatin1( "Local Protocols" ) );
+ QString temp=config->readEntry( mProtocol, QString::null );
+ if ( temp.left( 1 ) == "*" )
+ {
+ temp.remove( 0, 1 );
+ mayExec = TRUE;
+ }
+ else if ( temp.left( 1 ) == "!" )
+ {
+ temp.remove( 0, 1 );
+ mayExec = TRUE;
+ asProxy = TRUE;
+ path="";
+ }
+ path=temp+path;
+ }
+ if ( path.find( "/../" ) != -1 || path.right( 3 ) == "/.." )
+ {
+ error( KIO::ERR_MALFORMED_URL, path );
+ return;
+ }
+#endif
QFileInfo info( path );
@@ -57,13 +91,75 @@
QFile file( path );
unsigned long bytes_read = 0;
- if ( !file.open( IO_ReadOnly ) )
- {
- error( KIO::ERR_CANNOT_OPEN_FOR_READING, path );
- return;
+#if defined(ENABLE_CGI)
+ if ( mayExec && info.isExecutable() &&
+ info.permission( QFileInfo::ExeUser | QFileInfo::ExeGroup | QFileInfo::ExeOther ) )
+ {
+ QString referrer = metaData("referrer");
+ int pipefd[2];
+ if ( ::pipe( pipefd ) )
+ {
+ error( KIO::ERR_UNKNOWN, path );
+ return;
+ }
+
+ int pid = fork();
+ if ( pid == -1 )
+ {
+ error( KIO::ERR_CANNOT_LAUNCH_PROCESS, path );
+ return;
+ }
+
+ if ( pid == 0 )
+ { // in child here
+ ::close( pipefd [0] );
+ if ( ::dup2( pipefd[1], 1 ) == -1 )
+ ::exit( errno );
+ int i;
+ for ( i=getdtablesize(); i >= 3 ; i-- )
+ ::close( i );
+ ::setenv( "GATEWAY_INTERFACE", "LOCAL-CGI/1.1", TRUE );
+ ::setenv( "SCRIPT_NAME", url.path().latin1(), TRUE );
+ ::setenv( "SCRIPT_FILENAME", path.latin1(), TRUE );
+ ::setenv( "REQUEST_METHOD", "GET", TRUE );
+ ::setenv( "REQUEST_URI", url.encodedPathAndQuery().latin1(), TRUE );
+ if ( url.hasHost() )
+ ::setenv( "SERVER_NAME", url.host().latin1(), TRUE );
+ if ( url.port() )
+ ::setenv( "SERVER_PORT", QString::number( url.port() ).latin1(), TRUE );
+ if ( !url.query().isEmpty() )
+ ::setenv( "QUERY_STRING", url.query().mid( 1 ).latin1(), TRUE );
+ if ( url.hasUser() )
+ ::setenv( "PROTOCOL_USER_NAME", url.user().latin1(), TRUE );
+ if ( url.hasPass() )
+ ::setenv( "PROTOCOL_USER_PASS", url.pass().latin1(), TRUE );
+ if ( !referrer.isEmpty() )
+ ::setenv( "PROTOCOL_REFERER", referrer.latin1(), TRUE );
+ ::setenv( "PROTOCOL_NAME", mProtocol.data(), TRUE );
+ QDir::setCurrent(info.dirPath(true));
+ execl( path.latin1(), path.latin1(), 0 );
+ ::exit( errno );
+ }
+ ::close( pipefd[1] );
+ if ( !file.open( IO_ReadOnly, pipefd[0] ) )
+ {
+ ::close( pipefd[0] );
+ error( KIO::ERR_CANNOT_OPEN_FOR_READING, path );
+ return;
+ }
+ }
+
+ else
+#endif
+ {
+ if ( !file.open( IO_ReadOnly ) )
+ {
+ error( KIO::ERR_CANNOT_OPEN_FOR_READING, path );
+ return;
+ }
+ totalSize( info.size() );
}
- totalSize( info.size() );
while ( !file.atEnd() )
{
@@ -89,7 +185,11 @@
}
- else if ( info.isDir() )
+ else if ( info.isDir()
+#if defined(ENABLE_CGI)
+ && !asProxy
+#endif
+ )
{
QDir dir( info.absFilePath() );
@@ -107,18 +207,21 @@
QFileInfoListIterator it( *entries );
- for ( unsigned long c = 0; it.current(); ++it, c++ )
+ for ( unsigned long c = 0; it.current(); ++it )
{
+ if ( it.current()->fileName() == "." ) continue;
+ if ( it.current()->fileName() == ".." &&
+ url.path() == "/" ) continue;
+
QByteArray buffer;
QTextStream stream( buffer, IO_WriteOnly );
- stream << QString::fromLatin1( "<a href=\"%1\">%2</a>\n" )
- .arg( it.current()->absFilePath().
- prepend( QString::fromLatin1( "file:" ) ) )
+ stream << QString::fromLatin1( "<a href=\"file:%1\">%2</a>\n" )
+ .arg( it.current()->absFilePath() )
.arg( it.current()->fileName() );
- processedSize( c + 1 );
+ processedSize( ++c );
data( buffer );
@@ -135,6 +238,23 @@
}
}
+ else
+ {
+ error( KIO::ERR_DOES_NOT_EXIST, path );
+ return;
+ }
finished();
+}
+
+bool File::implementsProto( const QString &prot )
+{
+ if ( prot == "file" ) return TRUE;
+#if defined(ENABLE_CGI)
+ KConfig *config = KGlobal::config();
+ KConfigGroupSaver saver( config, QString::fromLatin1( "Local Protocols" ) );
+ return !config->readEntry( prot, QString::null ).isEmpty();
+#else
+ return false;
+#endif
}
--- ./konq-embed/dropin/kio/kio_file.h.orig Sat Dec 2 15:34:12 2000
+++ ./konq-embed/dropin/kio/kio_file.h Sat Jan 12 15:19:38 2002
@@ -27,10 +27,12 @@
class File : public SlaveBase
{
public:
- File();
+ File( const QString &prot = "file" );
virtual ~File();
virtual void get( const KURL &url );
+
+ static bool implementsProto( const QString &prot );
};
};
--- ./konq-embed/dropin/kio/slavebase.cpp.orig Tue Apr 2 20:37:41 2002
+++ ./konq-embed/dropin/kio/slavebase.cpp Sun Jun 23 00:05:17 2002
@@ -21,15 +21,16 @@
*/
-#include <sys/types.h>
-#include <sys/socket.h>
+#include <config.h>
#include "slavebase.h"
#include "job.h"
#include "http.h"
#include "kio_file.h"
+#if defined(ENABLE_FTP)
#include "kio_ftp.h"
+#endif
#include "slaveinterface.h"
#include "connection.h"
@@ -42,6 +43,8 @@
#include <assert.h>
#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h>
@@ -153,18 +156,23 @@
else if ( prot == "https" )
res = new HTTPProtocol( prot.ascii(), "", "" );
#endif
- else if ( prot == "file" )
- res = new File();
+ else if ( File::implementsProto( prot ) )
+ res = new File( prot );
+#if defined(ENABLE_FTP)
else if ( prot == "ftp" )
- res = new Ftp("", "" );
+ res = new Ftp("", "" );
+#endif
return res;
}
bool SlaveBase::knownProtocol( const QString &protocol )
{
- return ( protocol == "http" || protocol == "https" ||
- protocol == "ftp" || protocol == "file" );
+ return ( protocol == "http" || protocol == "https" ||
+#if defined(ENABLE_FTP)
+ protocol == "ftp" ||
+#endif
+ File::implementsProto( protocol ) );
}
SlaveBase::SlaveBase( const QCString &protocol, const QCString &, const QCString & )
@@ -300,8 +308,17 @@
{
}
-void SlaveBase::mimeType( const QString & )
+void SlaveBase::mimeType( const QString &_type )
{
+ kdDebug(7019) << "(" << getpid() << ") SlaveBase::mimeType '" << _type << "'" << endl;
+ if ( !mOutgoingMetaData.isEmpty() )
+ {
+ KIO_ARGS << mOutgoingMetaData;
+ m_connection->send( INF_META_DATA, data );
+ }
+
+ KIO_ARGS << _type;
+ m_connection->send( INF_MIME_TYPE, data );
}
void SlaveBase::infoMessage( const QString &msg )
@@ -502,6 +519,10 @@
stream >> url;
get( url );
break;
+ case CMD_MIMETYPE:
+ stream >> url;
+ mimetype( url );
+ break;
case CMD_META_DATA:
stream >> m_incomingMetaData;
break;
@@ -521,6 +542,8 @@
stream >> m_config;
}
break;
+ case CMD_NONE:
+ break;
default:
assert( 0 );
}
--- ./konq-embed/dropin/kio/jobclasses.h.orig Thu Oct 11 15:27:01 2001
+++ ./konq-embed/dropin/kio/jobclasses.h Fri May 31 12:58:22 2002
@@ -143,6 +143,8 @@
static TransferJob *findDetachedJobForURL( const KURL &url );
+ QString mimetype() const { return m_mimetype; }
+
protected slots:
void setIncomingMetaData( const KIO::MetaData &dat );
@@ -154,11 +156,15 @@
virtual void receiveData( const QByteArray &dat );
+ virtual void slotMimetype( const QString& type );
+
signals:
void redirection( KIO::Job *, const KURL & );
void data( KIO::Job *job, const QByteArray &data );
+ void mimetype( KIO::Job *, const QString &type );
+
private slots:
void slotRedirectDelayed();
void slotEmitCachedData();
@@ -173,6 +179,7 @@
bool m_finishAfterCacheEmit;
QValueList<QByteArray> m_cachedData;
bool m_cachedDataEmitted;
+ QString m_mimetype;
static QList<TransferJob> *s_detachedJobs;
};
--- ./konq-embed/dropin/kio/jobclasses.cpp.orig Fri Oct 12 16:48:59 2001
+++ ./konq-embed/dropin/kio/jobclasses.cpp Fri May 31 13:07:26 2002
@@ -443,6 +443,12 @@
return it.data();
}
+void TransferJob::slotMimetype( const QString& type )
+{
+ m_mimetype = type;
+ emit mimetype( this, m_mimetype );
+}
+
void TransferJob::start( Slave *slave )
{
m_slave = slave;
@@ -451,6 +457,11 @@
QObject::connect( m_slave, SIGNAL( metaData( const KIO::MetaData & ) ),
this, SLOT( setIncomingMetaData( const KIO::MetaData & ) ) );
+
+ QObject::connect( m_slave, SIGNAL( mimeType( const QString & ) ),
+ this, SLOT( slotMimetype( const QString & ) ) );
+
+ m_mimetype = "";
KIO_ARGS << m_outgoingMetaData;
--- ./konq-embed/dropin/kio/configure.in.in.orig Sat Jun 22 22:33:14 2002
+++ ./konq-embed/dropin/kio/configure.in.in Sun Jun 23 01:37:40 2002
@@ -0,0 +1,11 @@
+AC_ARG_ENABLE(ftp,[ --enable-ftp Enable support for the FTP protocol],
+ want_ftp=$enableval,want_ftp=no)
+if test "x$want_ftp" = "xyes"; then
+ AC_DEFINE(ENABLE_FTP, 1, [If we want support for the FTP protocol])
+fi
+
+AC_ARG_ENABLE(cgi,[ --enable-cgi Enable support for CGI implemented protocols],
+ want_cgi=$enableval,want_cgi=no)
+if test "x$want_cgi" = "xyes"; then
+ AC_DEFINE(ENABLE_CGI, 1, [If we support protocols trough local CGI])
+fi
--- ./konq-embed/dropin/kio/Makefile.am.orig Tue Apr 2 20:37:41 2002
+++ ./konq-embed/dropin/kio/Makefile.am Sun Jun 23 12:36:04 2002
@@ -4,7 +4,7 @@
INCLUDES = -I$(srcdir)/.. -I$(srcdir)/../../kdesrc/kdecore -I$(srcdir)/../../kdesrc \
-I$(srcdir)/../../kdesrc/kio/http -I$(srcdir)/../../kdesrc/kio -I../../kdesrc/kio/http \
-I$(srcdir)/../../kdesrc/kssl -I$(srcdir)/../../kdesrc/khtml -I$(srcdir)/../khtml \
- $(QTOPIA_INCLUDES) $(all_includes)
+ $(QTOPIA_INCLUDES) $(all_includes)
noinst_LTLIBRARIES = libkiodropin.la
@@ -13,7 +13,7 @@
scheduler.cpp observer.cpp \
slave.cpp passdlg.cpp kio_file.cpp kio_ftp.cpp \
kmimemagic.cpp global.cpp \
- launcher.cpp
+ launcher.cpp slaveconfig.cpp
libkiodropin_la_METASOURCES = AUTO
dcopskel:
--- ./konq-embed/dropin/kio/kio_ftp.h.orig Tue Apr 2 20:37:41 2002
+++ ./konq-embed/dropin/kio/kio_ftp.h Sun Jun 23 01:52:48 2002
@@ -24,6 +24,8 @@
#include <config.h>
+#if defined(ENABLE_FTP)
+
#include <stdio.h>
#include <sys/types.h>
@@ -275,4 +277,5 @@
};
+#endif
#endif
--- ./konq-embed/dropin/kio/kio_ftp.cpp.orig Tue Apr 2 20:37:41 2002
+++ ./konq-embed/dropin/kio/kio_ftp.cpp Sun Jun 23 01:53:23 2002
@@ -21,6 +21,8 @@
#include "kio_ftp.h"
+#if defined(ENABLE_FTP)
+
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
@@ -2250,3 +2252,4 @@
finished();
}
+#endif
--- ./konq-embed/dropin/kio/slaveconfig.cpp.orig Sun Jun 23 12:33:06 2002
+++ ./konq-embed/dropin/kio/slaveconfig.cpp Sun Jun 23 12:40:37 2002
@@ -0,0 +1,39 @@
+// -*- c++ -*-
+/*
+ * This file is part of the KDE libraries
+ * Copyright (c) 2001 Waldo Bastian <bastian@kde.org>
+ *
+ * $Id: slaveconfig.cpp,v 1.8.2.1 2001/10/21 07:05:53 adawit Exp $
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ **/
+
+#include <assert.h>
+
+#include "slaveconfig.h"
+
+using namespace KIO;
+
+namespace KIO {
+
+SlaveConfig::SlaveConfig()
+{
+}
+
+SlaveConfig::~SlaveConfig()
+{
+}
+
+}
--- ./konq-embed/dropin/kssl/configure.in.in.orig Sat Dec 8 01:11:27 2001
+++ ./konq-embed/dropin/kssl/configure.in.in Sun Jun 23 01:10:50 2002
@@ -20,7 +20,7 @@
want_ssl=yes
AC_ARG_WITH(ssl,
- [ --without-ssl disable SSL checks],
+ [ --without-ssl Disable SSL checks],
[want_ssl=$withval])
if test $want_ssl = yes; then
@@ -87,7 +87,7 @@
dnl Check for SSL version
fixed_ssl_version="no"
- AC_ARG_WITH(ssl-version, [ --with-ssl-version=ver disable ssl version check
+ AC_ARG_WITH(ssl-version, [ --with-ssl-version=ver Disable ssl version check
and assume specified version],
[fixed_ssl_version=$withval])
--- ./konq-embed/ipkg/konq-embedrc.in.orig Mon Mar 11 10:40:20 2002
+++ ./konq-embed/ipkg/konq-embedrc.in Sun Jun 23 01:19:06 2002
@@ -1,5 +1,15 @@
[External Protocols]
mailto=mailit
+aj=@http://www.ask.com/main/askJeeves.asp?ask=
+av=@http://www.altavista.com/sites/search/web?q=
+dj=@http://www.deja.com/dnquery.xp?QRY=
+ex=@http://search.excite.com/search.gw?search=
+gg=@http://www.google.com/search?q=
+hb=@http://hotbot.lycos.com/?MT=
+ly=@http://search.lycos.com/main/?query=
+ya=@http://search.yahoo.com/bin/search?p=
+
+[Local Protocols]
[http Settings]
UseCache=true
--- ./konq-embed/src/htmlview.cc.orig Fri Oct 12 02:03:54 2001
+++ ./konq-embed/src/htmlview.cc Sat Jun 22 22:52:00 2002
@@ -52,7 +52,7 @@
QString serviceType = browserExtension()->urlArgs().serviceType;
if ( !serviceType.isEmpty() )
- m_imageMode = serviceType == "image/*";
+ m_imageMode = serviceType.startsWith("image/");
if ( !m_imageMode )
return KHTMLPart::openURL( url );
--- ./konq-embed/src/configure.in.in.orig Mon Feb 11 22:37:40 2002
+++ ./konq-embed/src/configure.in.in Sun Jun 23 01:05:59 2002
@@ -31,7 +31,7 @@
;;
esac
-AC_ARG_ENABLE(bookmarks,[ --disable-bookmarks disable XBel bookmark support],
+AC_ARG_ENABLE(bookmarks,[ --disable-bookmarks Disable XBel bookmark support],
want_bookmarks=$enableval,want_bookmarks=yes)
if test "x$want_bookmarks" = "xyes"; then
--- ./konq-embed/configure.in.in.orig Tue Feb 12 14:12:04 2002
+++ ./konq-embed/configure.in.in Sun Jun 23 01:04:22 2002
@@ -5,7 +5,7 @@
AC_DEFINE_UNQUOTED(KHTML_NO_SELECTION, 1, [Defined if selections in KHTML are disabled])
fi
-AC_ARG_ENABLE(scrollbars,[ --disable-scrollbars Disable scrollbars in KHTML],
+AC_ARG_ENABLE(scrollbars,[ --disable-scrollbars Disable scrollbars in KHTML],
want_scrollbars=$enableval, want_scrollbars=yes)
if test "x$want_scrollbars" = "xno"; then
@@ -24,7 +24,7 @@
LIB_KJSHTML=""
fi
-AC_ARG_WITH(javascript,[ --with-javascript=mode where mode is one of static/dynamic/none],
+AC_ARG_WITH(javascript,[ --with-javascript=mode where mode is one of static/dynamic/none],
javascript_mode=$withval,
javascript_mode=static)
--- ./admin/acinclude.m4.in.orig Fri Feb 1 22:51:46 2002
+++ ./admin/acinclude.m4.in Sun Jun 23 13:19:25 2002
@@ -2188,7 +2188,7 @@
dnl then search the headers (can't use simply AC_TRY_xxx, as jpeglib.h
dnl requires system dependent includes loaded before it)
-jpeg_incdirs="/usr/include /usr/local/include $kde_extra_includes"
+jpeg_incdirs="$includedir $prefix/include /usr/include /usr/local/include $kde_extra_includes"
AC_FIND_FILE(jpeglib.h, $jpeg_incdirs, jpeg_incdir)
test "x$jpeg_incdir" = xNO && jpeg_incdir=
_______________________________________________
konq-e mailing list
konq-e@mail.kde.org
http://mail.kde.org/mailman/listinfo/konq-e
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic