0
* License. See README file for details.
0
+#define PyDict_SetStringString(dict, str1, str2) PyDict_SetItemString(dict, str1, PyString_FromString(str2))
0
+#define ASCII_UPPER(ch) ('a' <= ch && ch <= 'z' ? ch - 'a' + 'A' : ch)
0
+/* Why is there a global ebb_server variable instead of a wrapping it in a
0
+ * class? Because you would for no conceivable reason want to run more than
0
+ * one ebb_server per python VM instance.
0
+static ebb_server server;
0
+struct ev_loop *loop = NULL;
0
+static PyObject *application = NULL;
0
+static PyObject *base_env = NULL;
0
+static PyObject *global_http_prefix;
0
+static PyObject *global_request_method;
0
+static PyObject *global_request_uri;
0
+static PyObject *global_fragment;
0
+static PyObject *global_request_path;
0
+static PyObject *global_query_string;
0
+static PyObject *global_http_version;
0
+static PyObject *global_request_body;
0
+static PyObject *global_server_name;
0
+static PyObject *global_server_port;
0
+static PyObject *global_path_info;
0
+static PyObject *global_content_length;
0
+static PyObject *global_http_host;
0
+/* A callable type called Client. __call__(status, response_headers)
0
+ * is the second argument to an appplcation
0
+ * Client.environ is the first argument.
0
+static PyObject* env_field(struct ebb_env_item *item)
0
+ case EBB_FIELD_VALUE_PAIR:
0
+ f = PyString_FromStringAndSize(NULL, PyString_GET_SIZE(global_http_prefix) + item->field_length);
0
+ memcpy( PyString_AS_STRING(f)
0
+ , PyString_AS_STRING(global_http_prefix)
0
+ , PyString_GET_SIZE(global_http_prefix)
0
+ for(i = 0; i < item->field_length; i++) {
0
+ char *ch = PyString_AS_STRING(f) + PyString_GET_SIZE(global_http_prefix) + i;
0
+ *ch = item->field[i] == '-' ? '_' : ASCII_UPPER(item->field[i]);
0
+ case EBB_REQUEST_METHOD: f = global_request_method; break;
0
+ case EBB_REQUEST_URI: f = global_request_uri; break;
0
+ case EBB_FRAGMENT: f = global_fragment; break;
0
+ case EBB_REQUEST_PATH: f = global_request_path; break;
0
+ case EBB_QUERY_STRING: f = global_query_string; break;
0
+ case EBB_HTTP_VERSION: f = global_http_version; break;
0
+ case EBB_SERVER_NAME: f = global_server_name; break;
0
+ case EBB_SERVER_PORT: f = global_server_port; break;
0
+ case EBB_CONTENT_LENGTH: f = global_content_length; break;
0
+ default: assert(FALSE);
0
+static PyObject* env_value(struct ebb_env_item *item)
0
+ if(item->value_length > 0)
0
+ return PyString_FromStringAndSize(item->value, item->value_length);
0
+ return Py_None; // XXX need to increase ref count? :/
0
+static PyObject* client_env(ebb_client *client)
0
+ PyObject *env = PyDict_Copy(base_env);
0
+ for(i=0; i < client->env_size; i++) {
0
+ PyDict_SetItem(env, env_field(&client->env[i])
0
+ , env_value(&client->env[i])
0
+ // PyDict_SetStringString(hash, global_path_info, rb_hash_aref(hash, global_request_path));
0
-Server_dealloc(Server* self)
0
+const char *test_response = "Hello World!\r\n";
0
+void request_cb(ebb_client *client, void *ignore)
0
- ebb_server_free(self->server);
0
- self->ob_type->tp_free((PyObject*)self);
0
+ PyObject *env = client_env(client);
0
+ PyObject *start_response = Py_None;
0
+ printf("hello world\n");
0
+ arglist = Py_BuildValue("OO", env, start_response);
0
+ result = PyEval_CallObject(application, arglist);
0
+ ebb_client_write(client, test_response, strlen(test_response));
0
+ ebb_client_finished(client);
0
+ printf("finished calling\n");
0
-static PyMethodDef Server_methods[] = {
0
- {"name", (PyCFunction)Noddy_name, METH_NOARGS,
0
- "Return the name, combining the first and last name"
0
-static PyTypeObject ServerType = {
0
- PyObject_HEAD_INIT(NULL)
0
- "ebb.Server", /*tp_name*/
0
- sizeof(Server), /*tp_basicsize*/
0
- (destructor)Server_dealloc, /*tp_dealloc*/
0
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
0
- "Ebb Server", /* tp_doc */
0
- 0, /* tp_richcompare */
0
- 0, /* tp_weaklistoffset */
0
- Server_methods, /* tp_methods */
0
- 0, /* tp_dictoffset */
0
- (initproc)Server_init, /* tp_init */
0
- Server_alloc, /* tp_alloc */
0
- Server_new, /* tp_new */
0
+static PyObject *start_server(PyObject *self, PyObject *args)
0
+ PyObject *application_temp;
0
+ if(!PyArg_ParseTuple(args, "Oi", &application_temp, &port))
0
+ if(!PyCallable_Check(application_temp)) {
0
+ PyErr_SetString(PyExc_TypeError, "parameter must be callable");
0
+ Py_XINCREF(application_temp); /* Add a reference to new callback */
0
+ Py_XDECREF(application); /* Dispose of previous callback */
0
+ application = application_temp; /* Remember new callback */
0
+ loop = ev_default_loop(0);
0
+ ebb_server_init(&server, loop, request_cb, NULL);
0
+ ebb_server_listen_on_port(&server, port);
0
+ //ev_loop(loop, EVLOOP_ONESHOT);
0
+ Py_XDECREF(application);
0
+static PyObject *stop_server(PyObject *self)
0
- PyObject *m, *d, *tmp;
0
- ServerType.ob_type = &PyType_Type;
0
- m = Py_InitModule("Ebb", GeoIP_Class_methods);
0
- d = PyModule_GetDict(m);
0
+static PyMethodDef Ebb_methods[] =
0
+ { {"start_server" , (PyCFunction)start_server, METH_VARARGS,
0
+ "Listen on port supplied. Start the server event loop." }
0
+ , {"stop_server" , (PyCFunction)stop_server, METH_NOARGS,
0
+ , {NULL, NULL, 0, NULL}
0
- tmp = PyInt_FromLong(0);
0
- PyDict_SetItemString(d, "GEOIP_STANDARD", tmp);
0
+PyMODINIT_FUNC initebb(void)
0
+ ebb_server_init(&server, loop, request_cb, NULL);
0
+ m = Py_InitModule("ebb", Ebb_methods);
0
- tmp = PyInt_FromLong(1);
0
- PyDict_SetItemString(d, "GEOIP_MEMORY_CACHE", tmp);
0
+ base_env = PyDict_New();
0
+ PyDict_SetStringString(base_env, "SCRIPT_NAME", "");
0
+ PyDict_SetStringString(base_env, "SERVER_SOFTWARE", "Ebb 0.0.4");
0
+ PyDict_SetStringString(base_env, "SERVER_PROTOCOL", "HTTP/1.1");
0
+ PyDict_SetStringString(base_env, "wsgi.url_scheme", "http");
0
+ PyDict_SetItemString(base_env, "wsgi.multithread", Py_False);
0
+ PyDict_SetItemString(base_env, "wsgi.multiprocess", Py_False);
0
+ PyDict_SetItemString(base_env, "wsgi.run_once", Py_False);
0
+ //PyDict_SetItemString(base_env, "wsgi.version", (0,1));
0
+ //PyDict_SetItemString(base_env, "wsgi.errors", STDERR);
0
+#define DEF_GLOBAL(N, val) global_##N = PyString_FromString(val)
0
+ DEF_GLOBAL(http_prefix, "HTTP_");
0
+ DEF_GLOBAL(request_method, "REQUEST_METHOD");
0
+ DEF_GLOBAL(request_uri, "REQUEST_URI");
0
+ DEF_GLOBAL(fragment, "FRAGMENT");
0
+ DEF_GLOBAL(request_path, "REQUEST_PATH");
0
+ DEF_GLOBAL(query_string, "QUERY_STRING");
0
+ DEF_GLOBAL(http_version, "HTTP_VERSION");
0
+ DEF_GLOBAL(request_body, "REQUEST_BODY");
0
+ DEF_GLOBAL(server_name, "SERVER_NAME");
0
+ DEF_GLOBAL(server_port, "SERVER_PORT");
0
+ DEF_GLOBAL(path_info, "PATH_INFO");
0
+ DEF_GLOBAL(content_length, "CONTENT_LENGTH");
0
+ DEF_GLOBAL(http_host, "HTTP_HOST");
0
\ No newline at end of file
Comments
No one has commented yet.