|
Server 0.0.1
HTTP/REST server implementation
|
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: