Server 0.0.1
HTTP/REST server implementation

src/http/writer/write.c

Go to the documentation of this file.
00001 
00023 #include <unistd.h>
00024 #include <sys/stat.h>
00025 
00026 #include "class.h"
00027 #include "http/message.h"
00028 #include "http/writer.h"
00029 #include "cbuf.h"
00030 #include "stream.h"
00031 
00032 #include "commons.h"
00033 
00034 
00035 ssize_t
00036 httpWriterWrite(void * _this, Stream st)
00037 {
00038         HttpWriter       this    = _this;
00039         HttpMessageQueue respq   = this->queue;
00040         int              cont    = 1;
00041 
00042         if (cbufIsLocked(this->buffer)) {
00043                 if (FALSE == this->ourLock)
00044                         return 0;
00045         }
00046         else {
00047                 cbufLock(this->buffer);
00048                 this->ourLock = TRUE;
00049         }
00050 
00051         while (cont) {
00052                 switch (this->state) {
00053                         case HTTP_WRITER_GET:
00054                                 if (NULL == this->current && 0 < respq->nmsgs) {
00055                                         this->current = respq->msgs[0];
00056 
00057                                         this->written = 0;
00058                                         this->nbody   = 0;
00059                                         this->nheader = httpMessageHeaderSizeGet(this->current);
00060 
00061                                         httpMessageHeaderToString(
00062                                                         this->current,
00063                                                         cbufGetWrite(this->buffer));
00064                                         cbufIncWrite(this->buffer, this->nheader);
00065 
00066                                         this->state = HTTP_WRITER_WRITE;
00067                                 }
00068                                 else {
00069                                         cbufRelease(this->buffer);
00070                                         this->ourLock = FALSE;
00071                                         cont          = 0;
00072                                 }
00073                                 break;
00074 
00075                         case HTTP_WRITER_WRITE:
00079                                 if (this->nbody < this->current->nbody) {
00080                                         size_t size = MIN(
00081                                                         this->current->nbody - this->nbody,
00082                                                         cbufGetFree(this->buffer));
00083 
00084                                         switch (this->current->type) {
00085                                                 case HTTP_MESSAGE_BUFFERED:
00086                                                         cbufSetData(this->buffer,
00087                                                                         this->current->body + this->nbody,
00088                                                                         size);
00089                                                         break;
00090 
00091                                                 case HTTP_MESSAGE_PIPED:
00092                                                         size = cbufRead(this->buffer, this->current->handle);
00093                                                         break;
00094 
00095                                                 default:
00096                                                         return -1;
00097                                         }
00098 
00099                                         this->nbody += size;
00100                                 }
00101 
00105                                 {
00106                                         ssize_t written = cbufWrite(this->buffer, st);
00107 
00108                                         if (0 <= written) {
00109                                                 this->written += written;
00110                                         }
00111                                         else {
00112                                                 return -1;
00113                                         }
00114                                 }
00115 
00116                                 if (this->written == this->current->nbody + this->nheader) {
00117                                         this->state = HTTP_WRITER_DONE;
00118                                 }
00119                                 else {
00120                                         cont = 0;
00121                                 }
00122                                 break;
00123 
00124                         case HTTP_WRITER_DONE:
00125                                 this->state   = HTTP_WRITER_GET;
00126 
00127                                 memmove(respq->msgs,
00128                                                 &(respq->msgs[1]),
00129                                                 sizeof(void*) * (--respq->nmsgs + 1));
00130 
00131                                 cbufRelease(this->buffer);
00132                                 this->ourLock = FALSE;
00133 
00134                                 if (! httpMessageHasKeepAlive(this->current)) {
00142                                         delete(this->current);
00143                                         return -1;
00144                                 }
00145 
00146                                 delete(this->current);
00147                                 break;
00148                 }
00149         }
00150 
00151         return respq->nmsgs;
00152 }
00153 
00154 // vim: set ts=4 sw=4:
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines