1*76404edcSAsim Jamshed /**
2*76404edcSAsim Jamshed * the HTTP chunk-API
3*76404edcSAsim Jamshed *
4*76404edcSAsim Jamshed *
5*76404edcSAsim Jamshed */
6*76404edcSAsim Jamshed
7*76404edcSAsim Jamshed #include "server.h"
8*76404edcSAsim Jamshed #include "chunk.h"
9*76404edcSAsim Jamshed #include "http_chunk.h"
10*76404edcSAsim Jamshed #include "log.h"
11*76404edcSAsim Jamshed
12*76404edcSAsim Jamshed #include <sys/types.h>
13*76404edcSAsim Jamshed #include <sys/stat.h>
14*76404edcSAsim Jamshed
15*76404edcSAsim Jamshed #include <stdlib.h>
16*76404edcSAsim Jamshed #include <fcntl.h>
17*76404edcSAsim Jamshed #include <unistd.h>
18*76404edcSAsim Jamshed
19*76404edcSAsim Jamshed #include <stdio.h>
20*76404edcSAsim Jamshed #include <errno.h>
21*76404edcSAsim Jamshed #include <string.h>
22*76404edcSAsim Jamshed
http_chunk_append_len(server * srv,connection * con,size_t len)23*76404edcSAsim Jamshed static int http_chunk_append_len(server *srv, connection *con, size_t len) {
24*76404edcSAsim Jamshed size_t i, olen = len, j;
25*76404edcSAsim Jamshed buffer *b;
26*76404edcSAsim Jamshed
27*76404edcSAsim Jamshed b = srv->tmp_chunk_len;
28*76404edcSAsim Jamshed
29*76404edcSAsim Jamshed if (len == 0) {
30*76404edcSAsim Jamshed buffer_copy_string_len(b, CONST_STR_LEN("0"));
31*76404edcSAsim Jamshed } else {
32*76404edcSAsim Jamshed for (i = 0; i < 8 && len; i++) {
33*76404edcSAsim Jamshed len >>= 4;
34*76404edcSAsim Jamshed }
35*76404edcSAsim Jamshed
36*76404edcSAsim Jamshed /* i is the number of hex digits we have */
37*76404edcSAsim Jamshed buffer_prepare_copy(b, i + 1);
38*76404edcSAsim Jamshed
39*76404edcSAsim Jamshed for (j = i-1, len = olen; j+1 > 0; j--) {
40*76404edcSAsim Jamshed b->ptr[j] = (len & 0xf) + (((len & 0xf) <= 9) ? '0' : 'a' - 10);
41*76404edcSAsim Jamshed len >>= 4;
42*76404edcSAsim Jamshed }
43*76404edcSAsim Jamshed b->used = i;
44*76404edcSAsim Jamshed b->ptr[b->used++] = '\0';
45*76404edcSAsim Jamshed }
46*76404edcSAsim Jamshed
47*76404edcSAsim Jamshed buffer_append_string_len(b, CONST_STR_LEN("\r\n"));
48*76404edcSAsim Jamshed chunkqueue_append_buffer(con->write_queue, b);
49*76404edcSAsim Jamshed
50*76404edcSAsim Jamshed return 0;
51*76404edcSAsim Jamshed }
52*76404edcSAsim Jamshed
53*76404edcSAsim Jamshed
http_chunk_append_file(server * srv,connection * con,buffer * fn,off_t offset,off_t len)54*76404edcSAsim Jamshed int http_chunk_append_file(server *srv, connection *con, buffer *fn, off_t offset, off_t len) {
55*76404edcSAsim Jamshed chunkqueue *cq;
56*76404edcSAsim Jamshed
57*76404edcSAsim Jamshed if (!con) return -1;
58*76404edcSAsim Jamshed
59*76404edcSAsim Jamshed cq = con->write_queue;
60*76404edcSAsim Jamshed
61*76404edcSAsim Jamshed if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
62*76404edcSAsim Jamshed http_chunk_append_len(srv, con, len);
63*76404edcSAsim Jamshed }
64*76404edcSAsim Jamshed
65*76404edcSAsim Jamshed chunkqueue_append_file(cq, fn, offset, len);
66*76404edcSAsim Jamshed
67*76404edcSAsim Jamshed if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && len > 0) {
68*76404edcSAsim Jamshed chunkqueue_append_mem(cq, "\r\n", 2 + 1);
69*76404edcSAsim Jamshed }
70*76404edcSAsim Jamshed
71*76404edcSAsim Jamshed return 0;
72*76404edcSAsim Jamshed }
73*76404edcSAsim Jamshed
http_chunk_append_buffer(server * srv,connection * con,buffer * mem)74*76404edcSAsim Jamshed int http_chunk_append_buffer(server *srv, connection *con, buffer *mem) {
75*76404edcSAsim Jamshed chunkqueue *cq;
76*76404edcSAsim Jamshed
77*76404edcSAsim Jamshed if (!con) return -1;
78*76404edcSAsim Jamshed
79*76404edcSAsim Jamshed cq = con->write_queue;
80*76404edcSAsim Jamshed
81*76404edcSAsim Jamshed if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
82*76404edcSAsim Jamshed http_chunk_append_len(srv, con, mem->used - 1);
83*76404edcSAsim Jamshed }
84*76404edcSAsim Jamshed
85*76404edcSAsim Jamshed chunkqueue_append_buffer(cq, mem);
86*76404edcSAsim Jamshed
87*76404edcSAsim Jamshed if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED && mem->used > 0) {
88*76404edcSAsim Jamshed chunkqueue_append_mem(cq, "\r\n", 2 + 1);
89*76404edcSAsim Jamshed }
90*76404edcSAsim Jamshed
91*76404edcSAsim Jamshed return 0;
92*76404edcSAsim Jamshed }
93*76404edcSAsim Jamshed
http_chunk_append_mem(server * srv,connection * con,const char * mem,size_t len)94*76404edcSAsim Jamshed int http_chunk_append_mem(server *srv, connection *con, const char * mem, size_t len) {
95*76404edcSAsim Jamshed chunkqueue *cq;
96*76404edcSAsim Jamshed
97*76404edcSAsim Jamshed if (!con) return -1;
98*76404edcSAsim Jamshed
99*76404edcSAsim Jamshed cq = con->write_queue;
100*76404edcSAsim Jamshed
101*76404edcSAsim Jamshed if (len == 0) {
102*76404edcSAsim Jamshed if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
103*76404edcSAsim Jamshed chunkqueue_append_mem(cq, "0\r\n\r\n", 5 + 1);
104*76404edcSAsim Jamshed } else {
105*76404edcSAsim Jamshed chunkqueue_append_mem(cq, "", 1);
106*76404edcSAsim Jamshed }
107*76404edcSAsim Jamshed return 0;
108*76404edcSAsim Jamshed }
109*76404edcSAsim Jamshed
110*76404edcSAsim Jamshed if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
111*76404edcSAsim Jamshed http_chunk_append_len(srv, con, len - 1);
112*76404edcSAsim Jamshed }
113*76404edcSAsim Jamshed
114*76404edcSAsim Jamshed chunkqueue_append_mem(cq, mem, len);
115*76404edcSAsim Jamshed
116*76404edcSAsim Jamshed if (con->response.transfer_encoding & HTTP_TRANSFER_ENCODING_CHUNKED) {
117*76404edcSAsim Jamshed chunkqueue_append_mem(cq, "\r\n", 2 + 1);
118*76404edcSAsim Jamshed }
119*76404edcSAsim Jamshed
120*76404edcSAsim Jamshed return 0;
121*76404edcSAsim Jamshed }
122*76404edcSAsim Jamshed
123*76404edcSAsim Jamshed
http_chunkqueue_length(server * srv,connection * con)124*76404edcSAsim Jamshed off_t http_chunkqueue_length(server *srv, connection *con) {
125*76404edcSAsim Jamshed if (!con) {
126*76404edcSAsim Jamshed log_error_write(srv, __FILE__, __LINE__, "s", "connection is NULL!!");
127*76404edcSAsim Jamshed
128*76404edcSAsim Jamshed return 0;
129*76404edcSAsim Jamshed }
130*76404edcSAsim Jamshed
131*76404edcSAsim Jamshed return chunkqueue_length(con->write_queue);
132*76404edcSAsim Jamshed }
133