nxt_python_asgi_http.c (1624:e46b1b422545) nxt_python_asgi_http.c (1681:542b5b8c0647)
1
2/*
3 * Copyright (C) NGINX, Inc.
4 */
5
6
7#include <python/nxt_python.h>
8

--- 53 unchanged lines hidden (view full) ---

62 .tp_iter = nxt_py_asgi_iter,
63 .tp_iternext = nxt_py_asgi_next,
64 .tp_methods = nxt_py_asgi_http_methods,
65};
66
67static Py_ssize_t nxt_py_asgi_http_body_buf_size = 32 * 1024 * 1024;
68
69
1
2/*
3 * Copyright (C) NGINX, Inc.
4 */
5
6
7#include <python/nxt_python.h>
8

--- 53 unchanged lines hidden (view full) ---

62 .tp_iter = nxt_py_asgi_iter,
63 .tp_iternext = nxt_py_asgi_next,
64 .tp_methods = nxt_py_asgi_http_methods,
65};
66
67static Py_ssize_t nxt_py_asgi_http_body_buf_size = 32 * 1024 * 1024;
68
69
70nxt_int_t
71nxt_py_asgi_http_init(nxt_task_t *task)
70int
71nxt_py_asgi_http_init(void)
72{
73 if (nxt_slow_path(PyType_Ready(&nxt_py_asgi_http_type) != 0)) {
72{
73 if (nxt_slow_path(PyType_Ready(&nxt_py_asgi_http_type) != 0)) {
74 nxt_alert(task, "Python failed to initialize the 'http' type object");
75 return NXT_ERROR;
74 nxt_unit_alert(NULL,
75 "Python failed to initialize the 'http' type object");
76 return NXT_UNIT_ERROR;
76 }
77
77 }
78
78 return NXT_OK;
79 return NXT_UNIT_OK;
79}
80
81
82PyObject *
83nxt_py_asgi_http_create(nxt_unit_request_info_t *req)
84{
85 nxt_py_asgi_http_t *http;
86

--- 14 unchanged lines hidden (view full) ---

101}
102
103
104static PyObject *
105nxt_py_asgi_http_receive(PyObject *self, PyObject *none)
106{
107 PyObject *msg, *future;
108 nxt_py_asgi_http_t *http;
80}
81
82
83PyObject *
84nxt_py_asgi_http_create(nxt_unit_request_info_t *req)
85{
86 nxt_py_asgi_http_t *http;
87

--- 14 unchanged lines hidden (view full) ---

102}
103
104
105static PyObject *
106nxt_py_asgi_http_receive(PyObject *self, PyObject *none)
107{
108 PyObject *msg, *future;
109 nxt_py_asgi_http_t *http;
110 nxt_py_asgi_ctx_data_t *ctx_data;
109 nxt_unit_request_info_t *req;
110
111 http = (nxt_py_asgi_http_t *) self;
112 req = http->req;
113
114 nxt_unit_req_debug(req, "asgi_http_receive");
115
116 msg = nxt_py_asgi_http_read_msg(http);
117 if (nxt_slow_path(msg == NULL)) {
118 return NULL;
119 }
120
111 nxt_unit_request_info_t *req;
112
113 http = (nxt_py_asgi_http_t *) self;
114 req = http->req;
115
116 nxt_unit_req_debug(req, "asgi_http_receive");
117
118 msg = nxt_py_asgi_http_read_msg(http);
119 if (nxt_slow_path(msg == NULL)) {
120 return NULL;
121 }
122
121 future = PyObject_CallObject(nxt_py_loop_create_future, NULL);
123 ctx_data = req->ctx->data;
124
125 future = PyObject_CallObject(ctx_data->loop_create_future, NULL);
122 if (nxt_slow_path(future == NULL)) {
123 nxt_unit_req_alert(req, "Python failed to create Future object");
124 nxt_python_print_exception();
125
126 Py_DECREF(msg);
127
128 return PyErr_Format(PyExc_RuntimeError,
129 "failed to create Future object");
130 }
131
132 if (msg != Py_None) {
126 if (nxt_slow_path(future == NULL)) {
127 nxt_unit_req_alert(req, "Python failed to create Future object");
128 nxt_python_print_exception();
129
130 Py_DECREF(msg);
131
132 return PyErr_Format(PyExc_RuntimeError,
133 "failed to create Future object");
134 }
135
136 if (msg != Py_None) {
133 return nxt_py_asgi_set_result_soon(req, future, msg);
137 return nxt_py_asgi_set_result_soon(req, ctx_data, future, msg);
134 }
135
136 http->receive_future = future;
137 Py_INCREF(http->receive_future);
138
139 Py_DECREF(msg);
140
141 return future;

--- 182 unchanged lines hidden (view full) ---

324 Py_INCREF(http);
325 return (PyObject *) http;
326}
327
328
329static PyObject *
330nxt_py_asgi_http_response_body(nxt_py_asgi_http_t *http, PyObject *dict)
331{
138 }
139
140 http->receive_future = future;
141 Py_INCREF(http->receive_future);
142
143 Py_DECREF(msg);
144
145 return future;

--- 182 unchanged lines hidden (view full) ---

328 Py_INCREF(http);
329 return (PyObject *) http;
330}
331
332
333static PyObject *
334nxt_py_asgi_http_response_body(nxt_py_asgi_http_t *http, PyObject *dict)
335{
332 int rc;
333 char *body_str;
334 ssize_t sent;
335 PyObject *body, *more_body, *future;
336 Py_ssize_t body_len, body_off;
336 int rc;
337 char *body_str;
338 ssize_t sent;
339 PyObject *body, *more_body, *future;
340 Py_ssize_t body_len, body_off;
341 nxt_py_asgi_ctx_data_t *ctx_data;
337
338 body = PyDict_GetItem(dict, nxt_py_body_str);
339 if (nxt_slow_path(body != NULL && !PyBytes_Check(body))) {
340 return PyErr_Format(PyExc_TypeError, "'body' is not a byte string");
341 }
342
343 more_body = PyDict_GetItem(dict, nxt_py_more_body_str);
344 if (nxt_slow_path(more_body != NULL && !PyBool_Check(more_body))) {

--- 21 unchanged lines hidden (view full) ---

366 > http->content_length))
367 {
368 return PyErr_Format(PyExc_RuntimeError,
369 "Response content longer than Content-Length");
370 }
371
372 body_off = 0;
373
342
343 body = PyDict_GetItem(dict, nxt_py_body_str);
344 if (nxt_slow_path(body != NULL && !PyBytes_Check(body))) {
345 return PyErr_Format(PyExc_TypeError, "'body' is not a byte string");
346 }
347
348 more_body = PyDict_GetItem(dict, nxt_py_more_body_str);
349 if (nxt_slow_path(more_body != NULL && !PyBool_Check(more_body))) {

--- 21 unchanged lines hidden (view full) ---

371 > http->content_length))
372 {
373 return PyErr_Format(PyExc_RuntimeError,
374 "Response content longer than Content-Length");
375 }
376
377 body_off = 0;
378
379 ctx_data = http->req->ctx->data;
380
374 while (body_len > 0) {
375 sent = nxt_unit_response_write_nb(http->req, body_str, body_len, 0);
376 if (nxt_slow_path(sent < 0)) {
377 return PyErr_Format(PyExc_RuntimeError, "failed to send body");
378 }
379
380 if (nxt_slow_path(sent == 0)) {
381 nxt_unit_req_debug(http->req, "asgi_http_response_body: "
382 "out of shared memory, %d",
383 (int) body_len);
384
381 while (body_len > 0) {
382 sent = nxt_unit_response_write_nb(http->req, body_str, body_len, 0);
383 if (nxt_slow_path(sent < 0)) {
384 return PyErr_Format(PyExc_RuntimeError, "failed to send body");
385 }
386
387 if (nxt_slow_path(sent == 0)) {
388 nxt_unit_req_debug(http->req, "asgi_http_response_body: "
389 "out of shared memory, %d",
390 (int) body_len);
391
385 future = PyObject_CallObject(nxt_py_loop_create_future, NULL);
392 future = PyObject_CallObject(ctx_data->loop_create_future,
393 NULL);
386 if (nxt_slow_path(future == NULL)) {
387 nxt_unit_req_alert(http->req,
388 "Python failed to create Future object");
389 nxt_python_print_exception();
390
391 return PyErr_Format(PyExc_RuntimeError,
392 "failed to create Future object");
393 }
394
395 http->send_body = body;
396 Py_INCREF(http->send_body);
397 http->send_body_off = body_off;
398
394 if (nxt_slow_path(future == NULL)) {
395 nxt_unit_req_alert(http->req,
396 "Python failed to create Future object");
397 nxt_python_print_exception();
398
399 return PyErr_Format(PyExc_RuntimeError,
400 "failed to create Future object");
401 }
402
403 http->send_body = body;
404 Py_INCREF(http->send_body);
405 http->send_body_off = body_off;
406
399 nxt_queue_insert_tail(&nxt_py_asgi_drain_queue, &http->link);
407 nxt_py_asgi_drain_wait(http->req, &http->link);
400
401 http->send_future = future;
402 Py_INCREF(http->send_future);
403
404 return future;
405 }
406
407 body_str += sent;

--- 184 unchanged lines hidden ---
408
409 http->send_future = future;
410 Py_INCREF(http->send_future);
411
412 return future;
413 }
414
415 body_str += sent;

--- 184 unchanged lines hidden ---