File indexing completed on 2025-01-05 04:26:52
0001 /*************************************************************************** 0002 * copyright : (C) 2008 Ian Monroe <ian@monroe.nu> 0003 * 0004 * This program is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU General Public License as 0006 * published by the Free Software Foundation; either version 2 of 0007 * the License or (at your option) version 3 or any later version 0008 * accepted by the membership of KDE e.V. (or its successor approved 0009 * by the membership of KDE e.V.), which shall act as a proxy 0010 * defined in Section 14 of version 3 of the license. 0011 * 0012 * This program is distributed in the hope that it will be useful, 0013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0015 * GNU General Public License for more details. 0016 * 0017 * You should have received a copy of the GNU General Public License 0018 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0019 **************************************************************************/ 0020 0021 //Importer.load( "HttpServer.js" ); 0022 0023 0024 Importer.loadQtBinding( "qt.core" ); 0025 Importer.loadQtBinding( "qt.network" ); 0026 0027 QByteArray.prototype.toString = function() 0028 { 0029 ts = new QTextStream( this, QIODevice.ReadOnly ); 0030 return ts.readAll(); 0031 } 0032 0033 function HttpServer() 0034 { 0035 QTcpServer.call( this, null ); 0036 var portNumber = 8080; 0037 do { 0038 var connected = this.listen(new QHostAddress( QHostAddress.Any ), portNumber); 0039 portNumber++; 0040 } while( !connected && ((this.serverError() & QAbstractSocket.AddressInUseError) == 0 ) && portNumber < 9000 ) 0041 if( !this.isListening() ) 0042 { 0043 Amarok.debug( "Unable to open a port for the web server" ); 0044 return; 0045 } 0046 Amarok.debug("Web server started at port " + this.serverPort() ); 0047 this.newConnection.connect( this, this.newIncomingConnection ); 0048 this.registry = new Object(); 0049 } 0050 0051 HttpServer.prototype = new QTcpServer(); 0052 0053 HttpServer.prototype.newIncomingConnection = function() 0054 { 0055 var socket = this.nextPendingConnection(); 0056 var request = new QByteArray(); 0057 var thisHttp = this; 0058 socket.readyRead.connect( function() { 0059 request.append( socket.readAll() ); 0060 var endOfRequest = request.indexOf("\r\n\r\n"); 0061 if( endOfRequest > 0 ) 0062 { 0063 try{ 0064 request = thisHttp.parseHeader( request, socket, endOfRequest + 4 ); 0065 } 0066 catch( error ) { 0067 Amarok.debug( error) 0068 } 0069 } 0070 }); 0071 } 0072 0073 HttpServer.prototype.parseHeader = function( request, socket, endOfRequest ) 0074 { 0075 var header = new QHttpRequestHeader( request.left( endOfRequest ).toString() ); 0076 if( header.method() == "GET" ) 0077 { 0078 this.sendResponse( socket, header.path() ); 0079 socket.close(); 0080 } 0081 return request.mid( endOfRequest ); 0082 } 0083 0084 HttpServer.prototype.sendResponse = function( socket, path ) 0085 { 0086 var userResponse = null; 0087 for( var registeredPath in this.registry ) 0088 { 0089 Amarok.debug( path.indexOf( registeredPath ) + " for " + registeredPath + " in " + path ); 0090 if( path.indexOf( registeredPath ) == 0 ) 0091 { 0092 userResponse = this.registry[registeredPath]( path.substring( registeredPath.length ) ); 0093 break; 0094 } 0095 } 0096 0097 Amarok.debug( "respondTo says::" + userResponse + "::"); 0098 if( userResponse == null ) 0099 { 0100 //var response404 = new QHttpResponseHeader( 404, "Not found", 1, 1 ); 0101 // responseHeader.setStatusLine( 404 ); 0102 //responseHeader.setContentType( "text/html" ) 0103 content = "HTTP/1.1 404 Not found\n" 0104 content += "Content-Type: text/html\n"; 0105 content += "Server: AmarokServer\n\r\n"; 0106 content += "<html><head><title>File not found</title></head>\n"; 0107 content += "<h1>404 Error</h1>\n" 0108 content += path + " not found.\n\r\n"; 0109 //responseHeader.setContentLength( content.length() ); 0110 var writeMe = new QByteArray(); 0111 //writeMe.append( response404.toString() ) 0112 writeMe.append( content ) 0113 socket.write( writeMe ); 0114 Amarok.debug("response:\n" + writeMe.toString() + " sent."); 0115 } 0116 else 0117 { 0118 try{ 0119 content = "HTTP/1.1 200\n" 0120 content += "Content-Type: " + userResponse.mimeType + "\n"; 0121 content += "Server: AmarokServer\n\r\n"; 0122 var writeMe = new QByteArray(); 0123 writeMe.append( content ); 0124 writeMe.append( userResponse.content ); 0125 socket.write( writeMe ); 0126 Amarok.debug("response:\n" + writeMe.toString() + " sent."); 0127 } 0128 catch( e ) 0129 { 0130 Amarok.debug( e ) 0131 } 0132 } 0133 } 0134 0135 HttpServer.prototype.register = function( path, responseFn ) 0136 { 0137 this.registry[path] = responseFn; 0138 if( path.charAt(0) === "/" ) 0139 { 0140 path = path.slice(1); 0141 } 0142 } 0143 0144 0145 function fileResponse( path ) 0146 { 0147 Amarok.debug( "requesting " + path ); 0148 var prefix = "/home/ian/.kde4/share/apps/amarok/scripts/script_console2/webrok/"; 0149 if( path === "/" || path === "" ) 0150 { 0151 path = "index.js.html"; 0152 } 0153 //we need to make sure it doesn't ../ out of the root 0154 url = new QUrl( path ); 0155 var fi = new QFileInfo( prefix + url.path() ); 0156 if( fi.absoluteFilePath().indexOf( prefix ) == 0 ) 0157 { 0158 Amarok.debug( "sending " + fi.absoluteFilePath() ); 0159 var file = new QFile( fi.absoluteFilePath() ); 0160 if( file.open( QIODevice.ReadOnly ) ) 0161 { 0162 var ret = new Object(); 0163 if( fi.completeSuffix() == "xml" ) 0164 { 0165 ret.mimeType = "application/xml"; 0166 } 0167 else 0168 { 0169 ret.mimeType = "text/html"; 0170 } 0171 ret.content = file.readAll() 0172 return ret; 0173 } 0174 else 0175 { 0176 Amarok.debug("file not found") 0177 return null; 0178 } 0179 } 0180 else 0181 { 0182 Amarok.debug( fi.absoluteFilePath() + " fails security check." ); 0183 return null; //send 404 error 0184 } 0185 } 0186 0187 function testResponse() 0188 { 0189 return "<h3>test</h3>"; 0190 } 0191 0192 function ajaxResponse( pathStr ) 0193 { 0194 url = new QUrl( pathStr ); 0195 command = url.path(); 0196 Amarok.debug( "the command is " + command ); 0197 switch( command ) 0198 { 0199 case "/play": 0200 row = Number( url.queryItemValue( "row" ) ); 0201 Amarok.Playlist.playByIndex( row ); 0202 Amarok.debug("playing file"); 0203 var ret = new Object(); 0204 ret.mimeType = "text/plain"; 0205 ret.content = "Playing row " + row; 0206 return ret; 0207 break; 0208 case "/savePlaylist": 0209 Amarok.Playlist.savePlaylist("/home/ian/.kde4/share/apps/amarok/scripts/script_console2/webrok/current.xspf"); 0210 var ret = new Object(); 0211 ret.mimeType = "text/plain"; 0212 ret.content = "saving playlist" 0213 return ret; 0214 breakZZz; 0215 } 0216 return null; //404 0217 } 0218 0219 http = new HttpServer(); 0220 http.register( "/ajax", ajaxResponse ); 0221 http.register( "/test", testResponse ); 0222 http.register( "/", fileResponse );