diff --git a/fibjs/include/HttpRequest.h b/fibjs/include/HttpRequest.h index db67d2b854..414b73bd97 100644 --- a/fibjs/include/HttpRequest.h +++ b/fibjs/include/HttpRequest.h @@ -38,6 +38,7 @@ class HttpRequest : public HttpRequest_base { virtual result_t read(int32_t bytes, obj_ptr& retVal, AsyncEvent* ac); virtual result_t readAll(obj_ptr& retVal, AsyncEvent* ac); virtual result_t write(Buffer_base* data, AsyncEvent* ac); + virtual result_t json(v8::Local data, AsyncEvent* ac); virtual result_t get_length(int64_t& retVal); virtual result_t end(); virtual result_t isEnded(bool& retVal); diff --git a/fibjs/include/HttpResponse.h b/fibjs/include/HttpResponse.h index cff3a1d24a..f620e2c0c4 100644 --- a/fibjs/include/HttpResponse.h +++ b/fibjs/include/HttpResponse.h @@ -37,6 +37,7 @@ class HttpResponse : public HttpResponse_base { virtual result_t read(int32_t bytes, obj_ptr& retVal, AsyncEvent* ac); virtual result_t readAll(obj_ptr& retVal, AsyncEvent* ac); virtual result_t write(Buffer_base* data, AsyncEvent* ac); + virtual result_t json(v8::Local data, AsyncEvent* ac); virtual result_t get_length(int64_t& retVal); virtual result_t end(); virtual result_t isEnded(bool& retVal); diff --git a/fibjs/include/Message.h b/fibjs/include/Message.h index 97c61958d9..4e1fb2e6af 100644 --- a/fibjs/include/Message.h +++ b/fibjs/include/Message.h @@ -29,6 +29,7 @@ class Message : public Message_base { virtual result_t read(int32_t bytes, obj_ptr& retVal, AsyncEvent* ac); virtual result_t readAll(obj_ptr& retVal, AsyncEvent* ac); virtual result_t write(Buffer_base* data, AsyncEvent* ac); + virtual result_t json(v8::Local data, AsyncEvent* ac); virtual result_t get_length(int64_t& retVal); virtual result_t end(); virtual result_t isEnded(bool& retVal); diff --git a/fibjs/include/WebSocketMessage.h b/fibjs/include/WebSocketMessage.h index 4e3714ef0d..475ff99cce 100644 --- a/fibjs/include/WebSocketMessage.h +++ b/fibjs/include/WebSocketMessage.h @@ -39,6 +39,7 @@ class WebSocketMessage : public WebSocketMessage_base { virtual result_t read(int32_t bytes, obj_ptr& retVal, AsyncEvent* ac); virtual result_t readAll(obj_ptr& retVal, AsyncEvent* ac); virtual result_t write(Buffer_base* data, AsyncEvent* ac); + virtual result_t json(v8::Local data, AsyncEvent* ac); virtual result_t get_length(int64_t& retVal); virtual result_t end(); virtual result_t isEnded(bool& retVal); diff --git a/fibjs/include/WorkerMessage.h b/fibjs/include/WorkerMessage.h index d63521bade..2f167ddce5 100644 --- a/fibjs/include/WorkerMessage.h +++ b/fibjs/include/WorkerMessage.h @@ -34,6 +34,7 @@ class WorkerMessage : public Message_base { virtual result_t read(int32_t bytes, obj_ptr& retVal, AsyncEvent* ac); virtual result_t readAll(obj_ptr& retVal, AsyncEvent* ac); virtual result_t write(Buffer_base* data, AsyncEvent* ac); + virtual result_t json(v8::Local data, AsyncEvent* ac); virtual result_t get_length(int64_t& retVal); virtual result_t end(); virtual result_t isEnded(bool& retVal); diff --git a/fibjs/include/ifs/Message.h b/fibjs/include/ifs/Message.h index 29cbbc5817..720ecc8479 100644 --- a/fibjs/include/ifs/Message.h +++ b/fibjs/include/ifs/Message.h @@ -45,6 +45,7 @@ class Message_base : public object_base { virtual result_t read(int32_t bytes, obj_ptr& retVal, AsyncEvent* ac) = 0; virtual result_t readAll(obj_ptr& retVal, AsyncEvent* ac) = 0; virtual result_t write(Buffer_base* data, AsyncEvent* ac) = 0; + virtual result_t json(v8::Local data, AsyncEvent* ac) = 0; virtual result_t get_length(int64_t& retVal) = 0; virtual result_t end() = 0; virtual result_t isEnded(bool& retVal) = 0; @@ -76,6 +77,7 @@ class Message_base : public object_base { static void s_read(const v8::FunctionCallbackInfo& args); static void s_readAll(const v8::FunctionCallbackInfo& args); static void s_write(const v8::FunctionCallbackInfo& args); + static void s_json(const v8::FunctionCallbackInfo& args); static void s_get_length(v8::Local property, const v8::PropertyCallbackInfo& args); static void s_end(const v8::FunctionCallbackInfo& args); static void s_isEnded(const v8::FunctionCallbackInfo& args); @@ -91,6 +93,7 @@ class Message_base : public object_base { ASYNC_MEMBERVALUE2(Message_base, read, int32_t, obj_ptr); ASYNC_MEMBERVALUE1(Message_base, readAll, obj_ptr); ASYNC_MEMBER1(Message_base, write, Buffer_base*); + ASYNC_MEMBER1(Message_base, json, v8::Local); ASYNC_MEMBER1(Message_base, sendTo, Stream_base*); ASYNC_MEMBER1(Message_base, readFrom, Stream_base*); }; @@ -111,6 +114,8 @@ inline ClassInfo& Message_base::class_info() { "readAllSync", s_readAll, false }, { "write", s_write, false }, { "writeSync", s_write, false }, + { "json", s_json, false }, + { "jsonSync", s_json, false }, { "end", s_end, false }, { "isEnded", s_isEnded, false }, { "clear", s_clear, false }, @@ -338,6 +343,24 @@ inline void Message_base::s_write(const v8::FunctionCallbackInfo& arg METHOD_VOID(); } +inline void Message_base::s_json(const v8::FunctionCallbackInfo& args) +{ + METHOD_INSTANCE(Message_base); + METHOD_ENTER(); + + ASYNC_METHOD_OVER(1, 1); + + ARG(v8::Local, 0); + + if (!cb.IsEmpty()) { + pInst->acb_json(v0, cb); + hr = CALL_RETURN_NULL; + } else + hr = pInst->ac_json(v0); + + METHOD_VOID(); +} + inline void Message_base::s_get_length(v8::Local property, const v8::PropertyCallbackInfo& args) { int64_t vr; diff --git a/fibjs/src/coroutine/WorkerMessage.cpp b/fibjs/src/coroutine/WorkerMessage.cpp index 164a3fb4e6..3b3b78442f 100644 --- a/fibjs/src/coroutine/WorkerMessage.cpp +++ b/fibjs/src/coroutine/WorkerMessage.cpp @@ -56,6 +56,11 @@ result_t WorkerMessage::write(Buffer_base* data, AsyncEvent* ac) return m_message->write(data, ac); } +result_t WorkerMessage::json(v8::Local data, AsyncEvent* ac) +{ + return m_message->json(data, ac); +} + result_t WorkerMessage::get_length(int64_t& retVal) { return m_message->get_length(retVal); diff --git a/fibjs/src/http/HttpRequest.cpp b/fibjs/src/http/HttpRequest.cpp index dafebde5ce..090fc75c06 100644 --- a/fibjs/src/http/HttpRequest.cpp +++ b/fibjs/src/http/HttpRequest.cpp @@ -59,6 +59,14 @@ result_t HttpRequest::write(Buffer_base* data, AsyncEvent* ac) return m_message->write(data, ac); } +result_t HttpRequest::json(v8::Local data, AsyncEvent* ac) +{ + if (ac->isSync()) + m_message->setHeader("Content-Type", "application/json"); + + return m_message->json(data, ac); +} + result_t HttpRequest::get_length(int64_t& retVal) { return m_message->get_length(retVal); diff --git a/fibjs/src/http/HttpResponse.cpp b/fibjs/src/http/HttpResponse.cpp index 6548fb4a90..f910b5c1d9 100644 --- a/fibjs/src/http/HttpResponse.cpp +++ b/fibjs/src/http/HttpResponse.cpp @@ -60,6 +60,14 @@ result_t HttpResponse::write(Buffer_base* data, AsyncEvent* ac) return m_message->write(data, ac); } +result_t HttpResponse::json(v8::Local data, AsyncEvent* ac) +{ + if (ac->isSync()) + m_message->setHeader("Content-Type", "application/json"); + + return m_message->json(data, ac); +} + result_t HttpResponse::get_length(int64_t& retVal) { return m_message->get_length(retVal); diff --git a/fibjs/src/mq/Message.cpp b/fibjs/src/mq/Message.cpp index 59f222e6bd..a954b8aae2 100644 --- a/fibjs/src/mq/Message.cpp +++ b/fibjs/src/mq/Message.cpp @@ -9,6 +9,8 @@ #include "Message.h" #include "List.h" #include "MemoryStream.h" +#include "Buffer.h" +#include "ifs/json.h" namespace fibjs { @@ -121,6 +123,24 @@ result_t Message::write(Buffer_base* data, AsyncEvent* ac) return m_body->write(data, ac); } +result_t Message::json(v8::Local data, AsyncEvent* ac) +{ + if (ac->isSync()) { + exlib::string str; + result_t hr = json_base::encode(data, str); + if (hr < 0) + return hr; + ac->m_ctx.resize(1); + ac->m_ctx[0] = new Buffer(str); + } + + if (m_body == NULL) + m_body = new MemoryStream(); + + obj_ptr buf = Buffer_base::getInstance(ac->m_ctx[0].object()); + return m_body->write(buf, ac); +} + result_t Message::get_length(int64_t& retVal) { if (m_body == NULL) { diff --git a/fibjs/src/websocket/WebSocketMessage.cpp b/fibjs/src/websocket/WebSocketMessage.cpp index 6f7ec2129a..545c9d19c3 100644 --- a/fibjs/src/websocket/WebSocketMessage.cpp +++ b/fibjs/src/websocket/WebSocketMessage.cpp @@ -67,6 +67,11 @@ result_t WebSocketMessage::write(Buffer_base* data, AsyncEvent* ac) return m_message->write(data, ac); } +result_t WebSocketMessage::json(v8::Local data, AsyncEvent* ac) +{ + return m_message->json(data, ac); +} + result_t WebSocketMessage::get_length(int64_t& retVal) { return m_message->get_length(retVal); diff --git a/idl/zh-cn/Message.idl b/idl/zh-cn/Message.idl index 1f0d4afdba..25fe6b8f17 100644 --- a/idl/zh-cn/Message.idl +++ b/idl/zh-cn/Message.idl @@ -49,6 +49,11 @@ interface Message : object */ write(Buffer data) async; + /*! @brief 以 JSON 编码写入给定的数据 + @param data 给定要写入的数据 + */ + json(Value data) async; + /*! @brief 消息数据部分的长度 */ readonly Long length; diff --git a/test/http_test.js b/test/http_test.js index 0d0ce39eac..c5d2056277 100644 --- a/test/http_test.js +++ b/test/http_test.js @@ -731,6 +731,22 @@ describe("http", () => { }); }); + it('json', () => { + var req = new http.Request(); + req.json({ + a: 100 + }); + assert.equal(req.firstHeader('Content-Type'), "application/json"); + assert.equal(req.data.toString(), '{"a":100}'); + + var rep = new http.Response(); + rep.json({ + a: 100 + }); + assert.equal(rep.firstHeader('Content-Type'), "application/json"); + assert.equal(rep.data.toString(), '{"a":100}'); + }); + describe("encode", () => { it("request", () => { var rep = new http.Request();