Klaus Demo bjoern / bf2f19d
Rename macros Jonas Haag 1 year, 6 months ago
5 changed file(s) with 73 addition(s) and 75 deletion(s). Raw diff Collapse all Expand all
2929 void _init_common()
3030 {
3131
32 #define _(name) _##name = _UnicodeUTF8_FromString(#name)
32 #define _(name) _##name = _PEP3333_String_FromUTF8String(#name)
3333 _(REMOTE_ADDR);
3434 _(PATH_INFO);
3535 _(QUERY_STRING);
5353 _(seek);
5454 #undef _
5555
56 _HTTP_1_1 = _UnicodeUTF8_FromString("HTTP/1.1");
57 _HTTP_1_0 = _UnicodeUTF8_FromString("HTTP/1.0");
58 _wsgi_input = _UnicodeUTF8_FromString("wsgi.input");
59 _empty_string = _UnicodeUTF8_FromString("");
60 _empty_bytes = _Bytes_FromString("");
56 _HTTP_1_1 = _PEP3333_String_FromUTF8String("HTTP/1.1");
57 _HTTP_1_0 = _PEP3333_String_FromUTF8String("HTTP/1.0");
58 _wsgi_input = _PEP3333_String_FromUTF8String("wsgi.input");
59 _empty_string = _PEP3333_String_FromUTF8String("");
60 _empty_bytes = _PEP3333_Bytes_FromString("");
6161 }
44 #define NOP do{}while(0)
55 #define PyFile_IncUseCount(file) NOP
66 #define PyFile_DecUseCount(file) NOP
7 #define _Bytes_AS_DATA(bytes) PyBytes_AS_STRING(bytes)
8 #define _Bytes_FromString(bytes) PyBytes_FromString(bytes)
9 #define _Bytes_FromStringAndSize(data, len) PyBytes_FromStringAndSize(data, len)
10 #define _Bytes_GET_SIZE(bytes) PyBytes_GET_SIZE(bytes)
11 #define _Bytes_Check(bytes) PyBytes_Check(bytes)
12 #define _Bytes_Resize(bytes, len) _PyBytes_Resize(bytes, len)
13 #define _BytesLatin1_FromUnicode(u) PyUnicode_AsLatin1String(u)
14 #define _UnicodeUTF8_FromString(data) PyUnicode_FromString(data)
15 #define _Unicode_GET_SIZE(u) PyUnicode_GET_LENGTH(u)
16 #define _UnicodeLatin1_FromStringAndSize(data, len) PyUnicode_DecodeLatin1(data, len, "replace")
17 #define _Unicode_Concat(u1, u2) PyUnicode_Concat(u1, u2)
187 #define _FromLong(n) PyLong_FromLong(n)
8 #define _PEP3333_Bytes_AS_DATA(bytes) PyBytes_AS_STRING(bytes)
9 #define _PEP3333_Bytes_FromString(bytes) PyBytes_FromString(bytes)
10 #define _PEP3333_Bytes_FromStringAndSize(data, len) PyBytes_FromStringAndSize(data, len)
11 #define _PEP3333_Bytes_GET_SIZE(bytes) PyBytes_GET_SIZE(bytes)
12 #define _PEP3333_Bytes_Check(bytes) PyBytes_Check(bytes)
13 #define _PEP3333_Bytes_Resize(bytes, len) _PyBytes_Resize(bytes, len)
14 #define _PEP3333_BytesLatin1_FromUnicode(u) PyUnicode_AsLatin1String(u)
15 #define _PEP3333_String_FromUTF8String(data) PyUnicode_FromString(data)
16 #define _PEP3333_String_FromLatin1StringAndSize(data, len) PyUnicode_DecodeLatin1(data, len, "replace")
17 #define _PEP3333_String_GET_SIZE(u) PyUnicode_GET_LENGTH(u)
18 #define _PEP3333_String_Concat(u1, u2) PyUnicode_Concat(u1, u2)
1919
2020 #else
2121
22 #define _Bytes_AS_DATA(bytes) PyString_AS_STRING(bytes)
23 #define _Bytes_FromString(bytes) PyString_FromString(bytes)
24 #define _Bytes_FromStringAndSize(data, len) PyString_FromStringAndSize(data, len)
25 #define _Bytes_GET_SIZE(bytes) PyString_GET_SIZE(bytes)
26 #define _Bytes_Check(bytes) PyString_Check(bytes)
27 #define _Bytes_Resize(bytes, len) _PyString_Resize(bytes, len)
28 #define _BytesLatin1_FromUnicode(u) (Py_INCREF(u),u)
2922 #define _FromLong(n) PyInt_FromLong(n)
23 #define _PEP3333_Bytes_AS_DATA(bytes) PyString_AS_STRING(bytes)
24 #define _PEP3333_Bytes_FromString(bytes) PyString_FromString(bytes)
25 #define _PEP3333_Bytes_FromStringAndSize(data, len) PyString_FromStringAndSize(data, len)
26 #define _PEP3333_Bytes_GET_SIZE(bytes) PyString_GET_SIZE(bytes)
27 #define _PEP3333_Bytes_Check(bytes) PyString_Check(bytes)
28 #define _PEP3333_Bytes_Resize(bytes, len) _PyString_Resize(bytes, len)
29 #define _PEP3333_BytesLatin1_FromUnicode(u) (Py_INCREF(u),u)
30 #define _PEP3333_String_FromUTF8String(data) PyString_FromString(data) // Assume UTF8
31 #define _PEP3333_String_GET_SIZE(u) PyString_GET_SIZE(u)
3032
31 #define _UnicodeUTF8_FromString(data) PyString_FromString(data)
32 #define _UnicodeLatin1_FromString(name) PyString_FromString(name)
33 #define _Unicode_GET_SIZE(u) PyString_GET_SIZE(u)
34
35 static PyObject* _UnicodeLatin1_FromStringAndSize(const char* data, Py_ssize_t len)
33 static PyObject* _PEP3333_String_FromLatin1StringAndSize(const char* data, Py_ssize_t len)
3634 {
3735 PyObject* tmp = PyUnicode_DecodeLatin1(data, len, "replace");
3836 if (tmp == NULL) {
4341 return tmp2;
4442 }
4543
46 static PyObject *_Unicode_Concat(PyObject *l, PyObject *r)
44 static PyObject *_PEP3333_String_Concat(PyObject *l, PyObject *r)
4745 {
4846 PyObject *ret = l;
4947
1818 #endif
1919 request->server_info = server_info;
2020 request->client_fd = client_fd;
21 request->client_addr = _UnicodeUTF8_FromString(client_addr);
21 request->client_addr = _PEP3333_String_FromUTF8String(client_addr);
2222 http_parser_init((http_parser*)&request->parser, HTTP_REQUEST);
2323 request->parser.parser.data = request;
2424 Request_reset(request);
9292
9393 static void
9494 _set_or_append_header(PyObject* headers, PyObject* k, const char* val, size_t len) {
95 PyObject *py_val = _UnicodeLatin1_FromStringAndSize(val, len);
95 PyObject *py_val = _PEP3333_String_FromLatin1StringAndSize(val, len);
9696 PyObject *py_val_old = PyDict_GetItem(headers, k);
9797
9898 if (py_val_old) {
99 PyObject *py_val_new = _Unicode_Concat(py_val_old, py_val);
99 PyObject *py_val_new = _PEP3333_String_Concat(py_val_old, py_val);
100100 PyDict_SetItem(headers, k, py_val_new);
101101 Py_DECREF(py_val_new);
102102 } else {
164164
165165 /* Append field name to the part we got from previous call */
166166 PyObject *field_old = PARSER->field;
167 PyObject *field_new = _UnicodeLatin1_FromStringAndSize(field_processed, len);
168 PARSER->field = _Unicode_Concat(field_old, field_new);
167 PyObject *field_new = _PEP3333_String_FromLatin1StringAndSize(field_processed, len);
168 PARSER->field = _PEP3333_String_Concat(field_old, field_new);
169169 Py_DECREF(field_old);
170170 Py_DECREF(field_new);
171171
200200 }
201201 _set_header_free_value(_wsgi_input, body);
202202 }
203 PyObject *temp_data = _Bytes_FromStringAndSize(data, len);
203 PyObject *temp_data = _PEP3333_Bytes_FromStringAndSize(data, len);
204204 PyObject *tmp = PyObject_CallMethodObjArgs(body, _write, temp_data, NULL);
205205 Py_DECREF(tmp); /* Never throw away return objects from py-api */
206206 Py_DECREF(temp_data);
223223 _set_header(_REQUEST_METHOD, _GET);
224224 } else {
225225 _set_header_free_value(_REQUEST_METHOD,
226 _UnicodeUTF8_FromString(http_method_str(parser->method))
226 _PEP3333_String_FromUTF8String(http_method_str(parser->method))
227227 );
228228 }
229229
181181 /* HTTP parse error */
182182 read_state = done;
183183 DBG_REQ(request, "Parse error");
184 request->current_chunk = _Bytes_FromString(
184 request->current_chunk = _PEP3333_Bytes_FromString(
185185 http_error_messages[request->state.error_code]);
186186 assert(request->iterator == NULL);
187187 } else if(request->state.parse_finished) {
195195 PyErr_Print();
196196 assert(!request->state.chunked_response);
197197 Py_XCLEAR(request->iterator);
198 request->current_chunk = _Bytes_FromString(
198 request->current_chunk = _PEP3333_Bytes_FromString(
199199 http_error_messages[HTTP_SERVER_ERROR]);
200200 }
201201 } else {
355355 send_terminator_chunk:
356356 if(request->state.chunked_response) {
357357 /* We have to send a terminating empty chunk + \r\n */
358 request->current_chunk = _Bytes_FromString("0\r\n\r\n");
358 request->current_chunk = _PEP3333_Bytes_FromString("0\r\n\r\n");
359359 assert(request->current_chunk_p == 0);
360360 // Next time we get here, don't send the terminating empty chunk again.
361361 // XXX This is kind of a hack and should be refactored for easier understanding.
373373 Py_ssize_t bytes_sent;
374374
375375 assert(request->current_chunk != NULL);
376 assert(!(request->current_chunk_p == _Bytes_GET_SIZE(request->current_chunk)
377 && _Bytes_GET_SIZE(request->current_chunk) != 0));
376 assert(!(request->current_chunk_p == _PEP3333_Bytes_GET_SIZE(request->current_chunk)
377 && _PEP3333_Bytes_GET_SIZE(request->current_chunk) != 0));
378378
379379 bytes_sent = write(
380380 request->client_fd,
381 _Bytes_AS_DATA(request->current_chunk) + request->current_chunk_p,
382 _Bytes_GET_SIZE(request->current_chunk) - request->current_chunk_p
381 _PEP3333_Bytes_AS_DATA(request->current_chunk) + request->current_chunk_p,
382 _PEP3333_Bytes_GET_SIZE(request->current_chunk) - request->current_chunk_p
383383 );
384384
385385 if(bytes_sent == -1)
386386 return handle_nonzero_errno(request);
387387
388388 request->current_chunk_p += bytes_sent;
389 if(request->current_chunk_p == _Bytes_GET_SIZE(request->current_chunk)) {
389 if(request->current_chunk_p == _PEP3333_Bytes_GET_SIZE(request->current_chunk)) {
390390 Py_CLEAR(request->current_chunk);
391391 request->current_chunk_p = 0;
392392 return false;
6262 PyObject* first_chunk;
6363
6464 if(PyList_Check(retval) && PyList_GET_SIZE(retval) == 1 &&
65 _Bytes_Check(PyList_GET_ITEM(retval, 0)))
65 _PEP3333_Bytes_Check(PyList_GET_ITEM(retval, 0)))
6666 {
6767 /* Optimize the most common case, a single string in a list: */
6868 PyObject* tmp = PyList_GET_ITEM(retval, 0);
7070 Py_DECREF(retval);
7171 retval = tmp;
7272 goto string; /* eeevil */
73 } else if(_Bytes_Check(retval)) {
73 } else if(_PEP3333_Bytes_Check(retval)) {
7474 /* According to PEP 333 strings should be handled like any other iterable,
7575 * i.e. sending the response item for item. "item for item" means
7676 * "char for char" if you have a string. -- I'm not that stupid. */
7777 string:
78 if(_Bytes_GET_SIZE(retval)) {
78 if(_PEP3333_Bytes_GET_SIZE(retval)) {
7979 first_chunk = retval;
8080 } else {
8181 Py_DECREF(retval);
140140 wsgi_getheaders(request, &buf, &length);
141141
142142 if(first_chunk == NULL) {
143 _Bytes_Resize(&buf, length);
143 _PEP3333_Bytes_Resize(&buf, length);
144144 goto out;
145145 }
146146
147147 if(request->state.chunked_response) {
148148 PyObject* new_chunk = wrap_http_chunk_cruft_around(first_chunk);
149149 Py_DECREF(first_chunk);
150 assert(_Bytes_GET_SIZE(new_chunk) >= _Bytes_GET_SIZE(first_chunk) + 5);
150 assert(_PEP3333_Bytes_GET_SIZE(new_chunk) >= _PEP3333_Bytes_GET_SIZE(first_chunk) + 5);
151151 first_chunk = new_chunk;
152152 }
153153
154 _Bytes_Resize(&buf, length + _Bytes_GET_SIZE(first_chunk));
155 memcpy((void *)(_Bytes_AS_DATA(buf)+length), _Bytes_AS_DATA(first_chunk),
156 _Bytes_GET_SIZE(first_chunk));
154 _PEP3333_Bytes_Resize(&buf, length + _PEP3333_Bytes_GET_SIZE(first_chunk));
155 memcpy((void *)(_PEP3333_Bytes_AS_DATA(buf)+length), _PEP3333_Bytes_AS_DATA(first_chunk),
156 _PEP3333_Bytes_GET_SIZE(first_chunk));
157157 Py_DECREF(first_chunk);
158158
159159 out:
183183 PyObject* unicode_field = PyTuple_GET_ITEM(tuple, 0);
184184 PyObject* unicode_value = PyTuple_GET_ITEM(tuple, 1);
185185
186 PyObject* bytes_field = _BytesLatin1_FromUnicode(unicode_field);
187 PyObject* bytes_value = _BytesLatin1_FromUnicode(unicode_value);
186 PyObject* bytes_field = _PEP3333_BytesLatin1_FromUnicode(unicode_field);
187 PyObject* bytes_value = _PEP3333_BytesLatin1_FromUnicode(unicode_value);
188188
189189 if (bytes_field == NULL || bytes_value == NULL) {
190190 Py_XDECREF(bytes_field);
195195 PyList_SET_ITEM(request->headers, i, PyTuple_Pack(2, bytes_field, bytes_value));
196196 Py_DECREF(tuple);
197197
198 if(!strncasecmp(_Bytes_AS_DATA(bytes_field), "Content-Length", _Bytes_GET_SIZE(bytes_field)))
198 if(!strncasecmp(_PEP3333_Bytes_AS_DATA(bytes_field), "Content-Length", _PEP3333_Bytes_GET_SIZE(bytes_field)))
199199 request->state.response_length_unknown = false;
200200
201201 Py_DECREF(bytes_field);
213213 static void
214214 wsgi_getheaders(Request* request, PyObject** buf, Py_ssize_t *length)
215215 {
216 Py_ssize_t length_upperbound = strlen("HTTP/1.1 ") + _Bytes_GET_SIZE(request->status) + strlen("\r\nConnection: Keep-Alive") + strlen("\r\nTransfer-Encoding: chunked") + strlen("\r\n\r\n");
216 Py_ssize_t length_upperbound = strlen("HTTP/1.1 ") + _PEP3333_Bytes_GET_SIZE(request->status) + strlen("\r\nConnection: Keep-Alive") + strlen("\r\nTransfer-Encoding: chunked") + strlen("\r\n\r\n");
217217 for(Py_ssize_t i=0; i<PyList_GET_SIZE(request->headers); ++i) {
218218 PyObject* tuple = PyList_GET_ITEM(request->headers, i);
219219 PyObject* field = PyTuple_GET_ITEM(tuple, 0);
220220 PyObject* value = PyTuple_GET_ITEM(tuple, 1);
221 length_upperbound += strlen("\r\n") + _Bytes_GET_SIZE(field) + strlen(": ") + _Bytes_GET_SIZE(value);
222 }
223
224 PyObject* bufobj = _Bytes_FromStringAndSize(NULL, length_upperbound);
225 char* bufp = (char *)_Bytes_AS_DATA(bufobj);
221 length_upperbound += strlen("\r\n") + _PEP3333_Bytes_GET_SIZE(field) + strlen(": ") + _PEP3333_Bytes_GET_SIZE(value);
222 }
223
224 PyObject* bufobj = _PEP3333_Bytes_FromStringAndSize(NULL, length_upperbound);
225 char* bufp = (char *)_PEP3333_Bytes_AS_DATA(bufobj);
226226
227227 #define buf_write(src, len) \
228228 do { \
234234
235235 /* First line, e.g. "HTTP/1.1 200 Ok" */
236236 buf_write2("HTTP/1.1 ");
237 buf_write(_Bytes_AS_DATA(request->status),
238 _Bytes_GET_SIZE(request->status));
237 buf_write(_PEP3333_Bytes_AS_DATA(request->status),
238 _PEP3333_Bytes_GET_SIZE(request->status));
239239
240240 /* Headers, from the `request->headers` mapping.
241241 * [("Header1", "value1"), ("Header2", "value2")]
246246 PyObject* field = PyTuple_GET_ITEM(tuple, 0);
247247 PyObject* value = PyTuple_GET_ITEM(tuple, 1);
248248 buf_write2("\r\n");
249 buf_write(_Bytes_AS_DATA(field), _Bytes_GET_SIZE(field));
249 buf_write(_PEP3333_Bytes_AS_DATA(field), _PEP3333_Bytes_GET_SIZE(field));
250250 buf_write2(": ");
251 buf_write(_Bytes_AS_DATA(value), _Bytes_GET_SIZE(value));
251 buf_write(_PEP3333_Bytes_AS_DATA(value), _PEP3333_Bytes_GET_SIZE(value));
252252 }
253253
254254 /* See `wsgi_call_application` */
264264 buf_write2("\r\n\r\n");
265265
266266 *buf = bufobj;
267 *length = bufp - _Bytes_AS_DATA(bufobj);
267 *length = bufp - _PEP3333_Bytes_AS_DATA(bufobj);
268268 }
269269
270270 inline PyObject*
276276 next = PyIter_Next(request->iterator);
277277 if(next == NULL)
278278 return NULL;
279 if(!_Bytes_Check(next)) {
279 if(!_PEP3333_Bytes_Check(next)) {
280280 TYPE_ERROR("wsgi iterable items", "bytes", next);
281281 Py_DECREF(next);
282282 return NULL;
283283 }
284 if(_Bytes_GET_SIZE(next))
284 if(_PEP3333_Bytes_GET_SIZE(next))
285285 return next;
286286 Py_DECREF(next);
287287 }
344344 return NULL;
345345 }
346346
347 request->status = _BytesLatin1_FromUnicode(status_unicode);
347 request->status = _PEP3333_BytesLatin1_FromUnicode(status_unicode);
348348 if (request->status == NULL) {
349349 return NULL;
350350 }
378378 {
379379 /* Who the hell decided to use decimal representation for Content-Length
380380 * but hexadecimal representation for chunk lengths btw!?! Fuck W3C */
381 size_t chunklen = _Bytes_GET_SIZE(chunk);
381 size_t chunklen = _PEP3333_Bytes_GET_SIZE(chunk);
382382 assert(chunklen);
383383 char buf[strlen("ffffffff") + 2];
384384 size_t n = sprintf(buf, "%x\r\n", (unsigned int)chunklen);
385 PyObject* new_chunk = _Bytes_FromStringAndSize(NULL, n + chunklen + 2);
386 char * new_chunk_p = (char *)_Bytes_AS_DATA(new_chunk);
385 PyObject* new_chunk = _PEP3333_Bytes_FromStringAndSize(NULL, n + chunklen + 2);
386 char * new_chunk_p = (char *)_PEP3333_Bytes_AS_DATA(new_chunk);
387387 memcpy(new_chunk_p, buf, n);
388388 new_chunk_p += n;
389 memcpy(new_chunk_p, _Bytes_AS_DATA(chunk), chunklen);
389 memcpy(new_chunk_p, _PEP3333_Bytes_AS_DATA(chunk), chunklen);
390390 new_chunk_p += chunklen;
391391 *new_chunk_p++ = '\r'; *new_chunk_p = '\n';
392 assert(new_chunk_p == _Bytes_AS_DATA(new_chunk) + n + chunklen + 1);
392 assert(new_chunk_p == _PEP3333_Bytes_AS_DATA(new_chunk) + n + chunklen + 1);
393393 return new_chunk;
394394 }