Klaus Demo bjoern / 4023ba1
Merge branch 'master' of https://github.com/jameslittle/bjoern into keepalive Jonas Haag 7 years ago
1 changed file(s) with 16 addition(s) and 25 deletion(s). Raw diff Collapse all Expand all
55 static PyObject* (start_response)(PyObject* self, PyObject* args, PyObject *kwargs);
66 static size_t wsgi_getheaders(Request*, PyObject* buf);
77 static inline bool inspect_headers(Request*);
8 static inline bool should_keep_alive(Request*);
98
109 typedef struct {
1110 PyObject_HEAD
114113 Py_DECREF(first_chunk);
115114 return false;
116115 }
117
118 if(should_keep_alive(request)) {
116
117 /* Let http-parser decide if connection should be keep-alive: */
118 if(http_should_keep_alive(&request->parser.parser)) {
119119 request->state.chunked_response = request->state.response_length_unknown;
120120 request->state.keep_alive = true;
121121 } else {
191191 return false;
192192 }
193193
194
194195 static size_t
195196 wsgi_getheaders(Request* request, PyObject* buf)
196197 {
197198 char* bufp = PyString_AS_STRING(buf);
199 int have_http11 = (request->parser.parser.http_major > 0 && request->parser.parser.http_minor > 0);
198200
199201 #define buf_write(src, len) \
200202 do { \
217219 buf_write2(": ");
218220 buf_write(PyString_AS_STRING(value), PyString_GET_SIZE(value));
219221 }
220 if(request->state.chunked_response)
222 if(!have_http11) {
223 if(request->state.chunked_response)
224 /* Can't do chunked with HTTP 1.0 */
225 buf_write2("\r\nConnection: close");
226 else if (request->state.keep_alive)
227 /* Need to be explicit with HTTP 1.0 */
228 buf_write2("\r\nConnection: Keep-Alive");
229 }
230 else if(request->state.chunked_response)
221231 buf_write2("\r\nTransfer-Encoding: chunked");
222232 buf_write2("\r\n\r\n");
223233
338348 start_response /* tp_call (__call__) */
339349 };
340350
341 #define F_KEEP_ALIVE 1<<1
342 #define have_http11(parser) (parser.http_major > 0 && parser.http_minor > 0)
343
344 static inline bool
345 should_keep_alive(Request* request)
346 {
347 if(!(request->parser.parser.flags & F_KEEP_ALIVE)) {
348 /* Only keep-alive if the client requested it explicitly */
349 return false;
350 }
351 if(request->state.response_length_unknown) {
352 /* If the client wants to keep-alive the connection but we don't know
353 * the response length, we can use Transfer-Encoding: chunked on HTTP/1.1.
354 * On HTTP/1.0 no such thing exists so there's no other option than closing
355 * the connection to indicate the response end. */
356 return have_http11(request->parser.parser);
357 } else {
358 /* If the response length is known we can keep-alive for both 1.0 and 1.1 */
359 return true;
360 }
361 }
351
352
362353
363354 PyObject*
364355 wrap_http_chunk_cruft_around(PyObject* chunk)