public
Description: A very fast & simple Ruby web server
Homepage: http://code.macournoyer.com/thin/
Clone URL: git://github.com/macournoyer/thin.git
Search Repo:
Do not puke on big header
macournoyer (author)
Sun Apr 06 16:32:01 -0700 2008
commit  e95a97c2d92c34daa69f17972ab8384fd793c13d
tree    9f6b5cf62e92eba99142c944ee149acc532a7509
parent  621c237891c6c9eb2d6df63b73281863cc352bd9
...
128
129
130
 
 
131
132
133
134
135
136
 
 
 
 
 
 
 
 
 
 
 
137
138
139
140
141
142
 
 
 
 
 
 
143
144
145
146
147
148
149
150
 
151
152
153
154
155
156
157
158
159
160
 
 
 
 
 
 
 
 
 
 
161
162
163
164
165
166
167
168
169
 
170
171
172
 
 
 
 
173
174
175
...
128
129
130
131
132
133
134
135
136
 
 
137
138
139
140
141
142
143
144
145
146
147
148
 
 
 
 
 
149
150
151
152
153
154
155
 
 
 
 
 
 
 
156
157
 
 
 
 
 
 
 
 
 
158
159
160
161
162
163
164
165
166
167
168
169
 
 
 
 
 
170
 
171
172
173
 
174
175
176
177
178
179
180
0
@@ -128,48 +128,53 @@
0
   
0
   /* init libev stuff */
0
   watch(connection, thin_connection_readable_cb, read, EV_READ);
0
+
0
+ /* TODO add timeout watcher */
0
 }
0
 
0
 void thin_connection_parse(thin_connection_t *connection, char *buf, int len)
0
 {
0
- if (http_parser_is_finished(&connection->parser)) {
0
- /* parsing done, can only be some more body ... */
0
+ if (!http_parser_is_finished(&connection->parser)
0
+ && connection->read_buffer.len + len > THIN_MAX_HEADER) {
0
+ thin_connection_error(connection, "Header too big");
0
+ return;
0
+ }
0
+
0
+ /* alloc more mem when buffer full */
0
+ /* TODO extract this into buffer.c and optimize */
0
+ /* TODO store big body in tempfile */
0
+ if (connection->read_buffer.len >= connection->read_buffer.salloc) {
0
+ char *new, *old;
0
     
0
- /* alloc more mem when buffer full */
0
- /* TODO extract this into buffer.c and optimize */
0
- /* TODO store big body in tempfile */
0
- if (connection->read_buffer.len >= connection->read_buffer.salloc) {
0
- char *new, *old;
0
+ /* TODO if last alloc, just alloc next block */
0
+ old = connection->read_buffer.ptr;
0
+ new = (char *) palloc(connection->buffer_pool,
0
+ connection->read_buffer.nalloc + 1);
0
+ if (new == NULL)
0
+ rb_sys_fail("palloc");
0
       
0
- old = connection->read_buffer.ptr;
0
- new = (char *) palloc(connection->buffer_pool,
0
- connection->read_buffer.nalloc * 2);
0
- if (new == NULL)
0
- rb_sys_fail("palloc");
0
-
0
- memcpy(new, old, connection->read_buffer.len);
0
+ memcpy(new, old, connection->read_buffer.len);
0
 
0
- connection->read_buffer.ptr = new;
0
- connection->read_buffer.nalloc *= 2;
0
- connection->read_buffer.salloc *= 2;
0
- pfree(connection->buffer_pool, old);
0
- }
0
-
0
- memcpy(connection->read_buffer.ptr + connection->read_buffer.len, buf, len);
0
-
0
- } else {
0
+ connection->read_buffer.ptr = new;
0
+ connection->read_buffer.nalloc ++;
0
+ connection->read_buffer.salloc += connection->buffer_pool->size;
0
+ pfree(connection->buffer_pool, old);
0
+ }
0
+
0
+ memcpy(connection->read_buffer.ptr + connection->read_buffer.len, buf, len);
0
+ connection->read_buffer.len += len;
0
+
0
+ if (!http_parser_is_finished(&connection->parser)) {
0
     /* header not all received, we continue parsing ... */
0
     
0
- if (connection->parser.nread + len > THIN_MAX_HEADER) {
0
- thin_connection_error(connection, "Header too big");
0
- return;
0
- }
0
-
0
     /* terminate string with null (required by ragel v5) */
0
- buf[len] = '\0';
0
+ memset(connection->read_buffer.ptr + connection->read_buffer.len, '\0', 1);
0
     
0
     /* parse the request into connection->env */
0
- http_parser_execute(&connection->parser, buf, len, connection->parser.nread);
0
+ connection->parser.nread = http_parser_execute(&connection->parser,
0
+ connection->read_buffer.ptr,
0
+ connection->read_buffer.len,
0
+ connection->parser.nread);
0
   
0
     /* parser error */
0
     if (http_parser_has_error(&connection->parser)) {
...
30
31
32
33
 
34
35
36
...
30
31
32
 
33
34
35
36
0
@@ -30,7 +30,7 @@
0
 #define THIN_LISTEN_BACKLOG 511
0
 #endif
0
 #define THIN_CONNECTIONS_SIZE 100
0
-#define THIN_BUFFER_SLICES 100
0
+#define THIN_BUFFER_SLICES (80 + 32) * 2 /* big enough so we can fit MAX_HEADER */
0
 #define THIN_BUFFER_SIZE 1024
0
 
0
 /* TODO move this to parser ... */

Comments

    No one has commented yet.