WEBBY - the embedded web server with many faces / objects in plain C Snapshot
|
represents the http response and includes methods to set response header and send the response body. More...
Classes | |
struct | tagHTTP_servlet_response |
Typedefs | |
typedef struct tagHTTP_servlet_response | HTTP_servlet_response |
Enumerations | |
enum | HTTP_servlet_response_type { RESPONSE_CONNECTION_CLOSE, RESPONSE_CONTENT_LENGTH, RESPONSE_CHUNKED } |
Functions | |
int | HTTP_response_start (HTTP_servlet_response *resp, int status, const char *mime_type, HTTP_servlet_response_type rtype, size_t length) |
initiate an HTTP response | |
int | HTTP_response_send (HTTP_servlet_response *resp, void *data, size_t size) |
send response data when sending RESPONSE_CONTENT_LENGTH or RESPONSE_CONNECTION_CLOSE responses | |
int | HTTP_response_finish (HTTP_servlet_response *resp) |
finish sending of response | |
BF * | HTTP_response_get_chunk_buffer (HTTP_servlet_response *resp, size_t chunk_size) |
returns buffer for sending chunks The buffer reserves enough space before start of buffer, in order to allow addition of chunk header before the sent daa | |
int | HTTP_response_write_chunk (HTTP_servlet_response *resp, BF *bf) |
send chunk from buffer The buffer must reserve enough space for the chunk header, before start of buffer |
represents the http response and includes methods to set response header and send the response body.
typedef struct tagHTTP_servlet_response HTTP_servlet_response |
int HTTP_response_finish | ( | HTTP_servlet_response * | resp | ) |
finish sending of response
Definition at line 1003 of file webby.c.
{ RDATA rdata; if (resp->state < 1 || resp->state > 2) { return -1; } if (resp->state == 1) { if (call_next_filter_response_header( &resp->response, resp->filter_context )) { return -1; } } if (resp->response.base.flags & HTTP_MESSAGE_FLAG_TRANSFER_CHUNKED) { rdata.chunk.bf = 0; rdata.chunk.chunk_no = ++resp->chunk_no; if ( call_next_filter_response_data ( &resp->response, 1, rdata, resp->filter_context ) ) { return -1; } #if 0 if (resp->state == 1) { if (call_next_filter_response_data ( &resp->response, LAST_CHUNK, LAST_CHUNK_SIZE, resp->filter_context )) { return -1; } } else { if (call_next_filter_response_data ( &resp->response, LAST_CHUNK_NOT_FIRST, LAST_CHUNK_NOT_FIRST_SIZE, resp->filter_context )) { return -1; } } #endif } resp->state = 3; return call_next_filter_response_completed ( &resp->response, resp->filter_context ); }
BF* HTTP_response_get_chunk_buffer | ( | HTTP_servlet_response * | resp, |
size_t | chunk_size | ||
) |
returns buffer for sending chunks The buffer reserves enough space before start of buffer, in order to allow addition of chunk header before the sent daa
Definition at line 928 of file webby.c.
{ size_t sz; void *tmp; if (resp->chunk_buf != 0) { if (resp->chunk_buf_size < chunk_size ) { sz = chunk_size + RESERVED_FOR_CHUNK_HEADER_SIZE; tmp = realloc( resp->chunk_buf, sz ); if (!tmp) { return 0; } resp->chunk_buf = tmp; resp->chunk_buf_size = chunk_size; } } else { sz = chunk_size + RESERVED_FOR_CHUNK_HEADER_SIZE; resp->chunk_buf = malloc( sz ); if (!resp->chunk_buf) { return 0; } BF_init( &resp->bf, resp->chunk_buf, sz ); resp->chunk_buf_size = chunk_size; } BF_put_mode( &resp->bf ); BF_set_start( &resp->bf, RESERVED_FOR_CHUNK_HEADER_SIZE ); resp->bf.end = resp->bf.put_pos + chunk_size; return &resp->bf; }
int HTTP_response_send | ( | HTTP_servlet_response * | resp, |
void * | data, | ||
size_t | size | ||
) |
send response data when sending RESPONSE_CONTENT_LENGTH or RESPONSE_CONNECTION_CLOSE responses
Precondition: HTTP_response_start has been called. and response type is either RESPONSE_CONTENT_LENGTH or RESPONSE_CONNECTION_CLOSE
Definition at line 892 of file webby.c.
{ RDATA rdata; if (resp->state < 1 || resp->state > 2) { return -1; } if (resp->state == 1) { if (call_next_filter_response_header( &resp->response, resp->filter_context )) { return -1; } resp->state = 2; } if (resp->response.base.flags & HTTP_MESSAGE_FLAG_TRANSFER_CHUNKED ) { return -1; } // check that not sending more data than allowed by set value of Content-Length header. if (resp->data_sent != (size_t) -1) { if (resp->data_sent < size ) { return -1; } resp->data_sent -= size; } rdata.no_chunk.data = data; rdata.no_chunk.data_size = size; return call_next_filter_response_data ( &resp->response, 0, rdata, resp->filter_context ); }
int HTTP_response_start | ( | HTTP_servlet_response * | resp, |
int | status, | ||
const char * | mime_type, | ||
HTTP_servlet_response_type | rtype, | ||
size_t | length | ||
) |
initiate an HTTP response
Definition at line 855 of file webby.c.
{ if (resp->state !=0) { return -1; } resp->response.status_code = status; if (mime_type) { HTTP_MESSAGE_add_header( &resp->response.base, "Content-Type", mime_type ); } if ( ! HTTP_REQUEST_is_persistent( resp->request ) ) { rtype = RESPONSE_CONNECTION_CLOSE; } switch(rtype) { case RESPONSE_CONNECTION_CLOSE: resp->response.base.flags = HTTP_MESSAGE_FLAG_CONNECTION_CLOSE; resp->data_sent = (size_t) -1; break; case RESPONSE_CONTENT_LENGTH: HTTP_MESSAGE_set_content_length( &resp->response.base, length ); resp->data_sent = length; break; case RESPONSE_CHUNKED: resp->response.base.flags = HTTP_MESSAGE_FLAG_TRANSFER_CHUNKED; #if 0 if (HTTP_MESSAGE_add_header( &resp->response.base, "Transfer-Encoding" , "chunked" )) { return -1; } #endif break; } resp->state = 1; return 0; }
int HTTP_response_write_chunk | ( | HTTP_servlet_response * | resp, |
BF * | bf | ||
) |
send chunk from buffer The buffer must reserve enough space for the chunk header, before start of buffer
Precondition: HTTP_response_start has been called, and response type is RESPONSE_CHUNKED
Definition at line 960 of file webby.c.
{ RDATA rdata; if (resp->state < 1 || resp->state > 2) { return -1; } if ( (resp->response.base.flags & (HTTP_MESSAGE_FLAG_TRANSFER_CHUNKED | HTTP_MESSAGE_FLAG_CONNECTION_CLOSE) ) == 0) { return -1; } if (resp->state == 1) { if (call_next_filter_response_header( &resp->response, resp->filter_context )) { return -1; } resp->state = 2; } else { ++ resp->chunk_no; } if ( resp->response.base.flags & HTTP_MESSAGE_FLAG_CONNECTION_CLOSE ) { rdata.no_chunk.data = bf->get_pos; rdata.no_chunk.data_size = BF_get_size( bf ); return call_next_filter_response_data ( &resp->response, 0, rdata, resp->filter_context ); } #if 0 if (first_chunk) { len = snprintf( chunk_header, sizeof( chunk_header ), "%x\r\n", BF_get_size(bf) ); } else { len = snprintf( chunk_header, sizeof( chunk_header ), "\r\n%x\r\n", BF_get_size(bf) ); } #endif rdata.chunk.bf = bf; rdata.chunk.chunk_no = resp->chunk_no; return call_next_filter_response_data ( &resp->response, 1, rdata, resp->filter_context ); }