lighttpd 1.4.x
https://www.lighttpd.net/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
2.7 KiB
133 lines
2.7 KiB
/** |
|
* the HTTP chunk-API |
|
* |
|
* |
|
*/ |
|
|
|
#include <sys/types.h> |
|
#include <sys/stat.h> |
|
|
|
#include <stdlib.h> |
|
#include <fcntl.h> |
|
#include <unistd.h> |
|
|
|
#include <stdio.h> |
|
#include <errno.h> |
|
#include <string.h> |
|
|
|
#include "server.h" |
|
#include "chunk.h" |
|
#include "http_chunk.h" |
|
#include "log.h" |
|
|
|
static int http_chunk_append_len(server *srv, connection *con, size_t len) { |
|
size_t i, olen = len, j; |
|
buffer *b; |
|
|
|
b = srv->tmp_chunk_len; |
|
|
|
if (len == 0) { |
|
buffer_copy_string(b, "0"); |
|
} else { |
|
for (i = 0; i < 8 && len; i++) { |
|
len >>= 4; |
|
} |
|
|
|
/* i is the number of hex digits we have */ |
|
buffer_prepare_copy(b, i + 1); |
|
|
|
for (j = i-1, len = olen; j+1 > 0; j--) { |
|
b->ptr[j] = (len & 0xf) + (((len & 0xf) <= 9) ? '0' : 'a' - 10); |
|
len >>= 4; |
|
} |
|
b->used = i; |
|
b->ptr[b->used++] = '\0'; |
|
} |
|
|
|
buffer_append_string(b, "\r\n"); |
|
chunkqueue_append_buffer(con->write_queue, b); |
|
|
|
return 0; |
|
} |
|
|
|
|
|
int http_chunk_append_file(server *srv, connection *con, buffer *fn, off_t offset, off_t len) { |
|
chunkqueue *cq; |
|
|
|
if (!con) return -1; |
|
|
|
cq = con->write_queue; |
|
|
|
if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { |
|
http_chunk_append_len(srv, con, len); |
|
} |
|
|
|
chunkqueue_append_file(cq, fn, offset, len); |
|
|
|
if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && len > 0) { |
|
chunkqueue_append_mem(cq, "\r\n", 2 + 1); |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
int http_chunk_append_buffer(server *srv, connection *con, buffer *mem) { |
|
chunkqueue *cq; |
|
|
|
if (!con) return -1; |
|
|
|
cq = con->write_queue; |
|
|
|
if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { |
|
http_chunk_append_len(srv, con, mem->used - 1); |
|
} |
|
|
|
chunkqueue_append_buffer(cq, mem); |
|
|
|
if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && mem->used > 0) { |
|
chunkqueue_append_mem(cq, "\r\n", 2 + 1); |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
int http_chunk_append_mem(server *srv, connection *con, const char * mem, size_t len) { |
|
chunkqueue *cq; |
|
|
|
if (!con) return -1; |
|
|
|
cq = con->write_queue; |
|
|
|
if (len == 0) { |
|
if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { |
|
http_chunk_append_len(srv, con, 0); |
|
chunkqueue_append_mem(cq, "\r\n", 2 + 1); |
|
} else { |
|
chunkqueue_append_mem(cq, "", 1); |
|
} |
|
return 0; |
|
} |
|
|
|
if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { |
|
http_chunk_append_len(srv, con, len - 1); |
|
} |
|
|
|
chunkqueue_append_mem(cq, mem, len); |
|
|
|
if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) { |
|
chunkqueue_append_mem(cq, "\r\n", 2 + 1); |
|
} |
|
|
|
return 0; |
|
} |
|
|
|
|
|
off_t http_chunkqueue_length(server *srv, connection *con) { |
|
if (!con) { |
|
log_error_write(srv, __FILE__, __LINE__, "s", "connection is NULL!!"); |
|
|
|
return 0; |
|
} |
|
|
|
return chunkqueue_length(con->write_queue); |
|
}
|
|
|