Permalink
Browse files

merge master conflicts

  • Loading branch information...
2 parents 3a67399 + 36d268d commit 63315b8a1424a7bae43a28bd8825cb4e91b51508 @william-os4y committed Jan 29, 2012
Showing with 251 additions and 79 deletions.
  1. +12 −0 INSTALL
  2. +72 −33 fapws/_evwsgi.c
  3. +8 −8 fapws/mainloop.c
  4. +7 −3 fapws/wsgi.c
  5. +30 −0 sample/hello_unixsocket/hello_world.py
  6. +8 −2 setup.py
  7. +33 −0 tests/unittests/_raw_send.py
  8. +19 −3 tests/unittests/server.py
  9. +62 −30 tests/unittests/test.py
View
@@ -24,6 +24,18 @@ For MacOSX users
- Install MacPorts from http://www.macports.org/
- Run "sudo port install libev"
+
+ or
+
+ If you have homebrew build libev for multi-architecture:
+ $ brew edit libev
+ add:
+ ENV["CFLAGS"] = '-arch i386 -arch x86_64'
+ just above the line:
+ system "./configure", "--disable-dependency-tracking",
+ run
+ brew install libev
+
- than follow the Fapws3 installation process described here under
View
@@ -32,6 +32,7 @@
#include <sys/wait.h>
#include <signal.h>
#include <assert.h>
+#include <sys/un.h>
#include <ev.h>
@@ -47,6 +48,7 @@
Somme global variables
*/
char *server_name="127.0.0.1";
+int server_name_length;
char *server_port="8000";
int sockfd; // main sock_fd
int debug=0; //1 full debug detail: 0 nodebug
@@ -84,59 +86,82 @@ code copied from the nice book written by Bee:
int yes=1;
int rv;
- if (!PyArg_ParseTuple(args, "ss", &server_name, &server_port))
+ if (!PyArg_ParseTuple(args, "s#s", &server_name, &server_name_length, &server_port))
{
PyErr_SetString(ServerError, "Failed to parse the start parameters. Must be 2 strings.");
return NULL;
}
- memset(&hints, 0, sizeof hints);
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_flags = AI_PASSIVE; // use my IP
- if ((rv = getaddrinfo(server_name, server_port, &hints, &servinfo)) == -1) {
- PyErr_Format(ServerError, "getaddrinfo: %s", gai_strerror(rv));
- return NULL;
- }
-
- // loop through all the results and bind to the first we can
- for(p = servinfo; p != NULL; p = p->ai_next) {
- sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
- if (sockfd == -1) {
- perror("server: socket");
- continue;
+ if (strncmp(server_port, "unix", 4) != 0) {
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE; // use my IP
+ if ((rv = getaddrinfo(server_name, server_port, &hints, &servinfo)) == -1) {
+ PyErr_Format(ServerError, "getaddrinfo: %s", gai_strerror(rv));
+ return NULL;
}
- if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,
- sizeof(int)) == -1) {
- perror("setsockopt");
+ // loop through all the results and bind to the first we can
+ for(p = servinfo; p != NULL; p = p->ai_next) {
+ sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
+ if (sockfd == -1) {
+ perror("server: socket");
+ continue;
+ }
+
+ if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes,
+ sizeof(int)) == -1) {
+ perror("setsockopt");
+ }
+
+ if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
+ close(sockfd);
+ perror("server: bind");
+ continue;
+ }
+
+ break;
}
+
+ freeaddrinfo(servinfo); // all done with this structure
- if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
+ if (p == NULL) {
+ PyErr_SetString(ServerError, "server: failed to bind");
+ return NULL;
+ }
+
+ } else {
+ sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sockfd == -1) {
+ perror("server: socket");
+ PyErr_SetString(ServerError, "server: failed to create socket");
+ return NULL;
+ }
+
+ struct sockaddr_un sockun;
+ sockun.sun_family = AF_UNIX;
+ memcpy(sockun.sun_path, server_name, server_name_length);
+ /*if (sockun.sun_path[0] == '@')
+ sockun.sun_path[0] = '\0';*/
+ if (bind(sockfd, (struct sockaddr *) &sockun, server_name_length+2) == -1) {
close(sockfd);
perror("server: bind");
- continue;
+ PyErr_SetString(ServerError, "server: failed to bind");
+ return NULL;
}
-
- break;
- }
-
- freeaddrinfo(servinfo); // all done with this structure
-
- if (p == NULL) {
- PyErr_SetString(ServerError, "server: failed to bind");
- return NULL;
}
if (listen(sockfd, BACKLOG) == -1) {
PyErr_SetString(ServerError, "listen");
return NULL;
}
- printf("listen on %s:%s\n", server_name, server_port);
+ if (server_name[0] == 0)
+ printf("listen on @%s:unix\n", server_name+1);
+ else
+ printf("listen on %s:%s\n", server_name, server_port);
return Py_None;
}
-
-
/*
Procedure exposed in Python will generate and start the event loop
*/
@@ -188,6 +213,15 @@ static PyObject *py_run_loop(PyObject *self, PyObject *args)
}
/*
+Procedure exposed in Python to provide the sockfd
+*/
+static PyObject *py_socket_fd(PyObject *self, PyObject *args)
+{
+ PyObject *pyres = PyLong_FromLong(sockfd);
+ return pyres;
+}
+
+/*
Procedure exposed in Python to provide libev's ABI version
*/
static PyObject *py_libev_version(PyObject *self, PyObject *args)
@@ -228,6 +262,10 @@ static PyObject *py_add_wsgi_cb(PyObject *self, PyObject *args)
PyObject *py_tuple;
if (!PyArg_ParseTuple(args, "O", &py_tuple))
return NULL;
+ if (py_registered_uri == NULL) {
+ PyErr_SetString(ServerError, "Base module not set");
+ return NULL;
+ }
PyList_Append(py_registered_uri, py_tuple);
return Py_None;
}
@@ -432,6 +470,7 @@ static PyMethodDef evwsgiMethods[] = {
{"defer", py_defer, METH_VARARGS, "defer the execution of a python function."},
{"defer_queue_size", py_defer_queue_size, METH_VARARGS, "Get the size of the defer queue"},
{"rfc1123_date", py_rfc1123_date, METH_VARARGS, "trasnform a time (in sec) into a string compatible with the rfc1123"},
+ {"socket_fd", py_socket_fd, METH_VARARGS, "Return the server socket's file descriptor"},
{NULL, NULL, 0, NULL} /* Sentinel */
};
View
@@ -24,17 +24,17 @@
#include "mainloop.h"
#include "compat.h"
-int debug;
-PyObject *pydeferqueue;
-PyObject *py_base_module; //to store the fapws.base python module
-PyObject *py_config_module; //to store the fapws.config module
-PyObject *py_registered_uri; //list containing the uri registered and their associated wsgi callback.
+extern int debug;
+extern PyObject *pydeferqueue;
+extern PyObject *py_base_module; //to store the fapws.base python module
+extern PyObject *py_config_module; //to store the fapws.config module
+extern PyObject *py_registered_uri; //list containing the uri registered and their associated wsgi callback.
#define MAX_BUFF 32768 //read buffer size. bigger faster, but memory foot print bigger
#define MAX_RETRY 9 //number of connection retry
-char * VERSION;
-PyObject *py_generic_cb;
-char * date_format;
+extern char * VERSION;
+extern PyObject *py_generic_cb;
+extern char * date_format;
View
@@ -10,9 +10,9 @@
#include "wsgi.h"
#include "compat.h"
-char *server_name;
-char *server_port;
-int debug;
+extern char *server_name;
+extern char *server_port;
+extern int debug;
/*
This procdure analyse uri and return a Python dictionary with every parameters as keys and their associated values into a list.
@@ -96,6 +96,7 @@ a dictionary key and list of values
'fapws.major_minor': b'1.1',
'fapws.remote_addr': b'127.0.0.1',
'fapws.remote_port': 60580,
+ 'fapws.socket_fd': 4,
'REQUEST_METHOD': b'GET',
'SCRIPT_NAME': b'/hello',
'QUERY_STRING': b'param=key',
@@ -396,6 +397,9 @@ PyObject *py_get_request_info(struct client *cli)
pydummy=Py_BuildValue("H",cli->remote_port);
PyDict_SetItemString(pydict, "fapws.remote_port", pydummy);
Py_DECREF(pydummy);
+ pydummy=PyLong_FromLong(cli->fd);
+ PyDict_SetItemString(pydict, "fapws.socket_fd", pydummy);
+ Py_DECREF(pydummy);
return pydict;
}
@@ -0,0 +1,30 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import fapws._evwsgi as evwsgi
+from fapws import base
+
+def start():
+ evwsgi.start("/tmp/hello_unix.sock", "unix")
+ evwsgi.set_base_module(base)
+
+ def hello(environ, start_response):
+ start_response('200 OK', [('Content-Type','text/html')])
+ return ["hello world!!"]
+
+ def iteration(environ, start_response):
+ start_response('200 OK', [('Content-Type','text/plain')])
+ yield "hello"
+ yield " "
+ yield "world!!"
+
+
+ evwsgi.wsgi_cb(("/hello", hello))
+ evwsgi.wsgi_cb(("/iterhello", iteration))
+
+ evwsgi.set_debug(0)
+ evwsgi.run()
+
+
+if __name__=="__main__":
+ start()
View
@@ -75,7 +75,10 @@ def find_file(fname, dirs):
#anyhow we include the standards directories
search_library_dirs.extend(['/usr/lib','/usr/local/lib','/opt/local/lib','/usr/lib64','/usr/pkg/lib/ev'])
-search_include_dirs.extend(['/usr/include','/usr/local/include','/opt/local/include','/usr/pkg/include/ev'])
+if sys.platform == "darwin":
+ search_include_dirs.extend(['/usr/local/include','/opt/local/include','/usr/pkg/include/ev'])
+else:
+ search_include_dirs.extend(['/usr/include','/usr/local/include','/opt/local/include','/usr/pkg/include/ev'])
#version=platform.python_version_tuple()
#if int(version[0])==2 and int(version[1])>=4:
@@ -104,7 +107,10 @@ def find_file(fname, dirs):
print("Please install libev, or provide the path by setting the shell environmental variable LD_LIBRARY_PATH")
sys.exit(1)
library_dirs.append(res)
-extra_link_args=['-Wl,-R%s' % res]
+if sys.platform == "darwin":
+ extra_link_args=['-Wl']
+else:
+ extra_link_args=['-Wl,-R%s' % res]
setup(cmdclass = {'build_py': build_py},
@@ -0,0 +1,33 @@
+import socket
+import time
+
+def send(post_data, port=8080, host='127.0.0.1'):
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ s.connect((host, port))
+ s.send(post_data)
+ time.sleep(0.1) # we just let the sercer having time to build the answer
+ res = s.recv(1024)
+ s.close()
+ return res
+
+
+if __name__ == "__main__":
+ data = """POST /testpost HTTP/1.1\r
+Host: 127.0.0.1:8080\r
+Accept: */*\r
+Content-Length: 333\r
+Content-Type: multipart/form-data; boundary=----------------------------6b72468f07eb\r
+\r
+------------------------------6b72468f07eb\r
+Content-Disposition: form-data; name="field1"\r
+\r
+this is a test using httppost & stuff\r
+------------------------------6b72468f07eb\r
+Content-Disposition: form-data; name="field2"; filename="short.txt"\r
+Content-Type: text/plain\r
+\r
+Hello world
+\r
+------------------------------6b72468f07eb--\r\n"""
+ res = send(data)
+ print(res)
@@ -7,7 +7,12 @@
import sys
from fapws.contrib import views, zip, log
import mybase
-import pprint
+
+if len(sys.argv)>1 and sys.argv[1]=="socket":
+ import socket
+ socket_server = True
+else:
+ socket_server = False
def env(environ, start_response):
start_response(b'200 OK', [(b'Content-Type',b'text/html')])
@@ -23,6 +28,13 @@ def hello(environ, start_response):
start_response(b'200 OK', [(b'Content-Type',b'text/html')])
return [b"Hello",b" world!!"]
+class helloclass(object):
+ def __init__(self, txt=None):
+ self.content = ["Hello from class %s" % txt]
+ def __call__(self, environ, start_response):
+ start_response('200 OK', [('Content-Type','text/html')])
+ return self.content
+
def iteration(environ, start_response):
start_response('200 OK', [('Content-Type','text/plain')])
yield b"Hello"
@@ -83,11 +95,15 @@ def badscript(environ, start_response):
def start():
- evwsgi.start("0.0.0.0", "8080")
+ if socket_server:
+ evwsgi.start("\0/org/fapws3/server", "unix")
+ else:
+ evwsgi.start("0.0.0.0", "8080")
evwsgi.set_base_module(mybase)
evwsgi.wsgi_cb((b"/env", env))
+ evwsgi.wsgi_cb((b"/helloclass", helloclass("!!!")))
evwsgi.wsgi_cb((b"/hello", hello))
evwsgi.wsgi_cb((b"/tuplehello", tuplehello))
evwsgi.wsgi_cb((b"/iterhello", iteration))
@@ -100,7 +116,7 @@ def start():
evwsgi.wsgi_cb((b"/testpost", testpost))
evwsgi.wsgi_cb((b"/badscript", badscript))
- evwsgi.set_debug(1)
+ evwsgi.set_debug(0)
evwsgi.run()
Oops, something went wrong.

0 comments on commit 63315b8

Please sign in to comment.