summaryrefslogtreecommitdiff
path: root/noncore/unsupported/ubrowser/httpfactory.cpp
Unidiff
Diffstat (limited to 'noncore/unsupported/ubrowser/httpfactory.cpp') (more/less context) (show whitespace changes)
-rw-r--r--noncore/unsupported/ubrowser/httpfactory.cpp376
1 files changed, 376 insertions, 0 deletions
diff --git a/noncore/unsupported/ubrowser/httpfactory.cpp b/noncore/unsupported/ubrowser/httpfactory.cpp
new file mode 100644
index 0000000..369f206
--- a/dev/null
+++ b/noncore/unsupported/ubrowser/httpfactory.cpp
@@ -0,0 +1,376 @@
1/*
2Opie-uBrowser. a very small web browser, using on QTextBrowser for html display/parsing
3Copyright (C) 2002 Thomas Stephens
4
5This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
6License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
7version.
8
9This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
10implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
11Public License for more details.
12
13You should have received a copy of the GNU General Public License along with this program; if not, write to the Free
14Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15*/
16
17#include "httpfactory.h"
18
19HttpFactory::HttpFactory(QTextBrowser *newBrowser):QMimeSourceFactory()
20{
21 //socket = new QSocket;
22 text = new QTextDrag;
23 browser=newBrowser;
24 //comm = new HttpComm(socket, browser);
25 image = new QImageDrag;
26}
27
28const QMimeSource * HttpFactory::data(const QString &abs_name) const
29{
30 printf("HttpFactory::data: using absolute data func\n");
31
32 int port=80, addrEnd, portSep;
33 QString host, file, portS, name, tempString;
34 bool done=false, isText=true;
35
36 //comm->setUp((QString *)&abs_name);
37
38 name = abs_name;
39 //name = name.lower();
40 name = name.stripWhiteSpace();
41
42 //printf("%s\n", name.latin1());
43
44 if(name.startsWith("http://"))
45 {
46 name = name.remove(0, 7);
47 }
48 else
49 {
50 name.prepend(browser->context());
51 name = name.remove(0, 7);
52 }
53
54 addrEnd = name.find('/');
55 if(addrEnd == -1)
56 {
57 name += '/';
58 addrEnd = name.length()-1;
59 }
60
61 host = name;
62 file = name;
63
64 host.truncate(addrEnd);
65 file.remove(0, addrEnd);
66
67 portSep = host.find(':');
68 if(portSep != -1)
69 {
70 portS=host;
71 host.truncate(portSep);
72 portS.remove(0, portSep+1);
73 port = portS.toInt();
74 }
75
76 //printf("%s %s %d\n", host.latin1(), file.latin1(), port);
77
78 if(port == 80)
79 {
80 portS="80";
81 }
82
83 //if(file.find(".png", file.length()-4) != -1 || file.find(".gif", file.length()-4) != -1 || file.find(".jpg", file.length()-4) != -1)
84 //{
85 // isImage=true;
86 //}
87
88 //comm->setStuff(host, portS, file, text, image, isImage);
89
90 //socket->connectToHost(host, port);
91
92 int con, bytesSent;
93 struct sockaddr_in serverAddr;
94 struct hostent * serverInfo = gethostbyname( host.latin1() );
95
96 if( serverInfo == NULL )
97 {
98 QMessageBox *mb = new QMessageBox(QObject::tr("Error!"),
99 QObject::tr("IP-Address not found"),
100 QMessageBox::NoIcon,
101 QMessageBox::Ok,
102 QMessageBox::NoButton,
103 QMessageBox::NoButton);
104 mb->exec();
105 perror("HttpFactory::data:");
106 return 0;
107 }
108
109 QByteArray data;
110 //printf( "HttpFactory::data: %s\n", inet_ntoa(*((struct in_addr *)serverInfo->h_addr )) );
111
112 QString request("GET " + file + " HTTP/1.1\r\nHost: " + host + ':' + portS + "\r\nConnection: close\r\n\r\n");
113
114 con = socket( AF_INET, SOCK_STREAM, 0 );
115 if( con == -1 )
116 {
117 QMessageBox *mb = new QMessageBox(QObject::tr("Error!"),
118 QObject::tr("Error creating socket"),
119 QMessageBox::NoIcon,
120 QMessageBox::Ok,
121 QMessageBox::NoButton,
122 QMessageBox::NoButton);
123 mb->exec();
124 perror("HttpFactory::data:");
125 return 0;
126 }
127
128 serverAddr.sin_family = AF_INET;
129 serverAddr.sin_port = htons( port );
130 serverAddr.sin_addr.s_addr = inet_addr( inet_ntoa(*((struct in_addr *)serverInfo->h_addr )) );
131 memset( &(serverAddr.sin_zero), '\0', 8 );
132
133 if(::connect( con, (struct sockaddr *)&serverAddr, sizeof(struct sockaddr)) == -1 )
134 {
135 QMessageBox *mb = new QMessageBox(QObject::tr("Error!"),
136 QObject::tr("Error connecting to socket"),
137 QMessageBox::NoIcon,
138 QMessageBox::Ok,
139 QMessageBox::NoButton,
140 QMessageBox::NoButton);
141 mb->exec();
142 perror("HttpFactory::data:");
143 return 0;
144 }
145
146
147 bytesSent = send( con, request.latin1(), request.length(), 0);
148 //printf("HttpFactory::data: bytes written: %d out of: %d\n", bytesSent, request.length() );
149 //printf("HttpFactory::data: request sent:\n%s", request.latin1());
150
151 data = this->processResponse( con, isText );
152
153 ::close( con );
154
155 if(isText)
156 {
157 text->setText( QString( data ) );
158 return text;
159 }
160 else
161 {
162 image->setImage( QImage( data ) );
163 return image;
164 }
165}
166
167const QMimeSource * HttpFactory::data(const QString &abs_or_rel_name, const QString & context) const
168{
169 printf("HttpFactory::data: using relative data func\n");
170
171 if(abs_or_rel_name.startsWith(context))
172 {
173 return data(abs_or_rel_name);
174 }
175 else
176 {
177 return data(context + abs_or_rel_name);
178 }
179
180 return 0;
181}
182
183const QByteArray HttpFactory::processResponse( int sockfd, bool &isText ) const
184{
185 QByteArray inputBin( 1 );
186 QByteArray conClosedErr( 27 );
187 char conClosedErrMsg[] = "Connection to server closed";
188 QString currentLine;
189 bool done=false, chunked=false;
190 int dataLength = 0;
191
192 for( int i = 0; i < 27; i++)
193 {
194 conClosedErr[i] = conClosedErrMsg[i];
195 }
196
197 while( !done )
198 {
199 recv( sockfd, inputBin.data(), inputBin.size(), 0 );
200 currentLine += *(inputBin.data());
201
202 if( *(inputBin.data()) == '\n' )
203 {
204 if( currentLine.isEmpty() || currentLine.startsWith( "\r") )
205 {
206 printf( "HttpFactory::processResponse: end of header\n" );
207 if( chunked )
208 {
209 return recieveChunked( sockfd );
210 } else {
211 return recieveNormal( sockfd, dataLength );
212 }
213 done = true;
214 }
215
216 if( currentLine.contains( "Transfer-Encoding: chunked", false) >= 1 )
217 {
218 chunked = true;
219 // printf( "HttpFactory::processResponse: chunked encoding\n" );
220 }
221
222 if( currentLine.contains( "Content-Type: text", false ) >= 1 )
223 {
224 isText = true;
225 // printf( "HttpFactory::processResponse: content type text\n" );
226 if( currentLine.contains( "html", false ) >= 1)
227 {
228 browser->setTextFormat(Qt::RichText);
229 // printf( "HttpFactory::processResponse: content type html\n" );
230 }
231 }
232
233 if( currentLine.contains( "Content-Type: image", false ) >= 1 )
234 {
235 isText = false;
236 // printf( "HttpFactory::processResponse: content type image\n" );
237 }
238
239 if( currentLine.contains( "Content-Length", false ) >= 1 )
240 {
241 currentLine.remove( 0, 16 );
242 dataLength = currentLine.toInt();
243 // printf( "HttpFactory::processResponse: content length: %d\n", dataLength );
244 }
245
246 if( currentLine.contains( "404", false ) >= 1 )
247 {
248 // printf( "HttpFactory::processResponse: 404 error\n" );
249 return 0;
250 }
251
252 currentLine = "";
253 // printf("HttpFactory::processResponse: reseting currentLine: %s\n", currentLine.latin1() );
254 }
255 }
256}
257
258const QByteArray HttpFactory::recieveNormal( int sockfd, int dataLen ) const
259{
260 //printf( "HttpFactory::recieveNormal: recieving w/out chunked encoding\n" );
261
262 QByteArray data( dataLen );
263 QByteArray temp( dataLen );
264 int recieved, i;
265
266 recieved = recv( sockfd, temp.data(), temp.size(), 0 );
267 //printf( "HttpFactory::recieveNormal: found some data: %s\n", (char *)temp.data() );
268 for( i = 0; i < recieved; i++ )
269 {
270 data[i] = temp[i];
271 }
272 dataLen -= recieved;
273 while( dataLen > 0 )
274 {
275 recieved = recv( sockfd, temp.data(), temp.size(), 0 );
276 dataLen -= recieved;
277 // printf( "HttpFactory::recieveNormal: found some more data: %s\n", (char *)temp.data() );
278 for( int j = 0; j < recieved; j++ )
279 {
280 data[i] = temp[j];
281 i++;
282 }
283 temp.fill('\0');
284 }
285
286 //printf( "HttpFactory::recieveNormal: end of data\n" );
287 return data;
288}
289
290const QByteArray HttpFactory::recieveChunked( int sockfd ) const
291{
292 //printf( "HttpFactory::recieveChunked: recieving data with chunked encoding\n" );
293
294 QByteArray data;
295 QByteArray temp( 1 );
296 int recieved, i = 0, cSize = 0;
297 QString cSizeS;
298
299 //printf( "HttpFactory::recieveChunked: temp.size(): %d\n", temp.size() );
300 recv( sockfd, temp.data(), temp.size(), 0 );
301 while( *(temp.data()) != '\n' && *(temp.data()) != ';' )
302 {
303 // printf( "HttpFactory::recieveChunked: temp.size(): %d\n", temp.size() );
304 // printf( "HttpFactory::recieveChunked: temp.data(): %c\n", temp[0] );
305 cSizeS += temp[0];
306 recv( sockfd, temp.data(), temp.size(), 0 );
307 }
308
309 //printf( "HttpFactory::recieveChunked: cSizeS: %s\n", cSizeS.latin1() );
310 cSize = cSizeS.toInt( 0, 16 );
311 //printf( "HttpFactory::recieveChunked: first chunk of size: %d\n", cSize );
312
313 if( *(temp.data()) == ';' )
314 {
315 while( *(temp.data()) != '\n' )
316 {
317 recv( sockfd, temp.data(), temp.size(), 0 );
318 }
319 }
320
321 temp.fill( '\0', cSize );
322 data.fill( '\0', cSize );
323
324 while( cSize > 0 )
325 {
326 while( cSize > 0 )
327 {
328 recieved = recv( sockfd, temp.data(), temp.size(), 0 );
329 cSize -= recieved;
330 for( int j = 0; j < recieved; j++ )
331 {
332 data[i] = temp[j];
333 i++;
334 }
335 temp.fill('\0', cSize);
336 }
337
338 // printf( "HttpFactory::recieveChunked: current data:\n%s", data.data() );
339
340 temp.fill('\0', 1);
341 cSizeS = "";
342 cSize = 0;
343
344 recv( sockfd, temp.data(), temp.size(), 0 );
345 if( *(temp.data()) == '\r' )
346 {
347 recv( sockfd, temp.data(), temp.size(), 0 );
348 }
349 recv( sockfd, temp.data(), temp.size(), 0 );
350 while( *(temp.data()) != '\n' && *(temp.data()) != ';' )
351 {
352 // printf( "HttpFactory::recieveChunked: temp.size(): %d\n", temp.size() );
353 // printf( "HttpFactory::recieveChunked: temp.data(): %d\n", temp[0] );
354 cSizeS += temp[0];
355 recv( sockfd, temp.data(), temp.size(), 0 );
356 }
357
358 // printf( "HttpFactory::recieveChunked: cSizeS: %s\n", cSizeS.latin1() );
359 cSize = cSizeS.toInt( 0, 16 );
360 // printf( "HttpFactory::recieveChunked: next chunk of size: %d\n", cSize );
361
362 if( *(temp.data()) == ';' )
363 {
364 while( *(temp.data()) != '\n' )
365 {
366 recv( sockfd, temp.data(), temp.size(), 0 );
367 }
368 }
369
370 temp.fill( '\0', cSize );
371 data.resize( data.size() + cSize );
372 }
373
374 //printf( "HttpFactory::recieveChunked: end of data\n" );
375 return data;
376}