00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "httpfactory.h"
00018
00019 HttpFactory::HttpFactory(QTextBrowser *newBrowser):QMimeSourceFactory()
00020 {
00021
00022 text = new QTextDrag;
00023 browser=newBrowser;
00024
00025 image = new QImageDrag;
00026 }
00027
00028 const QMimeSource * HttpFactory::data(const QString &abs_name) const
00029 {
00030 printf("HttpFactory::data: using absolute data func\n");
00031
00032 int port=80, addrEnd, portSep;
00033 QString host, file, portS, name, tempString;
00034 bool done=false, isText=true;
00035
00036
00037
00038 name = abs_name;
00039
00040 name = name.stripWhiteSpace();
00041
00042
00043
00044 if(name.startsWith("http://"))
00045 {
00046 name = name.remove(0, 7);
00047 }
00048 else
00049 {
00050 name.prepend(browser->context());
00051 name = name.remove(0, 7);
00052 }
00053
00054 addrEnd = name.find('/');
00055 if(addrEnd == -1)
00056 {
00057 name += '/';
00058 addrEnd = name.length()-1;
00059 }
00060
00061 host = name;
00062 file = name;
00063
00064 host.truncate(addrEnd);
00065 file.remove(0, addrEnd);
00066
00067 portSep = host.find(':');
00068 if(portSep != -1)
00069 {
00070 portS=host;
00071 host.truncate(portSep);
00072 portS.remove(0, portSep+1);
00073 port = portS.toInt();
00074 }
00075
00076
00077
00078 if(port == 80)
00079 {
00080 portS="80";
00081 }
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 int con, bytesSent;
00093 struct sockaddr_in serverAddr;
00094 struct hostent * serverInfo = gethostbyname( host.latin1() );
00095
00096 if( serverInfo == NULL )
00097 {
00098 QMessageBox *mb = new QMessageBox(QObject::tr("Error!"),
00099 QObject::tr("IP-Address not found"),
00100 QMessageBox::NoIcon,
00101 QMessageBox::Ok,
00102 QMessageBox::NoButton,
00103 QMessageBox::NoButton);
00104 mb->exec();
00105 perror("HttpFactory::data:");
00106 return 0;
00107 }
00108
00109 QByteArray data;
00110
00111
00112 QString request("GET " + file + " HTTP/1.1\r\nHost: " + host + ':' + portS + "\r\nConnection: close\r\n\r\n");
00113
00114 con = socket( AF_INET, SOCK_STREAM, 0 );
00115 if( con == -1 )
00116 {
00117 QMessageBox *mb = new QMessageBox(QObject::tr("Error!"),
00118 QObject::tr("Error creating socket"),
00119 QMessageBox::NoIcon,
00120 QMessageBox::Ok,
00121 QMessageBox::NoButton,
00122 QMessageBox::NoButton);
00123 mb->exec();
00124 perror("HttpFactory::data:");
00125 return 0;
00126 }
00127
00128 serverAddr.sin_family = AF_INET;
00129 serverAddr.sin_port = htons( port );
00130 serverAddr.sin_addr.s_addr = inet_addr( inet_ntoa(*((struct in_addr *)serverInfo->h_addr )) );
00131 memset( &(serverAddr.sin_zero), '\0', 8 );
00132
00133 if(::connect( con, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr)) == -1 )
00134 {
00135 QMessageBox *mb = new QMessageBox(QObject::tr("Error!"),
00136 QObject::tr("Error connecting to socket"),
00137 QMessageBox::NoIcon,
00138 QMessageBox::Ok,
00139 QMessageBox::NoButton,
00140 QMessageBox::NoButton);
00141 mb->exec();
00142 perror("HttpFactory::data:");
00143 return 0;
00144 }
00145
00146
00147 bytesSent = send( con, request.latin1(), request.length(), 0);
00148
00149
00150
00151 data = this->processResponse( con, isText );
00152
00153 ::close( con );
00154
00155 if(isText)
00156 {
00157 text->setText( QString( data ) );
00158 return text;
00159 }
00160 else
00161 {
00162 image->setImage( QImage( data ) );
00163 return image;
00164 }
00165 }
00166
00167 const QMimeSource * HttpFactory::data(const QString &abs_or_rel_name, const QString & context) const
00168 {
00169 printf("HttpFactory::data: using relative data func\n");
00170
00171 if(abs_or_rel_name.startsWith(context))
00172 {
00173 return data(abs_or_rel_name);
00174 }
00175 else
00176 {
00177 return data(context + abs_or_rel_name);
00178 }
00179
00180 return 0;
00181 }
00182
00183 const QByteArray HttpFactory::processResponse( int sockfd, bool &isText ) const
00184 {
00185 QByteArray inputBin( 1 );
00186 QByteArray conClosedErr( 27 );
00187 char conClosedErrMsg[] = "Connection to server closed";
00188 QString currentLine;
00189 bool done=false, chunked=false;
00190 int dataLength = 0;
00191
00192 for( int i = 0; i < 27; i++)
00193 {
00194 conClosedErr[i] = conClosedErrMsg[i];
00195 }
00196
00197 while( !done )
00198 {
00199 recv( sockfd, inputBin.data(), inputBin.size(), 0 );
00200 currentLine += *(inputBin.data());
00201
00202 if( *(inputBin.data()) == '\n' )
00203 {
00204 if( currentLine.isEmpty() || currentLine.startsWith( "\r") )
00205 {
00206 printf( "HttpFactory::processResponse: end of header\n" );
00207 if( chunked )
00208 {
00209 return recieveChunked( sockfd );
00210 } else {
00211 return recieveNormal( sockfd, dataLength );
00212 }
00213 done = true;
00214 }
00215
00216 if( currentLine.contains( "Transfer-Encoding: chunked", false) >= 1 )
00217 {
00218 chunked = true;
00219
00220 }
00221
00222 if( currentLine.contains( "Content-Type: text", false ) >= 1 )
00223 {
00224 isText = true;
00225
00226 if( currentLine.contains( "html", false ) >= 1)
00227 {
00228 browser->setTextFormat(Qt::RichText);
00229
00230 }
00231 }
00232
00233 if( currentLine.contains( "Content-Type: image", false ) >= 1 )
00234 {
00235 isText = false;
00236
00237 }
00238
00239 if( currentLine.contains( "Content-Length", false ) >= 1 )
00240 {
00241 currentLine.remove( 0, 16 );
00242 dataLength = currentLine.toInt();
00243
00244 }
00245
00246 if( currentLine.contains( "404", false ) >= 1 )
00247 {
00248
00249 return 0;
00250 }
00251
00252 currentLine = "";
00253
00254 }
00255 }
00256 }
00257
00258 const QByteArray HttpFactory::recieveNormal( int sockfd, int dataLen ) const
00259 {
00260
00261
00262 QByteArray data( dataLen );
00263 QByteArray temp( dataLen );
00264 int recieved, i;
00265
00266 recieved = recv( sockfd, temp.data(), temp.size(), 0 );
00267
00268 for( i = 0; i < recieved; i++ )
00269 {
00270 data[i] = temp[i];
00271 }
00272 dataLen -= recieved;
00273 while( dataLen > 0 )
00274 {
00275 recieved = recv( sockfd, temp.data(), temp.size(), 0 );
00276 dataLen -= recieved;
00277
00278 for( int j = 0; j < recieved; j++ )
00279 {
00280 data[i] = temp[j];
00281 i++;
00282 }
00283 temp.fill('\0');
00284 }
00285
00286
00287 return data;
00288 }
00289
00290 const QByteArray HttpFactory::recieveChunked( int sockfd ) const
00291 {
00292
00293
00294 QByteArray data;
00295 QByteArray temp( 1 );
00296 int recieved, i = 0, cSize = 0;
00297 QString cSizeS;
00298
00299
00300 recv( sockfd, temp.data(), temp.size(), 0 );
00301 while( *(temp.data()) != '\n' && *(temp.data()) != ';' )
00302 {
00303
00304
00305 cSizeS += temp[0];
00306 recv( sockfd, temp.data(), temp.size(), 0 );
00307 }
00308
00309
00310 cSize = cSizeS.toInt( 0, 16 );
00311
00312
00313 if( *(temp.data()) == ';' )
00314 {
00315 while( *(temp.data()) != '\n' )
00316 {
00317 recv( sockfd, temp.data(), temp.size(), 0 );
00318 }
00319 }
00320
00321 temp.fill( '\0', cSize );
00322 data.fill( '\0', cSize );
00323
00324 while( cSize > 0 )
00325 {
00326 while( cSize > 0 )
00327 {
00328 recieved = recv( sockfd, temp.data(), temp.size(), 0 );
00329 cSize -= recieved;
00330 for( int j = 0; j < recieved; j++ )
00331 {
00332 data[i] = temp[j];
00333 i++;
00334 }
00335 temp.fill('\0', cSize);
00336 }
00337
00338
00339
00340 temp.fill('\0', 1);
00341 cSizeS = "";
00342 cSize = 0;
00343
00344 recv( sockfd, temp.data(), temp.size(), 0 );
00345 if( *(temp.data()) == '\r' )
00346 {
00347 recv( sockfd, temp.data(), temp.size(), 0 );
00348 }
00349 recv( sockfd, temp.data(), temp.size(), 0 );
00350 while( *(temp.data()) != '\n' && *(temp.data()) != ';' )
00351 {
00352
00353
00354 cSizeS += temp[0];
00355 recv( sockfd, temp.data(), temp.size(), 0 );
00356 }
00357
00358
00359 cSize = cSizeS.toInt( 0, 16 );
00360
00361
00362 if( *(temp.data()) == ';' )
00363 {
00364 while( *(temp.data()) != '\n' )
00365 {
00366 recv( sockfd, temp.data(), temp.size(), 0 );
00367 }
00368 }
00369
00370 temp.fill( '\0', cSize );
00371 data.resize( data.size() + cSize );
00372 }
00373
00374
00375 return data;
00376 }