add more spacing
[personal-kdebase.git] / runtime / kioslave / cgi / cgi.cpp
blob36e8e15b7ce5ecfb08b528b68ab16a8ae3438897
1 /*
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.
19 #include "cgi.h"
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <unistd.h> // getpid()
25 #include <QDir>
26 #include <QRegExp>
28 #include <kdebug.h>
29 #include <kshell.h>
30 #include <kstandarddirs.h>
31 #include <kcomponentdata.h>
32 #include <klocale.h>
33 #include <kconfig.h>
34 #include <kconfiggroup.h>
37 using namespace KIO;
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();
58 #if 0
59 kDebug(7124) << " Path: " << url.path();
60 kDebug(7124) << " Query: " << url.query();
61 kDebug(7124) << " Protocol: " << url.protocol();
62 kDebug(7124) << " Filename: " << url.filename();
63 #endif
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();
76 QString file;
78 int pos = path.lastIndexOf('/');
79 if ( pos >= 0 ) file = path.mid( pos + 1 );
80 else file = path;
82 QString cmd;
84 bool stripHeader = false;
85 bool forwardFile = true;
87 QStringList::ConstIterator it;
88 for( it = mCgiPaths.constBegin(); it != mCgiPaths.constEnd(); ++it ) {
89 cmd = *it;
90 if ( !(*it).endsWith('/') )
91 cmd += '/';
92 cmd += file;
93 if ( KStandardDirs::exists( cmd ) ) {
94 forwardFile = false;
95 stripHeader = true;
96 break;
100 FILE *fd;
102 if ( forwardFile ) {
103 kDebug(7124) << "Forwarding to '" << path << "'";
105 QByteArray filepath = QFile::encodeName( path );
107 fd = fopen( filepath.data(), "r" );
109 if ( !fd ) {
110 kDebug(7124) << "Error opening '" << filepath << "'";
111 error( KIO::ERR_CANNOT_OPEN_FOR_READING, filepath );
112 return;
114 } else {
115 kDebug(7124) << "Cmd: " << cmd;
117 fd = popen( QFile::encodeName(KShell::quoteArg( cmd )).data(), "r" );
119 if ( !fd ) {
120 kDebug(7124) << "Error running '" << cmd << "'";
121 error( KIO::ERR_CANNOT_OPEN_FOR_READING, cmd );
122 return;
126 char buffer[ 4090 ];
128 while ( !feof( fd ) )
130 int n = fread( buffer, 1, 2048, fd );
132 if ( n == -1 )
134 // ERROR
135 if ( forwardFile ) {
136 fclose( fd );
137 } else {
138 pclose( fd );
140 return;
143 buffer[n] = 0;
145 if ( stripHeader ) {
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 );
150 int end;
151 if ( semicolon < 0 ) end = newline;
152 else end = semicolon;
154 #if 0
155 kDebug(7124) << " colon: " << colon;
156 kDebug(7124) << " newline: " << newline;
157 kDebug(7124) << " semicolon: " << semicolon;
158 kDebug(7124) << " end: " << end;
159 #endif
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;
171 else {
172 start = output.indexOf( "\n\n" );
173 if ( start >= 0 ) start += 2;
176 if ( start >= 0 ) output = output.mid( start );
178 stripHeader = false;
179 data( output );
180 } else {
181 data( QByteArray::fromRawData( buffer, n ) );
185 if ( forwardFile ) {
186 fclose( fd );
187 } else {
188 pclose( fd );
191 finished();
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
199 * dispatch loop. */
201 int kdemain( int argc, char **argv )
203 KComponentData componentData( "kio_cgi" );
205 kDebug(7124) << "kio_cgi starting " << getpid();
207 if (argc != 4)
209 fprintf(stderr, "Usage: kio_cgi protocol domain-socket1 domain-socket2\n");
210 exit(-1);
213 CgiProtocol slave( argv[2], argv[3] );
214 slave.dispatchLoop();
216 return 0;