Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
M
mongoose
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
esp
mongoose
Commits
d685d23b
Commit
d685d23b
authored
Aug 26, 2010
by
valenok
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fixed python bindings
parent
ee997ba7
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
91 additions
and
79 deletions
+91
-79
example.py
bindings/python/example.py
+14
-17
mongoose.py
bindings/python/mongoose.py
+77
-62
No files found.
bindings/python/example.py
View file @
d685d23b
...
@@ -10,38 +10,35 @@ import sys
...
@@ -10,38 +10,35 @@ import sys
# This function is a "/foo" URI handler: it will be called each time
# This function is a "/foo" URI handler: it will be called each time
# HTTP request to http://this_machine:8080/foo made.
# HTTP request to http://this_machine:8080/foo made.
# It displays some request information.
# It displays some request information.
def
uri_handler
(
conn
,
info
,
data
):
def
uri_handler
(
conn
,
info
):
if
info
.
uri
!=
'/foo'
:
return
mongoose
.
MG_ERROR
conn
.
printf
(
'
%
s'
,
'HTTP/1.0 200 OK
\r\n
'
)
conn
.
printf
(
'
%
s'
,
'HTTP/1.0 200 OK
\r\n
'
)
conn
.
printf
(
'
%
s'
,
'Content-Type: text/plain
\r\n\r\n
'
)
conn
.
printf
(
'
%
s'
,
'Content-Type: text/plain
\r\n\r\n
'
)
conn
.
printf
(
'
%
s
%
s
\n
'
,
info
.
request_method
,
info
.
uri
)
conn
.
printf
(
'
%
s
%
s
\n
'
,
info
.
request_method
,
info
.
uri
)
conn
.
printf
(
'my_var:
%
s
\n
'
,
conn
.
get_var
(
'my_var'
)
or
'<not set>'
)
conn
.
printf
(
'my_var:
%
s
\n
'
,
conn
.
get_qsvar
(
info
,
'my_var'
)
or
'<not set>'
)
conn
.
printf
(
'HEADERS:
\n
'
)
conn
.
printf
(
'HEADERS:
\n
'
)
for
header
in
info
.
http_headers
[:
info
.
num_headers
]:
for
header
in
info
.
http_headers
[:
info
.
num_headers
]:
conn
.
printf
(
'
%
s:
%
s
\n
'
,
header
.
name
,
header
.
value
)
conn
.
printf
(
'
%
s:
%
s
\n
'
,
header
.
name
,
header
.
value
)
return
mongoose
.
MG_SUCCESS
# This function is 404 error handler: it is called each time requested
# This function is 404 error handler: it is called each time requested
# document is not found by the server.
# document is not found by the server.
def
error_
404_handler
(
conn
,
info
,
data
):
def
error_
handler
(
conn
,
info
):
conn
.
printf
(
'
%
s'
,
'HTTP/1.0 200 OK
\r\n
'
)
conn
.
printf
(
'
%
s'
,
'HTTP/1.0 200 OK
\r\n
'
)
conn
.
printf
(
'
%
s'
,
'Content-Type: text/plain
\r\n\r\n
'
)
conn
.
printf
(
'
%
s'
,
'Content-Type: text/plain
\r\n\r\n
'
)
conn
.
printf
(
'Document
%
s not found!
\n
'
,
info
.
uri
)
conn
.
printf
(
'HTTP error:
%
d
\n
'
,
info
.
status_code
)
return
mongoose
.
MG_SUCCESS
# Create mongoose object, and register '/foo' URI handler
# Create mongoose object, and register '/foo' URI handler
# List of options may be specified in the contructor
# List of options may be specified in the contructor
server
=
mongoose
.
Mongoose
(
root
=
'/tmp'
,
ports
=
'8080'
)
server
=
mongoose
.
Mongoose
(
document_root
=
'/tmp'
,
new_request_handler
=
uri_handler
,
http_error_handler
=
error_handler
,
listening_ports
=
'8080'
)
# Register custom URI and 404 error handler
print
'Starting Mongoose server, press enter to quit'
server
.
set_uri_callback
(
'/foo'
,
uri_handler
,
0
)
server
.
set_error_callback
(
404
,
error_404_handler
,
0
)
# Any option may be set later on by setting an attribute of the server object
server
.
ports
=
'8080,8081'
# Listen on port 8081 in addition to 8080
# Mongoose options can be retrieved by asking an attribute
print
'Starting Mongoose
%
s on port(s)
%
s '
%
(
server
.
version
,
server
.
ports
)
print
'CGI extensions:
%
s'
%
server
.
cgi_ext
# Serve connections until 'enter' key is pressed on a console
sys
.
stdin
.
read
(
1
)
sys
.
stdin
.
read
(
1
)
# Deleting server object stops all serving threads
# Deleting server object stops all serving threads
...
...
bindings/python/mongoose.py
View file @
d685d23b
...
@@ -44,6 +44,12 @@ import ctypes
...
@@ -44,6 +44,12 @@ import ctypes
import
os
import
os
MG_ERROR
=
0
MG_SUCCESS
=
1
MG_NOT_FOUND
=
2
MG_BUFFER_TOO_SMALL
=
3
class
mg_header
(
ctypes
.
Structure
):
class
mg_header
(
ctypes
.
Structure
):
"""A wrapper for struct mg_header."""
"""A wrapper for struct mg_header."""
_fields_
=
[
_fields_
=
[
...
@@ -59,37 +65,73 @@ class mg_request_info(ctypes.Structure):
...
@@ -59,37 +65,73 @@ class mg_request_info(ctypes.Structure):
(
'uri'
,
ctypes
.
c_char_p
),
(
'uri'
,
ctypes
.
c_char_p
),
(
'http_version'
,
ctypes
.
c_char_p
),
(
'http_version'
,
ctypes
.
c_char_p
),
(
'query_string'
,
ctypes
.
c_char_p
),
(
'query_string'
,
ctypes
.
c_char_p
),
(
'post_data'
,
ctypes
.
c_char_p
),
(
'remote_user'
,
ctypes
.
c_char_p
),
(
'remote_user'
,
ctypes
.
c_char_p
),
(
'log_message'
,
ctypes
.
c_char_p
),
(
'remote_ip'
,
ctypes
.
c_long
),
(
'remote_ip'
,
ctypes
.
c_long
),
(
'remote_port'
,
ctypes
.
c_int
),
(
'remote_port'
,
ctypes
.
c_int
),
(
'post_data_len'
,
ctypes
.
c_int
),
(
'status_code'
,
ctypes
.
c_int
),
(
'status_code'
,
ctypes
.
c_int
),
(
'is_ssl'
,
ctypes
.
c_int
),
(
'num_headers'
,
ctypes
.
c_int
),
(
'num_headers'
,
ctypes
.
c_int
),
(
'http_headers'
,
mg_header
*
64
),
(
'http_headers'
,
mg_header
*
64
),
]
]
mg_callback_t
=
ctypes
.
CFUNCTYPE
(
ctypes
.
c_int
,
ctypes
.
c_voidp
,
ctypes
.
POINTER
(
mg_request_info
))
class
mg_config
(
ctypes
.
Structure
):
"""A wrapper for struct mg_config."""
_fields_
=
[
(
'document_root'
,
ctypes
.
c_char_p
),
(
'index_files'
,
ctypes
.
c_char_p
),
(
'ssl_certificate'
,
ctypes
.
c_char_p
),
(
'listening_ports'
,
ctypes
.
c_char_p
),
(
'cgi_extensions'
,
ctypes
.
c_char_p
),
(
'cgi_interpreter'
,
ctypes
.
c_char_p
),
(
'cgi_environment'
,
ctypes
.
c_char_p
),
(
'ssi_extensions'
,
ctypes
.
c_char_p
),
(
'auth_domain'
,
ctypes
.
c_char_p
),
(
'protect'
,
ctypes
.
c_char_p
),
(
'global_passwords_file'
,
ctypes
.
c_char_p
),
(
'put_delete_passwords_file'
,
ctypes
.
c_char_p
),
(
'access_log_file'
,
ctypes
.
c_char_p
),
(
'error_log_file'
,
ctypes
.
c_char_p
),
(
'acl'
,
ctypes
.
c_char_p
),
(
'uid'
,
ctypes
.
c_char_p
),
(
'mime_types'
,
ctypes
.
c_char_p
),
(
'enable_directory_listing'
,
ctypes
.
c_char_p
),
(
'num_threads'
,
ctypes
.
c_char_p
),
(
'new_request_handler'
,
mg_callback_t
),
(
'http_error_handler'
,
mg_callback_t
),
(
'event_log_handler'
,
mg_callback_t
),
(
'ssl_password_handler'
,
mg_callback_t
),
]
class
Connection
(
object
):
class
Connection
(
object
):
"""A wrapper class for all functions that take
"""A wrapper class for all functions that take
struct mg_connection * as the first argument."""
struct mg_connection * as the first argument."""
def
__init__
(
self
,
mongoose
,
connection
):
def
__init__
(
self
,
mongoose
,
connection
):
self
.
m
=
mongoose
self
.
m
=
mongoose
self
.
conn
=
c
onnection
self
.
conn
=
c
types
.
c_voidp
(
connection
)
def
get_header
(
self
,
name
):
def
get_header
(
self
,
name
):
val
=
self
.
m
.
dll
.
mg_get_header
(
self
.
conn
,
name
)
val
=
self
.
m
.
dll
.
mg_get_header
(
self
.
conn
,
name
)
return
ctypes
.
c_char_p
(
val
)
.
value
return
ctypes
.
c_char_p
(
val
)
.
value
def
get_var
(
self
,
name
):
def
get_var
(
self
,
buf
,
buflen
,
name
):
var
=
None
size
=
1024
pointer
=
self
.
m
.
dll
.
mg_get_var
(
self
.
conn
,
name
)
value
=
ctypes
.
create_string_buffer
(
size
)
if
pointer
:
self
.
m
.
dll
.
mg_get_var
.
restype
=
ctypes
.
c_int
# Make a copy and free() the returned pointer
result
=
self
.
m
.
dll
.
mg_get_var
(
buf
,
buflen
,
name
,
value
,
size
)
var
=
''
+
ctypes
.
c_char_p
(
pointer
)
.
value
return
result
==
MG_ERROR
and
None
or
value
self
.
m
.
dll
.
mg_free
(
pointer
)
return
var
def
get_qsvar
(
self
,
request_info
,
name
):
qs
=
request_info
.
query_string
return
qs
and
self
.
get_var
(
qs
,
len
(
qs
),
name
)
or
None
def
printf
(
self
,
fmt
,
*
args
):
def
printf
(
self
,
fmt
,
*
args
):
val
=
self
.
m
.
dll
.
mg_printf
(
self
.
conn
,
fmt
,
*
args
)
val
=
self
.
m
.
dll
.
mg_printf
(
self
.
conn
,
fmt
,
*
args
)
...
@@ -103,75 +145,48 @@ class Connection(object):
...
@@ -103,75 +145,48 @@ class Connection(object):
class
Mongoose
(
object
):
class
Mongoose
(
object
):
"""A wrapper class for Mongoose shared library."""
"""A wrapper class for Mongoose shared library."""
# Exceptions for __setattr__ and __getattr__: these attributes
# must not be treated as Mongoose options
_private
=
(
'dll'
,
'ctx'
,
'version'
,
'callbacks'
)
def
__init__
(
self
,
**
kwargs
):
def
__init__
(
self
,
**
kwargs
):
dll_extension
=
os
.
name
==
'nt'
and
'dll'
or
'so'
dll_extension
=
os
.
name
==
'nt'
and
'dll'
or
'so'
self
.
dll
=
ctypes
.
CDLL
(
'_mongoose.
%
s'
%
dll_extension
)
self
.
dll
=
ctypes
.
CDLL
(
'_mongoose.
%
s'
%
dll_extension
)
start
=
self
.
dll
.
mg_start
self
.
ctx
=
ctypes
.
c_voidp
(
self
.
dll
.
mg_start
())
.
value
self
.
version
=
ctypes
.
c_char_p
(
self
.
dll
.
mg_version
())
.
value
self
.
callbacks
=
[]
self
.
callbacks
=
[]
for
name
,
value
in
kwargs
.
iteritems
():
self
.
config
=
mg_config
(
num_threads
=
'5'
,
self
.
__setattr__
(
name
,
value
)
enable_directory_listing
=
'yes'
,
listening_ports
=
'8080'
,
def
__setattr__
(
self
,
name
,
value
):
document_root
=
'.'
,
"""Set Mongoose option. Raises ValueError in option not set."""
auth_domain
=
'mydomain.com'
)
if
name
in
self
.
_private
:
for
key
,
value
in
kwargs
.
iteritems
():
object
.
__setattr__
(
self
,
name
,
value
)
if
key
in
(
'new_request_handler'
,
else
:
'http_error_handler'
,
code
=
self
.
dll
.
mg_set_option
(
self
.
ctx
,
name
,
value
)
'event_log_handler'
,
if
code
!=
1
:
'ssl_password_handler'
):
raise
ValueError
(
'Cannot set option [
%
s] '
cb
=
self
.
MakeHandler
(
value
)
'to [
%
s]'
%
(
name
,
value
))
setattr
(
self
.
config
,
key
,
cb
)
else
:
def
__getattr__
(
self
,
name
):
setattr
(
self
.
config
,
key
,
str
(
value
))
"""Get Mongoose option."""
self
.
dll
.
mg_start
.
restype
=
ctypes
.
c_void_p
if
name
in
self
.
_private
:
self
.
ctx
=
self
.
dll
.
mg_start
(
ctypes
.
byref
(
self
.
config
))
return
object
.
__getattr__
(
self
,
name
)
else
:
val
=
self
.
dll
.
mg_get_option
(
self
.
ctx
,
name
)
return
ctypes
.
c_char_p
(
val
)
.
value
def
__del__
(
self
):
def
__del__
(
self
):
"""Destructor, stop Mongoose instance."""
"""Destructor, stop Mongoose instance."""
self
.
dll
.
mg_stop
(
self
.
ctx
)
self
.
dll
.
mg_stop
(
ctypes
.
c_void_p
(
self
.
ctx
)
)
def
_make_c_callback
(
self
,
python_callback
):
def
MakeHandler
(
self
,
python_func
):
"""Return C callback from given Python callback."""
"""Return C callback from given Python callback."""
# Create a closure that will be called by the shared library.
# Create a closure that will be called by the shared library.
def
_cb
(
connection
,
request_info
,
user_data
):
def
func
(
connection
,
request_info
):
# Wrap connection pointer into the connection
# Wrap connection pointer into the connection
# object and call Python callback
# object and call Python callback
conn
=
Connection
(
self
,
connection
)
conn
=
Connection
(
self
,
connection
)
python_callback
(
conn
,
request_info
.
contents
,
user_data
)
return
python_func
(
conn
,
request_info
.
contents
)
# Convert the closure into C callable object
# Convert the closure into C callable object
c_
callback
=
ctypes
.
CFUNCTYPE
(
ctypes
.
c_voidp
,
ctypes
.
c_voidp
,
c_
func
=
mg_callback_t
(
func
)
ctypes
.
POINTER
(
mg_request_info
),
ctypes
.
c_voidp
)(
_cb
)
c_func
.
restype
=
ctypes
.
c_int
# Store created callback in the list, so it is kept alive
# Store created callback in the list, so it is kept alive
# during context lifetime. Otherwise, python can garbage
# during context lifetime. Otherwise, python can garbage
# collect it, and C code will crash trying to call it.
# collect it, and C code will crash trying to call it.
self
.
callbacks
.
append
(
c_callback
)
self
.
callbacks
.
append
(
c_func
)
return
c_callback
def
set_uri_callback
(
self
,
uri_regex
,
python_callback
,
user_data
):
return
c_func
self
.
dll
.
mg_set_uri_callback
(
self
.
ctx
,
uri_regex
,
self
.
_make_c_callback
(
python_callback
),
user_data
)
def
set_auth_callback
(
self
,
uri_regex
,
python_callback
,
user_data
):
self
.
dll
.
mg_set_auth_callback
(
self
.
ctx
,
uri_regex
,
self
.
_make_c_callback
(
python_callback
),
user_data
)
def
set_error_callback
(
self
,
error_code
,
python_callback
,
user_data
):
self
.
dll
.
mg_set_error_callback
(
self
.
ctx
,
error_code
,
self
.
_make_c_callback
(
python_callback
),
user_data
)
def
set_log_callback
(
self
,
python_callback
):
self
.
dll
.
mg_set_log_callback
(
self
.
ctx
,
self
.
_make_c_callback
(
python_callback
))
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment