~ubuntu-branches/ubuntu/karmic/gnash/karmic

« back to all changes in this revision

Viewing changes to cygnal/http.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack
  • Date: 2008-10-13 14:29:49 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20081013142949-f6qdvnu4mn05ltdc
Tags: 0.8.4~~bzr9980-0ubuntu1
* new upstream release 0.8.4 (LP: #240325)
* ship new lib usr/lib/gnash/libmozsdk.so.* in mozilla-plugin-gnash
  - update debian/mozilla-plugin-gnash.install
* ship new lib usr/lib/gnash/libgnashnet.so.* in gnash-common
  - update debian/gnash-common.install
* add basic debian/build_head script to build latest CVS head packages.
  - add debian/build_head
* new sound architecture requires build depend on libsdl1.2-dev
  - update debian/control
* head build script now has been completely migrated to bzr (upstream +
  ubuntu)
  - update debian/build_head
* disable kde gui until klash/qt4 has been fixed; keep kde packages as empty
  packages for now.
  - update debian/rules
  - debian/klash.install
  - debian/klash.links
  - debian/klash.manpages
  - debian/konqueror-plugin-gnash.install
* drop libkonq5-dev build dependency accordingly
  - update debian/control
* don't install headers manually anymore. gnash doesnt provide a -dev
  package after all
  - update debian/rules
* update libs installed in gnash-common; libgnashserver-*.so is not available
  anymore (removed); in turn we add the new libgnashcore-*.so
  - update debian/gnash-common.install
* use -Os for optimization and properly pass CXXFLAGS=$(CFLAGS) to configure
  - update debian/rules
* touch firefox .autoreg in postinst of mozilla plugin
  - update debian/mozilla-plugin-gnash.postinst
* link gnash in ubufox plugins directory for the plugin alternative switcher
  - add debian/mozilla-plugin-gnash.links
* suggest ubufox accordingly
  - update debian/control
* add new required build-depends on libgif-dev
  - update debian/control
* add Xb-Npp-Description and Xb-Npp-File as new plugin database meta data
  - update debian/control

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// http.cpp:  HyperText Transport Protocol handler for Cygnal, for Gnash.
2
 
// 
3
 
//   Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
4
 
// 
5
 
// This program is free software; you can redistribute it and/or modify
6
 
// it under the terms of the GNU General Public License as published by
7
 
// the Free Software Foundation; either version 3 of the License, or
8
 
// (at your option) any later version.
9
 
// 
10
 
// This program is distributed in the hope that it will be useful,
11
 
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
// GNU General Public License for more details.
14
 
//
15
 
// You should have received a copy of the GNU General Public License
16
 
// along with this program; if not, write to the Free Software
17
 
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 
//
19
 
 
20
 
#ifdef HAVE_CONFIG_H
21
 
#include "gnashconfig.h"
22
 
#endif
23
 
 
24
 
#include <boost/thread/mutex.hpp>
25
 
#include <boost/date_time/gregorian/gregorian.hpp>
26
 
//#include <boost/date_time/local_time/local_time.hpp>
27
 
#include <boost/date_time/posix_time/posix_time.hpp>
28
 
//#include <boost/date_time/time_zone_base.hpp>
29
 
#include <string>
30
 
#include <iostream>
31
 
#include <cstring>
32
 
#include <sys/types.h>
33
 
#include <sys/stat.h>
34
 
#include "http.h"
35
 
#include "log.h"
36
 
 
37
 
using namespace gnash;
38
 
using namespace std;
39
 
 
40
 
static boost::mutex stl_mutex;
41
 
 
42
 
namespace cygnal
43
 
{
44
 
 
45
 
// FIXME, this seems too small to me.  --gnu
46
 
static const int readsize = 1024;
47
 
 
48
 
HTTP::HTTP() 
49
 
    : _port(80), _filesize(0), _keepalive(false)
50
 
{
51
 
//    GNASH_REPORT_FUNCTION;
52
 
//    struct status_codes *status = new struct status_codes;
53
 
    
54
 
//    _status_codes(CONTINUE, status);
55
 
}
56
 
 
57
 
HTTP::~HTTP()
58
 
{
59
 
//    GNASH_REPORT_FUNCTION;
60
 
}
61
 
 
62
 
bool
63
 
HTTP::clearHeader()
64
 
{
65
 
    _header.str("");
66
 
    _body.str("");
67
 
    _charset.clear();
68
 
    _connections.clear();
69
 
    _language.clear();
70
 
    _encoding.clear();
71
 
    _te.clear();
72
 
    _accept.clear();
73
 
    _filesize = 0;
74
 
}
75
 
 
76
 
HTTP &
77
 
HTTP::operator = (HTTP& /*obj*/)
78
 
{
79
 
    GNASH_REPORT_FUNCTION;
80
 
//    this = obj;
81
 
    // TODO: FIXME !
82
 
    return *this; 
83
 
}
84
 
 
85
 
string
86
 
HTTP::waitForGetRequest(Network& /*net*/)
87
 
{
88
 
    GNASH_REPORT_FUNCTION;
89
 
    return ""; // TODO: FIXME !
90
 
}
91
 
 
92
 
string
93
 
HTTP::waitForGetRequest()
94
 
{
95
 
    GNASH_REPORT_FUNCTION;
96
 
 
97
 
    char buffer[readsize+1];
98
 
    memset(buffer, 0, readsize+1);
99
 
    if (readNet(buffer, readsize) > 0) {
100
 
        log_debug (_("Read initial GET Request"));
101
 
    } else {
102
 
        log_error (_("Couldn't read initial GET Request"));
103
 
    }
104
 
 
105
 
    clearHeader();
106
 
    extractAccept(buffer);
107
 
    extractMethod(buffer);
108
 
    extractReferer(buffer);
109
 
    extractHost(buffer);
110
 
    extractAgent(buffer);
111
 
    extractLanguage(buffer);
112
 
    extractCharset(buffer);
113
 
    extractConnection(buffer);
114
 
    extractEncoding(buffer);
115
 
    extractTE(buffer);
116
 
    dump();
117
 
 
118
 
    // See if we got a legit GET request
119
 
    if (strncmp(buffer, "GET ", 4) == 0) {
120
 
        log_debug (_("Got legit GET request"));
121
 
    } else {
122
 
        log_error (_("Got bogus GET request"));
123
 
    }
124
 
 
125
 
    _filespec = _url;
126
 
    return _url;
127
 
}
128
 
 
129
 
bool
130
 
HTTP::formatHeader(const short type)
131
 
{
132
 
    GNASH_REPORT_FUNCTION;
133
 
 
134
 
    formatHeader(_filesize, type);
135
 
}
136
 
 
137
 
 
138
 
bool
139
 
HTTP::formatHeader(int filesize, const short type)
140
 
{
141
 
    GNASH_REPORT_FUNCTION;
142
 
 
143
 
    _header << "HTTP/1.1 200 OK" << endl;
144
 
    this->formatServer();
145
 
    this->formatDate();
146
 
    this->formatConnection("close");
147
 
//     _header << "Accept-Ranges: bytes" << endl;
148
 
    this->formatContentLength(filesize);
149
 
    this->formatContentType();
150
 
    // All HTTP messages are followed by a blank line.
151
 
    this->terminateHeader();
152
 
}
153
 
 
154
 
bool
155
 
HTTP::formatErrorResponse(http_status_e code)
156
 
{
157
 
    GNASH_REPORT_FUNCTION;
158
 
 
159
 
    // First build the message body, so we know how to set Content-Length
160
 
    _body << "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">" << endl;
161
 
    _body << "<html><head>" << endl;
162
 
    _body << "<title>" << code << " Not Found</title>" << endl;
163
 
    _body << "</head><body>" << endl;
164
 
    _body << "<h1>Not Found</h1>" << endl;
165
 
    _body << "<p>The requested URL " << _filespec << " was not found on this server.</p>" << endl;
166
 
    _body << "<hr>" << endl;
167
 
    _body << "<address>Cygnal (GNU/Linux) Server at localhost Port " << _port << " </address>" << endl;
168
 
    _body << "</body></html>" << endl;
169
 
    _body << endl;
170
 
 
171
 
    // First build the header
172
 
    _header << "HTTP/1.1 " << code << " Not Found" << endl;
173
 
    formatDate();
174
 
    formatServer();
175
 
    _filesize = _body.str().size();
176
 
    formatContentLength(_filesize);
177
 
    formatConnection("close");
178
 
    formatContentType(HTTP::HTML);
179
 
}
180
 
 
181
 
bool
182
 
HTTP::formatDate()
183
 
{
184
 
    GNASH_REPORT_FUNCTION;
185
 
    boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
186
 
    
187
 
//    cout <<  now.time_of_day() << endl;
188
 
    
189
 
    boost::gregorian::date d(now.date());
190
 
//     boost::gregorian::date d(boost::gregorian::day_clock::local_day());
191
 
//     cout << boost::posix_time::to_simple_string(now) << endl;
192
 
//     cout << d.day_of_week() << endl;
193
 
//     cout << d.day() << endl;
194
 
//     cout << d.year() << endl;
195
 
//     cout << d.month() << endl;
196
 
    
197
 
//    boost::date_time::time_zone_ptr zone(new posix_time_zone("MST"));
198
 
//    boost::date_time::time_zone_base b(now "MST");
199
 
//    cout << zone.dst_zone_abbrev() << endl;
200
 
 
201
 
    _header << "Date: " << d.day_of_week();
202
 
    _header << ", " << d.day();
203
 
    _header << " "  << d.month();
204
 
    _header << " "  << d.year();
205
 
    _header << " "  << now.time_of_day();
206
 
    _header << " GMT" << endl;
207
 
 
208
 
}
209
 
 
210
 
bool
211
 
HTTP::formatServer()
212
 
{
213
 
    GNASH_REPORT_FUNCTION;
214
 
    _header << "Server: Cygnal (GNU/Linux)" << endl;
215
 
}
216
 
 
217
 
bool
218
 
HTTP::formatServer(const char *data)
219
 
{
220
 
    GNASH_REPORT_FUNCTION;
221
 
    _header << "Server: " << data << endl;
222
 
}
223
 
 
224
 
bool
225
 
HTTP::formatMethod(const char *data)
226
 
{
227
 
    GNASH_REPORT_FUNCTION;
228
 
    _header << "Method: " << data << endl;
229
 
}
230
 
 
231
 
bool
232
 
HTTP::formatReferer(const char *refer)
233
 
{
234
 
    GNASH_REPORT_FUNCTION;
235
 
    _header << "Referer: " << refer << endl;
236
 
}
237
 
 
238
 
bool
239
 
HTTP::formatConnection(const char *options)
240
 
{
241
 
    GNASH_REPORT_FUNCTION;
242
 
    _header << "Connection: " << options << endl;
243
 
}
244
 
 
245
 
bool
246
 
HTTP::formatContentType()
247
 
{
248
 
    return formatContentType(_filetype);
249
 
}
250
 
 
251
 
bool
252
 
HTTP::formatContentType(filetype_e filetype)
253
 
{
254
 
//    GNASH_REPORT_FUNCTION;
255
 
    
256
 
    switch (filetype) {
257
 
      case HTML:
258
 
          _header << "Content-Type: text/html; charset=UTF-8" << endl;
259
 
          break;
260
 
      case SWF:
261
 
          _header << "Content-Type: application/x-shockwave-flash" << endl;
262
 
//        _header << "Content-Type: application/futuresplash" << endl;
263
 
          break;
264
 
      case VIDEO:
265
 
          _header << "Content-Type: video/flv" << endl;
266
 
          break;
267
 
      case MP3:
268
 
          _header << "Content-Type: audio/mpeg" << endl;
269
 
          break;
270
 
      default:
271
 
          _header << "Content-Type: text/html; charset=UTF-8" << endl;
272
 
    }
273
 
}
274
 
 
275
 
bool
276
 
HTTP::formatContentLength()
277
 
{
278
 
//    GNASH_REPORT_FUNCTION;
279
 
    _header << "Content-Length: " << _filesize << endl;
280
 
}
281
 
 
282
 
bool
283
 
HTTP::formatContentLength(int filesize)
284
 
{
285
 
//    GNASH_REPORT_FUNCTION;
286
 
    _header << "Content-Length: " << filesize << endl;
287
 
}
288
 
 
289
 
bool
290
 
HTTP::formatHost(const char *host)
291
 
{
292
 
//    GNASH_REPORT_FUNCTION;
293
 
    _header << "Host: " << host << endl;
294
 
}
295
 
 
296
 
bool
297
 
HTTP::formatAgent(const char *agent)
298
 
{
299
 
//    GNASH_REPORT_FUNCTION;
300
 
    _header << "User-Agent: " << agent << endl;
301
 
}
302
 
 
303
 
bool
304
 
HTTP::formatLanguage(const char *lang)
305
 
{
306
 
//    GNASH_REPORT_FUNCTION;
307
 
 
308
 
    // For some browsers this appears to also be Content-Language
309
 
    _header << "Accept-Language: " << lang << endl;
310
 
}
311
 
 
312
 
bool
313
 
HTTP::formatCharset(const char *set)
314
 
{
315
 
    GNASH_REPORT_FUNCTION;
316
 
    // For some browsers this appears to also be Content-Charset
317
 
    _header << "Accept-Charset: " << set << endl;
318
 
}
319
 
 
320
 
bool
321
 
HTTP::formatEncoding(const char *code)
322
 
{
323
 
    GNASH_REPORT_FUNCTION;
324
 
    _header << "Accept-Encoding: " << code << endl;
325
 
}
326
 
 
327
 
bool
328
 
HTTP::formatTE(const char *te)
329
 
{
330
 
    GNASH_REPORT_FUNCTION;
331
 
    _header << "TE: " << te << endl;
332
 
}
333
 
 
334
 
bool
335
 
HTTP::sendGetReply(http_status_e code)
336
 
{
337
 
    GNASH_REPORT_FUNCTION;
338
 
    
339
 
    formatHeader(_filesize, HTML);
340
 
    int ret = writeNet(_header.str().c_str(), _header.str().size());
341
 
    if ( _body.str().size() > 0) {
342
 
        ret += writeNet(_body.str().c_str(), _body.str().size());
343
 
    }
344
 
 
345
 
    if (ret >= 0) {
346
 
        log_debug (_("Sent GET Reply"));
347
 
//        log_debug (_("Sent GET Reply: %s"), _header.str().c_str());
348
 
        clearHeader();
349
 
    } else {
350
 
        log_debug (_("Couldn't send GET Reply, writeNet returned %d"), ret);
351
 
        return false;
352
 
    }
353
 
//    cout << "GET Header is:" << endl << _header.str() << endl;
354
 
    return true; // Default to true
355
 
}
356
 
 
357
 
bool
358
 
HTTP::formatRequest(const char *url, http_method_e req)
359
 
{
360
 
    GNASH_REPORT_FUNCTION;
361
 
 
362
 
    _header.str("");
363
 
 
364
 
    _header << req << " " << url << "HTTP/1.1" << endl;
365
 
    _header << "User-Agent: Opera/9.01 (X11; Linux i686; U; en)" << endl;
366
 
    _header << "Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1" << endl;
367
 
 
368
 
    _header << "Accept-Language: en" << endl;
369
 
    _header << "Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1" << endl;
370
 
    
371
 
    _header << "Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0" << endl;
372
 
    _header << "Referer: " << url << endl;
373
 
 
374
 
    _header << "Connection: Keep-Alive, TE" << endl;
375
 
    _header << "TE: deflate, gzip, chunked, identity, trailers" << endl;
376
 
    
377
 
}
378
 
// bool
379
 
// HTTP::sendGetReply(Network &net)
380
 
// {
381
 
//     GNASH_REPORT_FUNCTION;    
382
 
// }
383
 
 
384
 
// This is what a GET request looks like.
385
 
// GET /software/gnash/tests/flvplayer2.swf?file=http://localhost:4080/software/gnash/tests/lulutest.flv HTTP/1.1
386
 
// User-Agent: Opera/9.01 (X11; Linux i686; U; en)
387
 
// Host: localhost:4080
388
 
// Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
389
 
// Accept-Language: en
390
 
// Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1
391
 
// Accept-Encoding: deflate, gzip, x-gzip, identity, *;q=0
392
 
// Referer: http://localhost/software/gnash/tests/
393
 
// Connection: Keep-Alive, TE
394
 
// TE: deflate, gzip, chunked, identity, trailers
395
 
int
396
 
HTTP::extractAccept(const char *data) {
397
 
//    GNASH_REPORT_FUNCTION;
398
 
    
399
 
    string body = data;
400
 
    string::size_type start, end, length, pos;
401
 
    string pattern = "Accept: ";
402
 
    
403
 
    start = body.find(pattern, 0);
404
 
    if (start == string::npos) {
405
 
        return -1;
406
 
    }
407
 
    end =  body.find("\r\n", start);
408
 
    if (end == string::npos) {
409
 
        end = body.find("\n", start);
410
 
//          return "error";
411
 
    }
412
 
 
413
 
    length = end-start-pattern.size();
414
 
    start = start+pattern.size();
415
 
    pos = start;
416
 
    while (pos <= end) {
417
 
        pos = (body.find(",", start) + 2);
418
 
        if (pos <= start) {
419
 
            return _encoding.size();
420
 
        }
421
 
        if ((pos == string::npos) || (pos > end)) {
422
 
            length = end - start;
423
 
        } else {
424
 
            length = pos - start - 2;
425
 
        }
426
 
        string substr = body.substr(start, length);
427
 
//      printf("FIXME: \"%s\"\n", substr.c_str());
428
 
        _accept.push_back(substr);
429
 
        start = pos;
430
 
    }
431
 
 
432
 
    return _accept.size();
433
 
}
434
 
 
435
 
string
436
 
HTTP::extractMethod(const char *data) {
437
 
//    GNASH_REPORT_FUNCTION;
438
 
    
439
 
    boost::mutex::scoped_lock lock(stl_mutex);
440
 
    string body = data;
441
 
    string::size_type start, end;
442
 
    int length;
443
 
 
444
 
    length = body.size();
445
 
    start = body.find(" ", 0);
446
 
    if (start == string::npos) {
447
 
        return "error";
448
 
    }
449
 
    _method = body.substr(0, start);
450
 
    end = body.find(" ", start+1);
451
 
    if (end == string::npos) {
452
 
        return "error";
453
 
    }
454
 
    _url = body.substr(start+1, end-start-1);
455
 
    _version = body.substr(end+1, length);
456
 
 
457
 
    end = _url.find("?", 0);
458
 
//    _filespec = _url.substr(start+1, end);
459
 
    return "error";
460
 
}
461
 
 
462
 
string 
463
 
HTTP::extractReferer(const char *data) {
464
 
//    GNASH_REPORT_FUNCTION;
465
 
    
466
 
    string body = data;
467
 
    string::size_type start, end;
468
 
    string pattern = "Referer: ";
469
 
    
470
 
    start = body.find(pattern, 0);
471
 
    if (start == string::npos) {
472
 
        return "error";
473
 
    }
474
 
    end =  body.find("\r\n", start);
475
 
    if (end == string::npos) {
476
 
        return "error";
477
 
    }
478
 
    
479
 
    _referer = body.substr(start+pattern.size(), end-start-1);
480
 
    return _referer;
481
 
}
482
 
 
483
 
int
484
 
HTTP::extractConnection(const char *data) {
485
 
//    GNASH_REPORT_FUNCTION;
486
 
    
487
 
    string body = data;
488
 
    string::size_type start, end, length, pos;
489
 
    string pattern = "Connection: ";
490
 
    
491
 
    start = body.find(pattern, 0);
492
 
    if (start == string::npos) {
493
 
        return -1;
494
 
    }
495
 
    end =  body.find("\r\n", start);
496
 
    if (end == string::npos) {
497
 
        end = body.find("\n", start);
498
 
//          return "error";
499
 
    }
500
 
 
501
 
    length = end-start-pattern.size();
502
 
    start = start+pattern.size();
503
 
    string _connection = body.substr(start, length);
504
 
    pos = start;
505
 
    while (pos <= end) {
506
 
        pos = (body.find(",", start) + 2);
507
 
        if (pos <= start) {
508
 
            return _encoding.size();
509
 
        }
510
 
        if ((pos == string::npos) || (pos > end)) {
511
 
            length = end - start;
512
 
        } else {
513
 
            length = pos - start - 2;
514
 
        }
515
 
        string substr = body.substr(start, length);
516
 
//      printf("FIXME: \"%s\"\n", substr.c_str());
517
 
        _connections.push_back(substr);
518
 
        if (substr == "Keep-Alive") {
519
 
            _keepalive = true;
520
 
        }
521
 
        start = pos;
522
 
    }
523
 
 
524
 
    return _connections.size();
525
 
}
526
 
 
527
 
string
528
 
HTTP::extractHost(const char *data) {
529
 
//    GNASH_REPORT_FUNCTION;
530
 
    
531
 
    string body = data;
532
 
    string::size_type start, end;
533
 
    string pattern = "Host: ";
534
 
    
535
 
    start = body.find(pattern, 0);
536
 
    if (start == string::npos) {
537
 
        return "error";
538
 
    }
539
 
    end =  body.find("\r\n", start);
540
 
    if (end == string::npos) {
541
 
        return "error";
542
 
    }
543
 
    
544
 
    _host = body.substr(start+pattern.size(), end-start-1);
545
 
    return _host;
546
 
}
547
 
 
548
 
string 
549
 
HTTP::extractAgent(const char *data) {
550
 
//    GNASH_REPORT_FUNCTION;
551
 
    
552
 
    string body = data;
553
 
    string::size_type start, end;
554
 
    string pattern = "User-Agent: ";
555
 
    
556
 
    start = body.find(pattern, 0);
557
 
    if (start == string::npos) {
558
 
        return "error";
559
 
    }
560
 
    end =  body.find("\r\n", start);
561
 
    if (end == string::npos) {
562
 
        return "error";
563
 
    }
564
 
    
565
 
    _agent = body.substr(start+pattern.size(), end-start-1);
566
 
    return _agent;
567
 
}
568
 
 
569
 
int
570
 
HTTP::extractLanguage(const char *data) {
571
 
//    GNASH_REPORT_FUNCTION;
572
 
    
573
 
    string body = data;
574
 
    string::size_type start, end, length, pos, terminate;
575
 
    // match both Accept-Language and Content-Language
576
 
    string pattern = "-Language: ";
577
 
    
578
 
    start = body.find(pattern, 0);
579
 
    if (start == string::npos) {
580
 
        return -1;
581
 
    }
582
 
    end =  body.find("\r\n", start);
583
 
    if (end == string::npos) {
584
 
        end = body.find("\n", start);
585
 
//        return "error";
586
 
    }
587
 
    length = end-start-pattern.size();
588
 
    start = start+pattern.size();
589
 
    pos = start;
590
 
    terminate = (body.find(";", start));
591
 
    if (terminate == string::npos) {
592
 
        terminate = end;
593
 
    }
594
 
    
595
 
    while (pos <= end) {
596
 
        pos = (body.find(",", start));
597
 
        if (pos <= start) {
598
 
            return _encoding.size();
599
 
        }
600
 
        if ((pos == string::npos) || (pos >= terminate)) {
601
 
            length = terminate - start;
602
 
        } else {
603
 
            length = pos - start;
604
 
        }
605
 
        string substr = body.substr(start, length);
606
 
//      printf("FIXME: \"%s\"\n", substr.c_str());
607
 
        _language.push_back(substr);
608
 
        start = pos + 1;
609
 
    }
610
 
    
611
 
//    _language = body.substr(start+pattern.size(), end-start-1);
612
 
    return _language.size();
613
 
}
614
 
 
615
 
int
616
 
HTTP::extractCharset(const char *data) {
617
 
//    GNASH_REPORT_FUNCTION;
618
 
    
619
 
    string body = data;
620
 
    string::size_type start, end, length, pos, terminate;
621
 
// match both Accept-Charset and Content-Charset
622
 
    string pattern = "-Charset: ";
623
 
    
624
 
    start = body.find(pattern, 0);
625
 
    if (start == string::npos) {
626
 
        return -1;
627
 
    }
628
 
    end =  body.find("\r\n", start);
629
 
    if (end == string::npos) {
630
 
        end = body.find("\n", start);
631
 
//        return "error";
632
 
    }
633
 
    
634
 
    length = end-start-pattern.size();
635
 
    start = start+pattern.size();
636
 
    string _connection = body.substr(start, length);
637
 
    pos = start;
638
 
    terminate = (body.find(";", start));
639
 
    if (terminate == string::npos) {
640
 
        terminate = end;
641
 
    }
642
 
    while (pos <= end) {
643
 
        pos = (body.find(",", start) + 2);
644
 
        if (pos <= start) {
645
 
            return _encoding.size();
646
 
        }
647
 
        if ((pos == string::npos) || (pos >= terminate)) {
648
 
            length = terminate - start;
649
 
        } else {
650
 
            length = pos - start - 2;
651
 
        }
652
 
        string substr = body.substr(start, length);
653
 
//      printf("FIXME: \"%s\"\n", substr.c_str());
654
 
        _charset.push_back(substr);
655
 
        start = pos;
656
 
    }
657
 
//    _charset = body.substr(start+pattern.size(), end-start-1);
658
 
    return _charset.size();
659
 
}
660
 
 
661
 
int
662
 
HTTP::extractEncoding(const char *data) {
663
 
//    GNASH_REPORT_FUNCTION;
664
 
    
665
 
    string body = data;
666
 
    string::size_type start, end, length, pos, terminate;
667
 
    // match both Accept-Encoding and Content-Encoding
668
 
    string pattern = "-Encoding: ";
669
 
    
670
 
    start = body.find(pattern, 0);
671
 
    if (start == string::npos) {
672
 
        return -1;
673
 
    }
674
 
    end =  body.find("\r\n", start);
675
 
    if (end == string::npos) {
676
 
        end = body.find("\n", start);
677
 
//        return "error";
678
 
    }
679
 
    
680
 
   length = end-start-pattern.size();
681
 
    start = start+pattern.size();
682
 
    string _connection = body.substr(start, length);
683
 
    pos = start;
684
 
    // Drop anything after a ';' character
685
 
    terminate = (body.find(";", start));
686
 
    if (terminate == string::npos) {
687
 
        terminate = end;
688
 
    }
689
 
    while (pos <= end) {
690
 
        pos = (body.find(",", start) + 2);
691
 
        if (pos <= start) {
692
 
            return _encoding.size();
693
 
        }
694
 
        if ((pos == string::npos) || (pos >= terminate)) {
695
 
            length = terminate - start;
696
 
        } else {
697
 
            length = pos - start - 2;
698
 
        }
699
 
        string substr = body.substr(start, length);
700
 
//      printf("FIXME: \"%s\"\n", substr.c_str());
701
 
        _encoding.push_back(substr);
702
 
        start = pos;
703
 
    }
704
 
 
705
 
//    _encoding = body.substr(start+pattern.size(), end-start-1);
706
 
    return _encoding.size();
707
 
}
708
 
 
709
 
int
710
 
HTTP::extractTE(const char *data) {
711
 
//    GNASH_REPORT_FUNCTION;
712
 
    
713
 
    string body = data;
714
 
    string::size_type start, end, length, pos;
715
 
    string pattern = "TE: ";
716
 
    
717
 
    start = body.find(pattern, 0);
718
 
    if (start == string::npos) {
719
 
        return -1;
720
 
    }
721
 
    end = body.find("\r\n", start);
722
 
    if (end == string::npos) {
723
 
        end = body.find("\n", start);
724
 
//        return "error";
725
 
    }
726
 
    
727
 
    length = end-start-pattern.size();
728
 
    start = start+pattern.size();
729
 
    pos = start;
730
 
    while (pos <= end) {
731
 
        pos = (body.find(",", start));
732
 
        if (pos <= start) {
733
 
            return _encoding.size();
734
 
        }
735
 
        if ((pos == string::npos) || (pos >= end)) {
736
 
            length = end - start;
737
 
        } else {
738
 
            length = pos - start;
739
 
        }
740
 
        string substr = body.substr(start, length);
741
 
//      printf("FIXME: \"%s\"\n", substr.c_str());
742
 
        _te.push_back(substr);
743
 
        start = pos + 2;
744
 
    }
745
 
    return _te.size();
746
 
}
747
 
 
748
 
// Get the file type, so we know how to set the
749
 
// Content-type in the header.
750
 
HTTP::filetype_e
751
 
HTTP::getFileStats(std::string &filespec)
752
 
{
753
 
    GNASH_REPORT_FUNCTION;    
754
 
    bool try_again = true;
755
 
    string actual_filespec = filespec;
756
 
    struct stat st;
757
 
 
758
 
    while (try_again) {
759
 
        try_again = false;
760
 
//      cerr << "Trying to open " << actual_filespec << endl;
761
 
        if (stat(actual_filespec.c_str(), &st) == 0) {
762
 
            // If it's a directory, then we emulate what apache
763
 
            // does, which is to load the index.html file in that
764
 
            // directry if it exists.
765
 
            if (S_ISDIR(st.st_mode)) {
766
 
                log_debug("%s is a directory\n", actual_filespec.c_str());
767
 
                if (actual_filespec[actual_filespec.size()-1] != '/') {
768
 
                    actual_filespec += '/';
769
 
                }
770
 
                actual_filespec += "index.html";
771
 
                try_again = true;
772
 
                continue;
773
 
            } else {            // not a directory
774
 
                log_debug("%s is not a directory\n", actual_filespec.c_str());
775
 
                string::size_type pos;
776
 
                pos = filespec.rfind(".");
777
 
                if (pos != string::npos) {
778
 
                    string suffix = filespec.substr(pos, filespec.size());
779
 
                    if (suffix == "html") {
780
 
                        _filetype = HTML;
781
 
                        log_debug("HTML content found");
782
 
                    }
783
 
                    if (suffix == "swf") {
784
 
                        _filetype = SWF;
785
 
                        log_debug("SWF content found");
786
 
                    }
787
 
                    if (suffix == "flv") {
788
 
                        _filetype = VIDEO;
789
 
                        log_debug("FLV content found");
790
 
                    }
791
 
                    if (suffix == "mp3") {
792
 
                        _filetype = AUDIO;
793
 
                        log_debug("MP3 content found");
794
 
                    }
795
 
                }
796
 
            }
797
 
        } else {
798
 
            _filetype = HTTP::ERROR;
799
 
        } // end of stat()
800
 
    } // end of try_waiting
801
 
 
802
 
    _filesize = st.st_size;
803
 
    return _filetype;
804
 
}
805
 
 
806
 
void
807
 
HTTP::dump() {
808
 
    GNASH_REPORT_FUNCTION;
809
 
    
810
 
    boost::mutex::scoped_lock lock(stl_mutex);
811
 
    vector<string>::iterator it;
812
 
    
813
 
    log_debug (_("==== The HTTP header breaks down as follows: ===="));
814
 
    log_debug (_("Filespec: %s"), _filespec.c_str());
815
 
    log_debug (_("URL: %s"), _url.c_str());
816
 
    log_debug (_("Version: %s"), _version.c_str());
817
 
    for (it = _accept.begin(); it != _accept.end(); it++) {
818
 
        log_debug("Accept param: \"%s\"", (*(it)).c_str());
819
 
    }
820
 
    log_debug (_("Method: %s"), _method.c_str());
821
 
    log_debug (_("Referer: %s"), _referer.c_str());
822
 
    log_debug (_("Connections:"));
823
 
    for (it = _connections.begin(); it != _connections.end(); it++) {
824
 
        log_debug("Connection param is: \"%s\"", (*(it)).c_str());
825
 
    }
826
 
    log_debug (_("Host: %s"), _host.c_str());
827
 
    log_debug (_("User Agent: %s"), _agent.c_str());
828
 
    for (it = _language.begin(); it != _language.end(); it++) {
829
 
        log_debug("Language param: \"%s\"", (*(it)).c_str());
830
 
    }
831
 
    for (it = _charset.begin(); it != _charset.end(); it++) {
832
 
        log_debug("Charset param: \"%s\"", (*(it)).c_str());
833
 
    }
834
 
    for (it = _encoding.begin(); it != _encoding.end(); it++) {
835
 
        log_debug("Encodings param: \"%s\"", (*(it)).c_str());
836
 
    }
837
 
    for (it = _te.begin(); it != _te.end(); it++) {
838
 
        log_debug("TE param: \"%s\"", (*(it)).c_str());
839
 
    }
840
 
    log_debug (_("==== ==== ===="));
841
 
}
842
 
 
843
 
} // end of cygnal namespace
844
 
 
845
 
 
846
 
// local Variables:
847
 
// mode: C++
848
 
// indent-tabs-mode: t
849
 
// End: