root/src/noit_http.h

Revision 68a5668794386efc593e280d7111deca068caa5d, 7.2 kB (checked in by Theo Schlossnagle <jesus@omniti.com>, 4 years ago)

hack to allow un-dup'd mmap buckets to be sent over HTTP when the planets align (no chunks, no compression)

  • Property mode set to 100644
Line 
1 /*
2  * Copyright (c) 2007, OmniTI Computer Consulting, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  *       notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  *       copyright notice, this list of conditions and the following
13  *       disclaimer in the documentation and/or other materials provided
14  *       with the distribution.
15  *     * Neither the name OmniTI Computer Consulting, Inc. nor the names
16  *       of its contributors may be used to endorse or promote products
17  *       derived from this software without specific prior written
18  *       permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #ifndef _NOIT_HTTP_H
34 #define _NOIT_HTTP_H
35
36 #include "noit_defines.h"
37 #include <libxml/tree.h>
38 #include "eventer/eventer.h"
39 #include "utils/noit_hash.h"
40 #include "utils/noit_atomic.h"
41 #include "noit_listener.h"
42
43 typedef enum {
44   NOIT_HTTP_OTHER, NOIT_HTTP_GET, NOIT_HTTP_HEAD, NOIT_HTTP_POST
45 } noit_http_method;
46 typedef enum {
47   NOIT_HTTP09, NOIT_HTTP10, NOIT_HTTP11
48 } noit_http_protocol;
49
50 #define NOIT_HTTP_CHUNKED 0x0001
51 #define NOIT_HTTP_CLOSE   0x0002
52 #define NOIT_HTTP_GZIP    0x0010
53 #define NOIT_HTTP_DEFLATE 0x0020
54
55 typedef enum {
56   BCHAIN_INLINE = 0,
57   BCHAIN_MMAP
58 } bchain_type_t;
59
60 struct bchain {
61   bchain_type_t type;
62   struct bchain *next, *prev;
63   size_t start; /* where data starts (buff + start) */
64   size_t size;  /* data length (past start) */
65   size_t allocd;/* total allocation */
66   char *buff;
67   char _buff[1]; /* over allocate as needed */
68 };
69
70 #define DEFAULT_MAXWRITE 1<<14 /* 32k */
71 #define DEFAULT_BCHAINSIZE ((1 << 15)-(offsetof(struct bchain, _buff)))
72 /* 64k - delta */
73 #define DEFAULT_BCHAINMINREAD (DEFAULT_BCHAINSIZE/4)
74 #define BCHAIN_SPACE(a) ((a)->allocd - (a)->size - (a)->start)
75
76 typedef struct {
77   eventer_t e;
78   int needs_close;
79 } noit_http_connection;
80
81 typedef struct {
82   struct bchain *first_input; /* The start of the input chain */
83   struct bchain *last_input;  /* The end of the input chain */
84   struct bchain *current_input;  /* The point of the input where we */
85   size_t         current_offset; /* analyzing. */
86
87   enum { NOIT_HTTP_REQ_HEADERS = 0,
88          NOIT_HTTP_REQ_EXPECT,
89          NOIT_HTTP_REQ_PAYLOAD } state;
90   struct bchain *current_request_chain;
91   noit_boolean has_payload;
92   int64_t content_length;
93   int64_t content_length_read;
94   char *method_str;
95   char *uri_str;
96   char *protocol_str;
97   noit_hash_table querystring;
98   u_int32_t opts;
99   noit_http_method method;
100   noit_http_protocol protocol;
101   noit_hash_table headers;
102   noit_boolean complete;
103   struct timeval start_time;
104   char *orig_qs;
105 } noit_http_request;
106
107 typedef struct {
108   noit_http_protocol protocol;
109   int status_code;
110   char *status_reason;
111
112   noit_hash_table headers;
113   struct bchain *leader; /* serialization of status line and headers */
114
115   u_int32_t output_options;
116   struct bchain *output;       /* data is pushed in here */
117   struct bchain *output_raw;   /* internally transcoded here for output */
118   size_t output_raw_offset;    /* tracks our offset */
119   noit_boolean output_started; /* locks the options and leader */
120                                /*   and possibly output. */
121   noit_boolean closed;         /* set by _end() */
122   noit_boolean complete;       /* complete, drained and disposable */
123   size_t bytes_written;        /* tracks total bytes written */
124 } noit_http_response;
125
126 struct noit_http_session_ctx;
127 typedef int (*noit_http_dispatch_func) (struct noit_http_session_ctx *);
128
129 typedef struct noit_http_session_ctx {
130   noit_atomic32_t ref_cnt;
131   int64_t drainage;
132   int max_write;
133   noit_http_connection conn;
134   noit_http_request req;
135   noit_http_response res;
136   noit_http_dispatch_func dispatcher;
137   void *dispatcher_closure;
138   acceptor_closure_t *ac;
139 } noit_http_session_ctx;
140
141 API_EXPORT(noit_http_session_ctx *)
142   noit_http_session_ctx_new(noit_http_dispatch_func, void *, eventer_t,
143                             acceptor_closure_t *);
144 API_EXPORT(void)
145   noit_http_ctx_session_release(noit_http_session_ctx *ctx);
146
147
148 API_EXPORT(void)
149   noit_http_ctx_acceptor_free(void *); /* just calls noit_http_session_ctx_release */
150
151 API_EXPORT(void)
152   noit_http_process_querystring(noit_http_request *);
153
154 API_EXPORT(int)
155   noit_http_session_drive(eventer_t, int, void *, struct timeval *, int *done);
156
157 API_EXPORT(noit_boolean)
158   noit_http_session_prime_input(noit_http_session_ctx *, const void *, size_t);
159 API_EXPORT(int)
160   noit_http_session_req_consume(noit_http_session_ctx *ctx,
161                                 void *buf, size_t len, int *mask);
162 API_EXPORT(noit_boolean)
163   noit_http_response_status_set(noit_http_session_ctx *, int, const char *);
164 API_EXPORT(noit_boolean)
165   noit_http_response_header_set(noit_http_session_ctx *,
166                                 const char *, const char *);
167 API_EXPORT(noit_boolean)
168   noit_http_response_option_set(noit_http_session_ctx *, u_int32_t);
169 API_EXPORT(noit_boolean)
170   noit_http_response_append(noit_http_session_ctx *, const void *, size_t);
171 API_EXPORT(noit_boolean)
172   noit_http_response_append_bchain(noit_http_session_ctx *, struct bchain *);
173 API_EXPORT(noit_boolean)
174   noit_http_response_append_mmap(noit_http_session_ctx *,
175                                  int fd, size_t len, int flags, off_t offset);
176 API_EXPORT(noit_boolean)
177   noit_http_response_flush(noit_http_session_ctx *, noit_boolean);
178 API_EXPORT(noit_boolean) noit_http_response_end(noit_http_session_ctx *);
179
180 #define noit_http_response_server_error(ctx, type) \
181   noit_http_response_standard(ctx, 500, "ERROR", type)
182 #define noit_http_response_ok(ctx, type) \
183   noit_http_response_standard(ctx, 200, "OK", type)
184 #define noit_http_response_not_found(ctx, type) \
185   noit_http_response_standard(ctx, 404, "NOT FOUND", type)
186 #define noit_http_response_denied(ctx, type) \
187   noit_http_response_standard(ctx, 403, "DENIED", type)
188
189 #define noit_http_response_standard(ctx, code, name, type) do { \
190   noit_http_response_status_set(ctx, code, name); \
191   noit_http_response_header_set(ctx, "Content-Type", type); \
192   if(noit_http_response_option_set(ctx, NOIT_HTTP_CHUNKED) == noit_false) \
193     noit_http_response_option_set(ctx, NOIT_HTTP_CLOSE); \
194   noit_http_response_option_set(ctx, NOIT_HTTP_DEFLATE); \
195 } while(0)
196
197 API_EXPORT(void)
198   noit_http_response_xml(noit_http_session_ctx *, xmlDocPtr);
199
200 API_EXPORT(void)
201   noit_http_init();
202
203 #endif
Note: See TracBrowser for help on using the browser.