File: //proc/thread-self/root/usr/local/lsws/fcgi-bin/wsgi-lsapi-2.1/wsgiwrapper.c
/*-
* Copyright (c) 2006 Allan Saddi <allan@saddi.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
*/
#include <Python.h>
#include "wsgi-int.h"
static void FileWrapper_dealloc ( FileWrapper *self )
{
PyObject *tmp;
tmp = ( PyObject * ) self->filelike;
self->filelike = NULL;
Py_XDECREF ( tmp );
Py_TYPE(self)->tp_free ( ( PyObject * ) self );
}
static PyObject *FileWrapper_new ( PyTypeObject *type, PyObject *args, PyObject *kwds )
{
FileWrapper *self;
self = ( FileWrapper * ) type->tp_alloc ( type, 0 );
if ( self != NULL )
{
self->filelike = NULL;
}
return ( PyObject * ) self;
}
static int FileWrapper_init ( FileWrapper *self, PyObject *args, PyObject *kwds )
{
PyObject *filelike;
int blocksize = 4096;
if ( !PyArg_ParseTuple ( args, "O|i", &filelike, &blocksize ) )
return -1;
Py_INCREF ( filelike );
self->filelike = filelike;
self->blocksize = blocksize;
return 0;
}
/* __iter__() implementation. Simply returns self. */
static PyObject *FileWrapper_iter ( FileWrapper *self )
{
Py_INCREF ( self );
return ( PyObject * ) self;
}
/* next() implementation for iteration protocol support. Calls read()
on the file-like and emits strings according to the blocksize.
This is only used for compatibility (the normal path uses
wsgiSendFile()). */
static PyObject *FileWrapper_iternext ( FileWrapper *self )
{
PyObject *pRead, *args, *data;
int len;
if ( ( pRead = PyObject_GetAttrString ( self->filelike, "read" ) ) == NULL )
return NULL;
if ( ( args = Py_BuildValue ( "(i)", self->blocksize ) ) == NULL )
{
Py_DECREF ( pRead );
return NULL;
}
data = PyObject_CallObject ( pRead, args );
Py_DECREF ( args );
Py_DECREF ( pRead );
if ( data == NULL )
return NULL;
len = PyBytes_Size ( data );
if ( PyErr_Occurred() )
{
Py_DECREF ( data );
return NULL;
}
if ( len == 0 )
{
Py_DECREF ( data );
PyErr_Clear();
return NULL;
}
return data;
}
/* Calls the file-like's close() method, if present. */
static PyObject *FileWrapper_close ( FileWrapper *self, PyObject *args )
{
PyObject *pClose, *args2, *result;
if ( PyObject_HasAttrString ( self->filelike, "close" ) )
{
if ( ( pClose = PyObject_GetAttrString ( self->filelike, "close" ) ) == NULL )
return NULL;
if ( ( args2 = PyTuple_New ( 0 ) ) == NULL )
{
Py_DECREF ( pClose );
return NULL;
}
result = PyObject_CallObject ( pClose, args2 );
Py_DECREF ( args2 );
Py_DECREF ( pClose );
if ( result == NULL )
return NULL;
}
Py_INCREF ( Py_None );
return Py_None;
}
static PyMethodDef FileWrapper_methods[] =
{
{ "close", ( PyCFunction ) FileWrapper_close, METH_VARARGS,
"Calls the file-like object's close method" },
{ NULL }
};
#if PY_MAJOR_VERSION >=3
# define Py_TPFLAGS_HAVE_ITER 0
#endif
PyTypeObject FileWrapper_Type =
{
PyVarObject_HEAD_INIT(NULL, 0)
"lsapi_wsgi.FileWrapper", /*tp_name*/
sizeof ( FileWrapper ), /*tp_basicsize*/
0, /*tp_itemsize*/
( destructor ) FileWrapper_dealloc, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, /*tp_flags*/
"wsgi.file_wrapper implementation", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
( getiterfunc ) FileWrapper_iter, /* tp_iter */
( iternextfunc ) FileWrapper_iternext, /* tp_iternext */
FileWrapper_methods, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
( initproc ) FileWrapper_init, /* tp_init */
0, /* tp_alloc */
FileWrapper_new, /* tp_new */
};