2 Copyright (C) 2002 Cornelius Schumacher <schumacher@kde.org>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #include <unistd.h> // getpid()
30 #include <kstandarddirs.h>
31 #include <kcomponentdata.h>
34 #include <kconfiggroup.h>
39 CgiProtocol::CgiProtocol( const QByteArray
&pool
, const QByteArray
&app
)
40 : SlaveBase( "cgi", pool
, app
)
42 kDebug(7124) << "CgiProtocol::CgiProtocol";
44 KConfig
_cfg( "kcmcgirc" );
45 KConfigGroup
cfg(&_cfg
, "General" );
46 mCgiPaths
= cfg
.readEntry( "Paths" , QStringList() );
49 CgiProtocol::~CgiProtocol()
51 kDebug(7124) << "CgiProtocol::~CgiProtocol";
54 void CgiProtocol::get( const KUrl
& url
)
56 kDebug(7124) << "CgiProtocol::get()";
57 kDebug(7124) << " URL: " << url
.url();
59 kDebug(7124) << " Path: " << url
.path();
60 kDebug(7124) << " Query: " << url
.query();
61 kDebug(7124) << " Protocol: " << url
.protocol();
62 kDebug(7124) << " Filename: " << url
.filename();
64 QByteArray protocol
= "SERVER_PROTOCOL=HTTP";
65 putenv( protocol
.data() );
67 QByteArray requestMethod
= "REQUEST_METHOD=GET";
68 putenv( requestMethod
.data() );
70 QByteArray query
= url
.query().mid( 1 ).toLocal8Bit();
71 query
.prepend( "QUERY_STRING=" );
72 putenv( query
.data() );
74 QString path
= url
.path();
78 int pos
= path
.lastIndexOf('/');
79 if ( pos
>= 0 ) file
= path
.mid( pos
+ 1 );
84 bool stripHeader
= false;
85 bool forwardFile
= true;
87 QStringList::ConstIterator it
;
88 for( it
= mCgiPaths
.constBegin(); it
!= mCgiPaths
.constEnd(); ++it
) {
90 if ( !(*it
).endsWith('/') )
93 if ( KStandardDirs::exists( cmd
) ) {
103 kDebug(7124) << "Forwarding to '" << path
<< "'";
105 QByteArray filepath
= QFile::encodeName( path
);
107 fd
= fopen( filepath
.data(), "r" );
110 kDebug(7124) << "Error opening '" << filepath
<< "'";
111 error( KIO::ERR_CANNOT_OPEN_FOR_READING
, filepath
);
115 kDebug(7124) << "Cmd: " << cmd
;
117 fd
= popen( QFile::encodeName(KShell::quoteArg( cmd
)).data(), "r" );
120 kDebug(7124) << "Error running '" << cmd
<< "'";
121 error( KIO::ERR_CANNOT_OPEN_FOR_READING
, cmd
);
128 while ( !feof( fd
) )
130 int n
= fread( buffer
, 1, 2048, fd
);
146 QByteArray output
= buffer
; // this assumes buffer is text and not binary
147 int colon
= output
.indexOf( ':' );
148 int newline
= output
.indexOf( '\n' );
149 int semicolon
= output
.lastIndexOf( ';', newline
);
151 if ( semicolon
< 0 ) end
= newline
;
152 else end
= semicolon
;
155 kDebug(7124) << " colon: " << colon
;
156 kDebug(7124) << " newline: " << newline
;
157 kDebug(7124) << " semicolon: " << semicolon
;
158 kDebug(7124) << " end: " << end
;
161 QByteArray contentType
= output
.mid( colon
+ 1, end
- colon
- 1 );
163 contentType
= contentType
.trimmed();
165 kDebug(7124) << "ContentType: '" << contentType
<< "'";
167 mimeType( contentType
);
169 int start
= output
.indexOf( "\r\n\r\n" );
170 if ( start
>= 0 ) start
+= 4;
172 start
= output
.indexOf( "\n\n" );
173 if ( start
>= 0 ) start
+= 2;
176 if ( start
>= 0 ) output
= output
.mid( start
);
181 data( QByteArray::fromRawData( buffer
, n
) );
193 kDebug(7124) << "CgiProtocol::get - done";
196 extern "C" { int KDE_EXPORT
kdemain( int argc
, char **argv
); }
198 /*! The kdemain function generates an instance of the ioslave and starts its
201 int kdemain( int argc
, char **argv
)
203 KComponentData
componentData( "kio_cgi" );
205 kDebug(7124) << "kio_cgi starting " << getpid();
209 fprintf(stderr
, "Usage: kio_cgi protocol domain-socket1 domain-socket2\n");
213 CgiProtocol
slave( argv
[2], argv
[3] );
214 slave
.dispatchLoop();