write.c 1.72 KB
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

#include "class.h"
#include "interface/class.h"
#include "http/response.h"
#include "http/response/writer.h"

size_t
httpResponseWriterWrite(HttpResponseWriter this, int fd)
{
	HttpMessageQueue respq   = this->response_queue;
	int              cont    = 1;
	size_t           written = 0;

	while (cont) {
		switch (this->state) {
			case HTTP_RESPONSE_NO:
				if (NULL == this->cur_response && 0 < respq->nmsgs) {
					this->cur_response = (HttpResponse)respq->msgs[0];
					memmove(respq->msgs, &(respq->msgs[1]), --respq->nmsgs);
					this->state = HTTP_RESPONSE_START;
				}
				else {
					cont = 0;
				}
				break;

			case HTTP_RESPONSE_START:
				if (NULL == this->buffer) {
					this->nbuffer = httpResponseSizeGet(this->cur_response);
					this->buffer  = calloc(1, this->nbuffer);
					httpResponseToString(this->cur_response, this->buffer);
				}
				{
					written = write(fd, this->buffer, this->nbuffer);

					if (-1 == written) {
						free (this->buffer);
						this->buffer = NULL;
						return written;
					}

					if (written == this->nbuffer) {
						if (HTTP_MESSAGE_BUFFERED ==
								((HttpMessage)(this->cur_response))->type) {
							this->state = HTTP_RESPONSE_DONE;
						}
						else {
							this->state = HTTP_RESPONSE_PIPE;
						}
					}
					else {
						this->nbuffer -= written;
						memmove(this->buffer, this->buffer + written, this->nbuffer);
						cont = 0;
					}
				}
				break;

			case HTTP_RESPONSE_PIPE:
				break;

			case HTTP_RESPONSE_DONE:
				free (this->buffer);
				this->buffer = NULL;
				delete(&(this->cur_response));
				this->state = HTTP_RESPONSE_NO;

				break;
		}
	}

	return written;
}

// vim: set ts=4 sw=4: