Skip to content

Commit 56d3429

Browse files
committed
Working on example http-server.
1 parent 0937eb6 commit 56d3429

File tree

11 files changed

+135
-23
lines changed

11 files changed

+135
-23
lines changed

examples/http-server/src/lib.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
use crate::{errors::make_exception_class, server::make_server_class};
1+
use crate::{
2+
errors::make_exception_class, request::make_request_class, response::make_response_class,
3+
server::make_server_class,
4+
};
25
use phper::{modules::Module, php_get_module};
36
use std::{mem::forget, sync::Arc};
47
use tokio::runtime;
58

69
pub mod errors;
10+
pub mod request;
11+
pub mod response;
712
pub mod server;
813
pub mod utils;
914

@@ -27,11 +32,12 @@ pub fn get_module() -> Module {
2732
forget(guard);
2833
true
2934
});
30-
3135
module.on_module_shutdown(move |_| true);
3236

3337
module.add_class(make_exception_class());
3438
module.add_class(make_server_class());
39+
module.add_class(make_request_class());
40+
module.add_class(make_response_class());
3541

3642
module
3743
}

examples/http-server/src/request.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
use crate::errors::HttpServerError;
2+
use phper::{
3+
classes::{DynamicClass, Visibility},
4+
values::Val,
5+
};
6+
7+
pub const HTTP_REQUEST_CLASS_NAME: &'static str = "HttpServer\\HttpRequest";
8+
9+
pub fn make_request_class() -> DynamicClass<()> {
10+
let mut class = DynamicClass::new(HTTP_REQUEST_CLASS_NAME);
11+
12+
class.add_property("header", Visibility::Public, ());
13+
class.add_property("server", Visibility::Public, ());
14+
class.add_property("data", Visibility::Private, ());
15+
16+
class.add_method(
17+
"getData",
18+
Visibility::Public,
19+
|this, _| {
20+
if this.get_property("data").get_type().is_null() {
21+
this.set_property("data", Val::new("Some data here"));
22+
}
23+
Ok::<_, HttpServerError>(this.duplicate_property("data"))
24+
},
25+
vec![],
26+
);
27+
28+
class
29+
}

examples/http-server/src/response.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use hyper::{Body, Response};
2+
use phper::{
3+
classes::{DynamicClass, Visibility},
4+
functions::Argument,
5+
};
6+
7+
pub const HTTP_RESPONSE_CLASS_NAME: &'static str = "HttpServer\\HttpResponse";
8+
9+
pub fn make_response_class() -> DynamicClass<Response<Body>> {
10+
let mut class = DynamicClass::new_with_default(HTTP_RESPONSE_CLASS_NAME);
11+
12+
class.add_method(
13+
"end",
14+
Visibility::Public,
15+
|this, arguments| {
16+
let response: &mut Response<Body> = this.as_mut_state();
17+
*response.body_mut() = arguments[0].as_string()?.into();
18+
Ok::<_, phper::Error>(())
19+
},
20+
vec![Argument::by_val("data")],
21+
);
22+
23+
class
24+
}

examples/http-server/src/server.rs

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1-
use crate::errors::HttpServerError;
1+
use crate::{
2+
errors::HttpServerError, request::HTTP_REQUEST_CLASS_NAME, response::HTTP_RESPONSE_CLASS_NAME,
3+
utils::replace_and_get,
4+
};
25
use hyper::{
36
server::{conn::AddrIncoming, Builder},
47
service::{make_service_fn, service_fn},
58
Body, Request, Response, Server,
69
};
710
use phper::{
8-
classes::{DynamicClass, Visibility},
11+
classes::{ClassEntry, DynamicClass, StatelessClassEntry, Visibility},
912
functions::Argument,
1013
values::Val,
1114
};
12-
use std::{convert::Infallible, mem::replace, net::SocketAddr};
13-
use tokio::runtime::Handle;
15+
use std::{convert::Infallible, mem::replace, net::SocketAddr, sync::Arc};
16+
use tokio::{runtime::Handle, sync::Mutex};
1417

1518
const HTTP_SERVER_CLASS_NAME: &'static str = "HttpServer\\HttpServer";
1619

@@ -52,9 +55,45 @@ pub fn make_server_class() -> DynamicClass<Option<Builder<AddrIncoming>>> {
5255
Visibility::Public,
5356
|this, _| {
5457
let builder = replace(this.as_mut_state(), None).unwrap();
58+
let handle = this
59+
.duplicate_property("onRequestHandle")
60+
.map_err(phper::Error::NotRefCountedType)?;
61+
let handle = Arc::new(Mutex::new(handle));
62+
63+
let make_svc = make_service_fn(move |_conn| {
64+
let handle = handle.clone();
65+
66+
async move {
67+
Ok::<_, Infallible>(service_fn(move |_: Request<Body>| {
68+
let handle = handle.clone();
69+
async move {
70+
let handle = handle.lock().await;
5571

56-
let make_svc =
57-
make_service_fn(|_conn| async { Ok::<_, Infallible>(service_fn(handle)) });
72+
let request =
73+
StatelessClassEntry::from_globals(HTTP_REQUEST_CLASS_NAME)
74+
.unwrap()
75+
.new_object([])
76+
.unwrap();
77+
let request = Val::new(request);
78+
let mut response = ClassEntry::<Response<Body>>::from_globals(
79+
HTTP_RESPONSE_CLASS_NAME,
80+
)
81+
.unwrap()
82+
.new_object([])
83+
.unwrap();
84+
let response_val = response.duplicate();
85+
let response_val = Val::new(response_val);
86+
handle
87+
.call([request, response_val])
88+
.map_err(phper::Error::CallFunction)
89+
.unwrap();
90+
91+
let response = replace_and_get(response.as_mut_state());
92+
Ok::<Response<Body>, Infallible>(response)
93+
}
94+
}))
95+
}
96+
});
5897

5998
let server = builder.serve(make_svc);
6099
Handle::current().block_on(server)?;
@@ -66,7 +105,3 @@ pub fn make_server_class() -> DynamicClass<Option<Builder<AddrIncoming>>> {
66105

67106
class
68107
}
69-
70-
async fn handle(_: Request<Body>) -> Result<Response<Body>, Infallible> {
71-
Ok(Response::new("Hello, World!".into()))
72-
}

examples/http-server/tests/php/test.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
$server = new HttpServer("127.0.0.1", 9000);
1010
$server->onRequest(function ($request, $response) {
11-
$response->header('Content-Type', 'text/plain');
11+
// $response->header('Content-Type', 'text/plain');
1212
$response->end("Hello World\n");
1313
});
14-
// $server->start();
14+
$server->start();

phper-alloc/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,5 @@ impl<T: EAllocatable> Drop for EBox<T> {
8181
<T>::free(self.ptr);
8282
}
8383
}
84+
85+
unsafe impl<T: EAllocatable> Send for EBox<T> {}

phper/src/classes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ impl<T: 'static> ClassEntry<T> {
222222
}
223223

224224
/// Create the object from class and call `__construct` with arguments.
225-
pub fn new_object(&self, arguments: &mut [Val]) -> crate::Result<EBox<Object<T>>> {
225+
pub fn new_object(&self, arguments: impl AsMut<[Val]>) -> crate::Result<EBox<Object<T>>> {
226226
let mut object = self.init_object()?;
227227
object.call_construct(arguments)?;
228228
Ok(object)

phper/src/functions.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,10 @@ impl ZendFunction {
238238
pub fn call_method<T: 'static>(
239239
&mut self,
240240
object: &mut Object<T>,
241-
arguments: &mut [Val],
241+
mut arguments: impl AsMut<[Val]>,
242242
) -> crate::Result<EBox<Val>> {
243243
let mut ret_val = EBox::new(Val::undef());
244+
let arguments = arguments.as_mut();
244245

245246
let mut fci = zend_fcall_info {
246247
size: size_of::<zend_fcall_info>(),

phper/src/objects.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use crate::{
44
alloc::{EAllocatable, EBox},
55
classes::ClassEntry,
6-
errors::CallMethodError,
6+
errors::{CallMethodError, NotRefCountedTypeError},
77
functions::ZendFunction,
88
sys::*,
99
values::Val,
@@ -67,6 +67,17 @@ impl<T: 'static> Object<T> {
6767
}
6868

6969
pub fn get_property(&self, name: impl AsRef<str>) -> &Val {
70+
self.get_mut_property(name)
71+
}
72+
73+
pub fn duplicate_property(
74+
&self,
75+
name: impl AsRef<str>,
76+
) -> Result<EBox<Val>, NotRefCountedTypeError> {
77+
self.get_mut_property(name).duplicate()
78+
}
79+
80+
fn get_mut_property(&self, name: impl AsRef<str>) -> &mut Val {
7081
let name = name.as_ref();
7182

7283
let prop = unsafe {
@@ -194,7 +205,7 @@ impl<T: 'static> Object<T> {
194205
}
195206
}
196207

197-
pub(crate) fn call_construct(&mut self, arguments: &mut [Val]) -> crate::Result<bool> {
208+
pub(crate) fn call_construct(&mut self, arguments: impl AsMut<[Val]>) -> crate::Result<bool> {
198209
unsafe {
199210
match (*self.inner.handlers).get_constructor {
200211
Some(get_constructor) => {

phper/src/values.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,8 @@ impl Val {
262262
/// # Errors
263263
///
264264
/// Return Err when self is not callable.
265-
pub fn call(&self, arguments: &[Val]) -> Result<EBox<Val>, CallFunctionError> {
265+
pub fn call(&self, mut arguments: impl AsMut<[Val]>) -> Result<EBox<Val>, CallFunctionError> {
266+
let arguments = arguments.as_mut();
266267
let mut ret = EBox::new(Val::null());
267268
unsafe {
268269
if phper_call_user_function(
@@ -271,7 +272,7 @@ impl Val {
271272
self.as_ptr() as *mut _,
272273
ret.as_mut_ptr(),
273274
arguments.len() as u32,
274-
arguments.as_ptr() as *const Val as *mut Val as *mut zval,
275+
arguments.as_mut_ptr().cast(),
275276
) && !ret.get_type().is_undef()
276277
{
277278
Ok(ret)

0 commit comments

Comments
 (0)