~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbms/src/cslib/CSHTTPStream.cc

  • Committer: Mark Atwood
  • Date: 2011-12-20 02:32:53 UTC
  • mfrom: (2469.1.1 drizzle-build)
  • Revision ID: me@mark.atwood.name-20111220023253-bvu0kr14kwsdvz7g
mergeĀ lp:~brianaker/drizzle/deprecate-pbms

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
2
 
 *
3
 
 * PrimeBase Media Stream for MySQL
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 2 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
 
 * Original author: Paul McCullagh (H&G2JCtL)
20
 
 * Continued development: Barry Leslie
21
 
 *
22
 
 * 2007-06-10
23
 
 *
24
 
 * A basic syncronized object.
25
 
 *
26
 
 */
27
 
#include "CSConfig.h"
28
 
 
29
 
#include <stdlib.h>
30
 
#include <string.h>
31
 
#include <inttypes.h>
32
 
 
33
 
#include "CSGlobal.h"
34
 
#include "CSHTTPStream.h"
35
 
#include "CSLog.h"
36
 
 
37
 
#ifdef DEBUG
38
 
//#define PRINT_HEADER
39
 
#endif
40
 
 
41
 
/*
42
 
 * ---------------------------------------------------------------
43
 
 * HTTP HEADERS
44
 
 */
45
 
 
46
 
CSHeader::~CSHeader()
47
 
{
48
 
        if (iName) {
49
 
                iName->release();
50
 
                iName = NULL;
51
 
        }
52
 
        if (iValue) {
53
 
                iValue->release();
54
 
                iValue = NULL;
55
 
        }
56
 
}
57
 
 
58
 
void CSHeader::setName(const char *name)
59
 
{
60
 
        iName = CSString::newString(name);
61
 
}
62
 
 
63
 
void CSHeader::setName(const char *name, uint32_t len)
64
 
{
65
 
        iName = CSString::newString(name, len);
66
 
}
67
 
 
68
 
void CSHeader::setName(CSString *name)
69
 
{
70
 
        iName = name;
71
 
}
72
 
 
73
 
void CSHeader::setValue(const char *value)
74
 
{
75
 
        iValue = CSString::newString(value);
76
 
}
77
 
 
78
 
void CSHeader::setValue(const char *value, uint32_t len)
79
 
{
80
 
        iValue = CSString::newString(value, len);
81
 
}
82
 
 
83
 
void CSHeader::setValue(CSString *value)
84
 
{
85
 
        iValue = value;
86
 
}
87
 
 
88
 
void CSHeader::write(CSOutputStream *out, bool trace)
89
 
{
90
 
        if (trace)
91
 
                printf("%s: %s\n", iName->getCString(), iValue->getCString());
92
 
 
93
 
        out->print(iName);
94
 
        out->print(": ");
95
 
        if (iValue)
96
 
                out->print(iValue);
97
 
        out->print("\r\n");
98
 
}
99
 
 
100
 
void CSHTTPHeaders::clearHeaders()
101
 
{
102
 
        iKeepAlive = false;
103
 
        iExpect100Continue = false;
104
 
        iUnknownEpectHeader = false;
105
 
        if (iHeaders) {
106
 
                iHeaders->release();
107
 
                iHeaders = NULL;
108
 
        }
109
 
}
110
 
CSVector *CSHTTPHeaders::takeHeaders()
111
 
{
112
 
        CSVector *headers = iHeaders;
113
 
        iHeaders = NULL;
114
 
        return headers;
115
 
}
116
 
 
117
 
void CSHTTPHeaders::setHeaders(CSVector *headers)
118
 
{
119
 
        if (iHeaders) 
120
 
                iHeaders->release();
121
 
        iHeaders = headers;
122
 
}
123
 
 
124
 
void CSHTTPHeaders::addHeader(CSHeader *h)
125
 
{
126
 
        if (!iHeaders)
127
 
                new_(iHeaders, CSVector(5));
128
 
 
129
 
        if (strcasecmp(h->getNameCString(), "Connection") == 0 && strcasecmp(h->getValueCString(), "Keep-Alive") == 0)
130
 
                iKeepAlive = true;
131
 
                
132
 
        if (strcasecmp(h->getNameCString(), "Expect") == 0) {
133
 
                if (strcasecmp(h->getValueCString(), "100-continue") == 0)
134
 
                        iExpect100Continue = true;
135
 
                else
136
 
                        iUnknownEpectHeader = true;
137
 
        }
138
 
                
139
 
        iHeaders->add(h);
140
 
}
141
 
 
142
 
void CSHTTPHeaders::addHeaders(CSHTTPHeaders *headers)
143
 
{
144
 
        CSHeader *h;
145
 
        uint32_t i =0;
146
 
        while ((h = headers->getHeader(i++))) {
147
 
                addHeader(h);
148
 
        }
149
 
}
150
 
 
151
 
void CSHTTPHeaders::addHeader(const char *name, const char *value)
152
 
{
153
 
        CSHeader *h;
154
 
 
155
 
        enter_();
156
 
        if (!iHeaders)
157
 
                new_(iHeaders, CSVector(5));
158
 
 
159
 
        new_(h, CSHeader());
160
 
        push_(h);
161
 
        h->setName(name);
162
 
        h->setValue(value);
163
 
        pop_(h);
164
 
 
165
 
        addHeader(h);
166
 
        exit_();
167
 
}
168
 
 
169
 
void CSHTTPHeaders::addHeader(const char *name, uint32_t nlen, const char *value, uint32_t vlen)
170
 
{
171
 
        CSHeader *h;
172
 
 
173
 
        enter_();
174
 
        if (!iHeaders)
175
 
                new_(iHeaders, CSVector(5));
176
 
 
177
 
        new_(h, CSHeader());
178
 
        push_(h);
179
 
        h->setName(name, nlen);
180
 
        h->setValue(value, vlen);
181
 
        pop_(h);
182
 
        addHeader(h);
183
 
        exit_();
184
 
}
185
 
 
186
 
void CSHTTPHeaders::addHeader(CSString *name, CSString *value)
187
 
{
188
 
        CSHeader *h;
189
 
 
190
 
        enter_();
191
 
        push_(name);
192
 
        push_(value);
193
 
        if (!iHeaders)
194
 
                new_(iHeaders, CSVector(5));
195
 
 
196
 
        new_(h, CSHeader());
197
 
        pop_(value);
198
 
        pop_(name);
199
 
        h->setName(name);
200
 
        h->setValue(value);
201
 
        addHeader(h);
202
 
        exit_();
203
 
}
204
 
 
205
 
void CSHTTPHeaders::addHeader(const char *name, CSString *value)
206
 
{
207
 
        CSHeader *h;
208
 
        CSString *n;
209
 
 
210
 
        enter_();
211
 
        push_(value);
212
 
        n = CSString::newString(name);
213
 
        push_(n);
214
 
        if (!iHeaders)
215
 
                new_(iHeaders, CSVector(5));
216
 
        new_(h, CSHeader());
217
 
        pop_(n);
218
 
        pop_(value);
219
 
        h->setName(n);
220
 
        h->setValue(value);
221
 
        addHeader(h);
222
 
        exit_();
223
 
}
224
 
 
225
 
void CSHTTPHeaders::addHeader(const char *name, uint64_t value)
226
 
{
227
 
        char buffer[30];
228
 
 
229
 
        snprintf(buffer, 30, "%"PRIu64, value);
230
 
        addHeader(name, buffer);
231
 
}
232
 
 
233
 
void CSHTTPHeaders::removeHeader(CSString *name)
234
 
{
235
 
        enter_();
236
 
        push_(name);
237
 
        if (iHeaders) {
238
 
                CSHeader *h;
239
 
 
240
 
                for (uint32_t i=0; i<iHeaders->size(); ) {
241
 
                        h = (CSHeader *) iHeaders->get(i);
242
 
                        if (h->getName()->compare(name) == 0) {
243
 
                                iHeaders->remove(i);
244
 
                        } else 
245
 
                                i++;
246
 
                }
247
 
        }
248
 
        release_(name);
249
 
        
250
 
        exit_();
251
 
}
252
 
 
253
 
void CSHTTPHeaders::removeHeader(const char *name)
254
 
{
255
 
        removeHeader(CSString::newString(name));
256
 
}
257
 
 
258
 
CSString *CSHTTPHeaders::getHeaderValue(const char *name)
259
 
{
260
 
        CSString *v;
261
 
 
262
 
        v = NULL;
263
 
        if (iHeaders) {
264
 
                CSHeader *h;
265
 
 
266
 
                for (uint32_t i=0; i<iHeaders->size(); i++) {
267
 
                        h = (CSHeader *) iHeaders->get(i);
268
 
                        if (h->getName()->compare(name) == 0) {
269
 
                                v = h->getValue();
270
 
                                v->retain();
271
 
                                break;
272
 
                        }
273
 
                }
274
 
        }
275
 
        return v;
276
 
}
277
 
 
278
 
const char *CSHTTPHeaders::getHeaderCStringValue(const char *name)
279
 
{
280
 
        if (iHeaders) {
281
 
                CSHeader *h;
282
 
 
283
 
                for (uint32_t i=0; i<iHeaders->size(); i++) {
284
 
                        h = (CSHeader *) iHeaders->get(i);
285
 
                        if (h->getName()->compare(name) == 0) {
286
 
                                return h->getValue()->getCString();
287
 
                        }
288
 
                }
289
 
        }
290
 
        return NULL;
291
 
}
292
 
 
293
 
void CSHTTPHeaders::writeHeader(CSOutputStream *out, bool trace)
294
 
{
295
 
        if (iHeaders) {
296
 
                CSHeader *h;
297
 
 
298
 
                for (uint32_t i=0; i<iHeaders->size(); i++) {
299
 
                        h = (CSHeader *) iHeaders->get(i);
300
 
                        h->write(out, trace);
301
 
                }
302
 
        }
303
 
}
304
 
 
305
 
bool CSHTTPHeaders::keepAlive()
306
 
{
307
 
        return iKeepAlive;
308
 
}
309
 
 
310
 
bool CSHTTPHeaders::expect100Continue()
311
 
{
312
 
        return iExpect100Continue;
313
 
}
314
 
 
315
 
bool CSHTTPHeaders::unknownEpectHeader()
316
 
{
317
 
        return iUnknownEpectHeader;
318
 
}
319
 
 
320
 
/*
321
 
 * ---------------------------------------------------------------
322
 
 * HTTP INPUT STREAMS
323
 
 */
324
 
 
325
 
CSHTTPInputStream::CSHTTPInputStream(CSInputStream* in):
326
 
CSHTTPHeaders(),
327
 
iInput(NULL),
328
 
iMethod(NULL),
329
 
iRequestURI(NULL),
330
 
iHTTPVersion(NULL),
331
 
iStatusPhrase(NULL)
332
 
{
333
 
        iInput = in;
334
 
}
335
 
 
336
 
CSHTTPInputStream::~CSHTTPInputStream()
337
 
{
338
 
        freeHead();
339
 
        if (iInput)
340
 
                iInput->release();
341
 
}
342
 
 
343
 
void CSHTTPInputStream::readHead(bool trace)
344
 
{
345
 
        CSStringBuffer  *sb = NULL;
346
 
        bool                    first_line = true;
347
 
        uint32_t                        start, end;
348
 
 
349
 
        enter_();
350
 
        freeHead();
351
 
        for (;;) {
352
 
                sb = iInput->readLine();
353
 
                if (!sb)
354
 
                        break;
355
 
                if (trace) {
356
 
                        if (first_line)
357
 
                                CSL.log(self, CSLog::Protocol, "HTTP Request - Header:\n");
358
 
                        printf("%s\n", sb->getCString());
359
 
                }
360
 
                if (sb->length() == 0) {
361
 
                        sb->release();
362
 
                        break;
363
 
                }
364
 
                push_(sb);
365
 
                
366
 
                if (first_line) {
367
 
                        CSString *str;
368
 
                        start = sb->ignore(0, ' ');
369
 
                        end = sb->find(start, ' ');
370
 
                        str = sb->substr(start, end - start);
371
 
                        if (str->startsWith("HTTP")) { // Reply header
372
 
                                iMethod = NULL;
373
 
                                iRequestURI = NULL;
374
 
                                iHTTPVersion = str;
375
 
                                start = sb->ignore(end, ' ');
376
 
                                end = sb->find(start, ' ');
377
 
                                if (start > end)
378
 
                                        CSException::throwException(CS_CONTEXT, CS_ERR_BAD_HTTP_HEADER, "Bad HTTP header");
379
 
 
380
 
                                str = sb->substr(start, end - start);
381
 
                                iStatus = atol(str->getCString());
382
 
                                str->release();
383
 
                                start = sb->ignore(end, ' ');
384
 
                                end = sb->find(start, '\r');
385
 
                                if (start > end)
386
 
                                        CSException::throwException(CS_CONTEXT, CS_ERR_BAD_HTTP_HEADER, "Bad HTTP header");
387
 
                                iStatusPhrase = sb->substr(start, end - start);
388
 
                        } else {
389
 
                                iStatus = 0;
390
 
                                iStatusPhrase = NULL;
391
 
                                iMethod = str;
392
 
                        start = sb->ignore(end, ' ');
393
 
                        end = sb->find(start, ' ');
394
 
                        if (start > end)
395
 
                                CSException::throwException(CS_CONTEXT, CS_ERR_BAD_HTTP_HEADER, "Bad HTTP header");
396
 
                        iRequestURI = sb->substr(start, end - start);
397
 
                        start = sb->ignore(end, ' ');
398
 
                        end = sb->find(start, ' ');
399
 
                        if (start > end)
400
 
                                CSException::throwException(CS_CONTEXT, CS_ERR_BAD_HTTP_HEADER, "Bad HTTP header");
401
 
                        iHTTPVersion = sb->substr(start, end - start);
402
 
                        }                               
403
 
                        first_line = false;
404
 
                }
405
 
                else {
406
 
                        uint32_t nstart, nend;
407
 
                        uint32_t vstart, vend;
408
 
 
409
 
                        nstart = sb->ignore(0, ' ');
410
 
                        nend = sb->find(nstart, ':');
411
 
 
412
 
                        vstart = sb->ignore(nend+1, ' ');
413
 
                        vend = sb->find(vstart, '\r');
414
 
 
415
 
                        nend = sb->trim(nend, ' ');
416
 
                        vend = sb->trim(vend, ' ');
417
 
                        
418
 
                        if (vstart > vend)
419
 
                                CSException::throwException(CS_CONTEXT, CS_ERR_BAD_HTTP_HEADER, "Bad HTTP header");
420
 
                        addHeader(sb->getBuffer(nstart), nend-nstart, sb->getBuffer(vstart), vend-vstart);
421
 
                }
422
 
 
423
 
                release_(sb);
424
 
        }
425
 
        exit_();
426
 
}
427
 
 
428
 
void CSHTTPInputStream::readBody()
429
 
{
430
 
        uint64_t        body_size;
431
 
        size_t  tfer, len;
432
 
 
433
 
        if (getContentLength(&body_size)) {
434
 
                iBody.setLength((size_t) body_size);
435
 
                len = 0;
436
 
                while (len < body_size) {
437
 
                        tfer =  read(iBody.getBuffer(len), (size_t)(body_size - len));
438
 
                        if (!tfer)
439
 
                                CSException::throwException(CS_CONTEXT, CS_ERR_BODY_INCOMPLETE, "POST data incomplete");
440
 
                        len += tfer;
441
 
                }
442
 
        }
443
 
        else {
444
 
                CSStringBuffer *sb = NULL;
445
 
 
446
 
                /* Read until we have an empty line. */
447
 
                for (;;) {
448
 
                        sb = readLine();
449
 
                        if (!sb)
450
 
                                break;
451
 
                        if (sb->length() == 0) {
452
 
                                sb->release();
453
 
                                break;
454
 
                        }
455
 
                        iBody.append(sb->getBuffer(0), sb->length());
456
 
                        iBody.append((char) '\n');
457
 
                        sb->release();
458
 
                }
459
 
        }
460
 
}
461
 
 
462
 
bool CSHTTPInputStream::getRange(uint64_t *size, uint64_t *offset)
463
 
{
464
 
        CSString        *val;
465
 
        bool haveRange = false;
466
 
 
467
 
        if ((val = getHeaderValue("Range"))) {
468
 
                uint64_t                first_byte = 0, last_byte = 0;
469
 
                const char      *range = val->getCString();
470
 
                
471
 
                if (range && (val->compare("bytes=", 6) == 0)) {
472
 
                        if ((sscanf(range + 6, "%"PRIu64"-%"PRIu64"", &first_byte, &last_byte) == 2) && (last_byte >= first_byte)) {
473
 
                                *offset = (uint64_t) first_byte;
474
 
                                *size =last_byte - first_byte + 1;
475
 
                                haveRange = true;
476
 
                        }       
477
 
                }
478
 
                val->release();
479
 
                                
480
 
        }
481
 
        return haveRange;
482
 
}
483
 
 
484
 
bool CSHTTPInputStream::getContentLength(uint64_t *length)
485
 
{
486
 
        CSString        *val;
487
 
        uint64_t                size = 0;
488
 
 
489
 
        if ((val = getHeaderValue("Content-Length"))) {
490
 
                const char      *len = val->getCString();
491
 
 
492
 
                if (len)  
493
 
                        sscanf(len, "%"PRIu64"", &size);                
494
 
                val->release();
495
 
                *length = size;
496
 
                return true;
497
 
        }
498
 
        return false;
499
 
}
500
 
 
501
 
const char *CSHTTPInputStream::getMethod()
502
 
{
503
 
        if (!iMethod)
504
 
                return NULL;
505
 
        return iMethod->getCString();
506
 
}
507
 
 
508
 
void CSHTTPInputStream::close()
509
 
{
510
 
        enter_();
511
 
        iInput->close();
512
 
        exit_();
513
 
}
514
 
 
515
 
size_t CSHTTPInputStream::read(char *b, size_t len)
516
 
{
517
 
        enter_();
518
 
        return_(iInput->read(b, len));
519
 
}
520
 
 
521
 
int CSHTTPInputStream::read()
522
 
{
523
 
        enter_();
524
 
        return_(iInput->read());
525
 
}
526
 
 
527
 
int CSHTTPInputStream::peek()
528
 
{
529
 
        enter_();
530
 
        return_(iInput->peek());
531
 
}
532
 
 
533
 
void CSHTTPInputStream::freeHead()
534
 
{
535
 
        enter_();
536
 
        clearHeaders();
537
 
        if (iMethod) {
538
 
                iMethod->release();
539
 
                iMethod = NULL;
540
 
        }
541
 
        if (iRequestURI) {
542
 
                iRequestURI->release();
543
 
                iRequestURI = NULL;
544
 
        }
545
 
        if (iHTTPVersion) {
546
 
                iHTTPVersion->release();
547
 
                iHTTPVersion = NULL;
548
 
        }
549
 
        if (iStatusPhrase) {
550
 
                iStatusPhrase->release();
551
 
                iStatusPhrase = NULL;
552
 
        }
553
 
        iStatus = 0;
554
 
        exit_();
555
 
}
556
 
 
557
 
CSHTTPInputStream *CSHTTPInputStream::newStream(CSInputStream* i)
558
 
{
559
 
        CSHTTPInputStream *s;
560
 
 
561
 
        if (!(s = new CSHTTPInputStream(i))) {
562
 
                i->release();
563
 
                CSException::throwOSError(CS_CONTEXT, ENOMEM);
564
 
        }
565
 
        return s;
566
 
}
567
 
 
568
 
/*
569
 
 * ---------------------------------------------------------------
570
 
 * HTTP OUTPUT STREAMS
571
 
 */
572
 
 
573
 
CSHTTPOutputStream::CSHTTPOutputStream(CSOutputStream* out):
574
 
CSHTTPHeaders(),
575
 
iOutput(NULL),
576
 
iStatus(0),
577
 
iContentLength(0),
578
 
iRangeSize(0),
579
 
iRangeOffset(0),
580
 
iTotalLength(0)
581
 
{
582
 
        iOutput = out;
583
 
        iBody.setGrowSize(120);
584
 
}
585
 
 
586
 
CSHTTPOutputStream::~CSHTTPOutputStream()
587
 
{
588
 
        clearHeaders();
589
 
        clearBody();
590
 
        if (iOutput)
591
 
                iOutput->release();
592
 
}
593
 
 
594
 
void CSHTTPOutputStream::print(const char *str, bool trace)
595
 
{
596
 
        if (trace)
597
 
                printf("%s", str);
598
 
        iOutput->print(str);
599
 
}
600
 
 
601
 
 
602
 
void CSHTTPOutputStream::print(int32_t value, bool trace)
603
 
{
604
 
        if (trace)
605
 
                printf("%d", value);
606
 
        iOutput->print(value);
607
 
}
608
 
 
609
 
void CSHTTPOutputStream::print(uint64_t value, bool trace)
610
 
{
611
 
        if (trace)
612
 
                printf("%"PRIu64, value);
613
 
        iOutput->print(value);
614
 
}
615
 
 
616
 
void CSHTTPOutputStream::writeHeaders(bool trace)
617
 
{
618
 
        writeHeader(this, trace);
619
 
        clearHeaders();
620
 
}
621
 
 
622
 
void CSHTTPOutputStream::writeHead(bool trace)
623
 
{
624
 
        enter_();
625
 
        if (trace)
626
 
                CSL.log(self, CSLog::Protocol, "HTTP Reply - Header:\n");
627
 
        print("HTTP/1.1 ", trace);
628
 
        print(iStatus, trace);
629
 
        print(" ", trace);
630
 
        print(getReasonPhrase(iStatus), trace);
631
 
        print("\r\n", trace);
632
 
        writeHeader(iOutput, trace);
633
 
        print("Content-Length: ", trace);
634
 
        print(iContentLength, trace);
635
 
        print("\r\n", trace);
636
 
        if (iRangeSize && (iStatus == 200)) {
637
 
                print("Content-Range: bytes ", trace);
638
 
                print(iRangeOffset, trace);
639
 
                print("-", trace);
640
 
                print(iRangeOffset + iRangeSize -1, trace);
641
 
                print("/", trace);
642
 
                print(iTotalLength, trace);
643
 
                print("\r\n", trace);
644
 
        }
645
 
        print("\r\n", trace);
646
 
        exit_();
647
 
 
648
 
}
649
 
 
650
 
void CSHTTPOutputStream::clearBody()
651
 
{
652
 
        iRangeSize = 0;
653
 
        iRangeOffset = 0;
654
 
        iTotalLength = 0;
655
 
        iContentLength = 0;
656
 
        iBody.clear();
657
 
}
658
 
 
659
 
void CSHTTPOutputStream::writeBody()
660
 
{
661
 
        iOutput->write(iBody.getBuffer(0), iBody.length());
662
 
}
663
 
 
664
 
void CSHTTPOutputStream::appendBody(const char *str)
665
 
{
666
 
        iBody.append(str);
667
 
        iContentLength = iBody.length();
668
 
}
669
 
 
670
 
void CSHTTPOutputStream::appendBody(int32_t value)
671
 
{
672
 
        iBody.append(value);
673
 
        iContentLength = iBody.length();
674
 
}
675
 
 
676
 
void CSHTTPOutputStream::appendBody(uint32_t value)
677
 
{
678
 
        iBody.append(value);
679
 
        iContentLength = iBody.length();
680
 
}
681
 
 
682
 
void CSHTTPOutputStream::appendBody(uint64_t value)
683
 
{
684
 
        iBody.append(value);
685
 
        iContentLength = iBody.length();
686
 
}
687
 
 
688
 
const char *CSHTTPOutputStream::getBodyData()
689
 
{
690
 
        return iBody.getCString(); 
691
 
}
692
 
 
693
 
size_t CSHTTPOutputStream::getBodyLength()
694
 
{
695
 
        return iBody.length();
696
 
}
697
 
 
698
 
void CSHTTPOutputStream::setBody(CSStringBufferImpl *buf)
699
 
{
700
 
        iBody.take(buf);
701
 
        iContentLength = iBody.length(); 
702
 
}
703
 
 
704
 
void CSHTTPOutputStream::close()
705
 
{
706
 
        enter_();
707
 
        iOutput->close();
708
 
        exit_();
709
 
}
710
 
 
711
 
void CSHTTPOutputStream::write(const char *b, size_t len)
712
 
{
713
 
        enter_();
714
 
        iOutput->write(b, len);
715
 
        exit_();
716
 
}
717
 
 
718
 
void CSHTTPOutputStream::flush()
719
 
{
720
 
        enter_();
721
 
        iOutput->flush();
722
 
        exit_();
723
 
}
724
 
 
725
 
void CSHTTPOutputStream::write(char b)
726
 
{
727
 
        enter_();
728
 
        iOutput->write(b);
729
 
        exit_();
730
 
}
731
 
 
732
 
const char *CSHTTPOutputStream::getReasonPhrase(int code)
733
 
{
734
 
        const char *message = "Unknown Code";
735
 
 
736
 
        switch (code) {
737
 
                case 100: message = "Continue"; break;
738
 
                case 101: message = "Switching Protocols"; break;
739
 
                case 200: message = "OK"; break;
740
 
                case 201: message = "Created"; break;
741
 
                case 202: message = "Accepted"; break;
742
 
                case 203: message = "Non-Authoritative Information"; break;
743
 
                case 204: message = "No Content"; break;
744
 
                case 205: message = "Reset Content"; break;
745
 
                case 206: message = "Partial Content"; break;
746
 
                case 300: message = "Multiple Choices"; break;
747
 
                case 301: message = "Moved Permanently"; break;
748
 
                case 302: message = "Found"; break;
749
 
                case 303: message = "See Other"; break;
750
 
                case 304: message = "Not Modified"; break;
751
 
                case 305: message = "Use Proxy"; break;
752
 
                case 307: message = "Temporary Redirect"; break;
753
 
                case 400: message = "Bad Request"; break;
754
 
                case 401: message = "Unauthorized"; break;
755
 
                case 402: message = "Payment Required"; break;
756
 
                case 403: message = "Forbidden"; break;
757
 
                case 404: message = "Not Found"; break;
758
 
                case 405: message = "Method Not Allowed"; break;
759
 
                case 406: message = "Not Acceptable"; break;
760
 
                case 407: message = "Proxy Authentication Required"; break;
761
 
                case 408: message = "Request Time-out"; break;
762
 
                case 409: message = "Conflict"; break;
763
 
                case 410: message = "Gone"; break;
764
 
                case 411: message = "Length Required"; break;
765
 
                case 412: message = "Precondition Failed"; break;
766
 
                case 413: message = "Request Entity Too Large"; break;
767
 
                case 414: message = "Request-URI Too Large"; break;
768
 
                case 415: message = "Unsupported Media Type"; break;
769
 
                case 416: message = "Requested range not satisfiable"; break;
770
 
                case 417: message = "Expectation Failed"; break;
771
 
                case 500: message = "Internal Server Error"; break;
772
 
                case 501: message = "Not Implemented"; break;
773
 
                case 502: message = "Bad Gateway"; break;
774
 
                case 503: message = "Service Unavailable"; break;
775
 
                case 504: message = "Gateway Time-out"; break;
776
 
                case 505: message = "HTTP Version not supported"; break;
777
 
        }
778
 
        return message;
779
 
}
780
 
 
781
 
CSHTTPOutputStream *CSHTTPOutputStream::newStream(CSOutputStream* i)
782
 
{
783
 
        CSHTTPOutputStream *s;
784
 
 
785
 
        if (!(s = new CSHTTPOutputStream(i))) {
786
 
                i->release();
787
 
                CSException::throwOSError(CS_CONTEXT, ENOMEM);
788
 
        }
789
 
        return s;
790
 
}
791
 
 
792