2019-04-29 08:22:36 +00:00
|
|
|
#include <iostream>
|
|
|
|
#include <http-parser/http_parser.h>
|
|
|
|
#include "angel_wings.h"
|
|
|
|
#include "wings_socket.h"
|
|
|
|
using namespace wings;
|
|
|
|
|
|
|
|
void Dart_WingsSocket_parseHttp(Dart_NativeArguments arguments)
|
|
|
|
{
|
|
|
|
Dart_Port service_port =
|
|
|
|
Dart_NewNativePort("WingsHttpCallback", &wingsHttpCallback, true);
|
|
|
|
Dart_Handle send_port = Dart_NewSendPort(service_port);
|
|
|
|
Dart_SetReturnValue(arguments, send_port);
|
|
|
|
}
|
|
|
|
|
2019-05-01 04:29:21 +00:00
|
|
|
struct wingsHttp
|
|
|
|
{
|
|
|
|
Dart_Port port;
|
|
|
|
std::string lastHeader;
|
|
|
|
};
|
|
|
|
|
2019-04-29 08:22:36 +00:00
|
|
|
void wingsHttpCallback(Dart_Port dest_port_id, Dart_CObject *message)
|
|
|
|
{
|
|
|
|
int64_t fd = -1;
|
|
|
|
Dart_Port outPort = message->value.as_array.values[0]->value.as_send_port.id;
|
|
|
|
Dart_CObject *fdArg = message->value.as_array.values[1];
|
|
|
|
|
2019-05-01 04:29:21 +00:00
|
|
|
wingsHttp httpData = {outPort};
|
|
|
|
|
|
|
|
#define theStruct (*((wingsHttp *)parser->data))
|
|
|
|
#define thePort theStruct.port
|
|
|
|
#define sendInt(n) \
|
|
|
|
{ \
|
|
|
|
Dart_CObject obj; \
|
|
|
|
obj.type = Dart_CObject_kInt64; \
|
|
|
|
obj.value.as_int64 = (n); \
|
|
|
|
Dart_PostCObject(thePort, &obj); \
|
|
|
|
}
|
|
|
|
#define sendString(n) \
|
|
|
|
if (length > 0) \
|
|
|
|
{ \
|
|
|
|
Dart_CObject typeObj; \
|
|
|
|
typeObj.type = Dart_CObject_kInt32; \
|
|
|
|
typeObj.value.as_int32 = (n); \
|
|
|
|
std::string str(at, length); \
|
|
|
|
Dart_CObject strObj; \
|
|
|
|
strObj.type = Dart_CObject_kString; \
|
|
|
|
strObj.value.as_string = (char *)str.c_str(); \
|
|
|
|
Dart_CObject *values[2] = {&typeObj, &strObj}; \
|
|
|
|
Dart_CObject out; \
|
|
|
|
out.type = Dart_CObject_kArray; \
|
|
|
|
out.value.as_array.length = 2; \
|
|
|
|
out.value.as_array.values = values; \
|
|
|
|
Dart_PostCObject(thePort, &out); \
|
2019-04-29 08:22:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (fdArg->type == Dart_CObject_kInt32)
|
|
|
|
{
|
|
|
|
fd = (int64_t)fdArg->value.as_int32;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fd = fdArg->value.as_int64;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fd != -1)
|
|
|
|
{
|
|
|
|
http_parser_settings settings;
|
|
|
|
|
|
|
|
settings.on_message_begin = [](http_parser *parser) {
|
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
settings.on_headers_complete = [](http_parser *parser) {
|
2019-05-01 04:29:21 +00:00
|
|
|
Dart_CObject type;
|
|
|
|
type.type = Dart_CObject_kInt32;
|
|
|
|
type.value.as_int32 = 2;
|
|
|
|
Dart_CObject value;
|
|
|
|
value.type = Dart_CObject_kInt32;
|
|
|
|
value.value.as_int32 = parser->method;
|
|
|
|
Dart_CObject *values[2] = {&type, &value};
|
|
|
|
Dart_CObject out;
|
|
|
|
out.type = Dart_CObject_kArray;
|
|
|
|
out.value.as_array.length = 2;
|
|
|
|
out.value.as_array.values = values;
|
|
|
|
Dart_PostCObject(thePort, &out);
|
|
|
|
sendInt(100);
|
2019-04-29 08:22:36 +00:00
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
settings.on_message_complete = [](http_parser *parser) {
|
2019-05-01 04:29:21 +00:00
|
|
|
sendInt(200);
|
2019-04-29 08:22:36 +00:00
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
settings.on_chunk_complete = [](http_parser *parser) {
|
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
settings.on_chunk_header = [](http_parser *parser) {
|
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
settings.on_url = [](http_parser *parser, const char *at, size_t length) {
|
2019-05-01 04:29:21 +00:00
|
|
|
sendString(0);
|
2019-04-29 08:22:36 +00:00
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
settings.on_header_field = [](http_parser *parser, const char *at, size_t length) {
|
2019-05-01 04:29:21 +00:00
|
|
|
theStruct.lastHeader = std::string(at, length);
|
2019-04-29 08:22:36 +00:00
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
settings.on_header_value = [](http_parser *parser, const char *at, size_t length) {
|
2019-05-01 04:29:21 +00:00
|
|
|
if (!theStruct.lastHeader.empty())
|
|
|
|
{
|
|
|
|
std::string vStr(at, length);
|
|
|
|
Dart_CObject type;
|
|
|
|
type.type = Dart_CObject_kInt32;
|
|
|
|
type.value.as_int32 = 1;
|
|
|
|
Dart_CObject name;
|
|
|
|
name.type = Dart_CObject_kString;
|
|
|
|
name.value.as_string = (char *)theStruct.lastHeader.c_str();
|
|
|
|
Dart_CObject value;
|
|
|
|
value.type = Dart_CObject_kString;
|
|
|
|
value.value.as_string = (char *)vStr.c_str();
|
|
|
|
Dart_CObject *values[3] = {&type, &name, &value};
|
|
|
|
Dart_CObject out;
|
|
|
|
out.type = Dart_CObject_kArray;
|
|
|
|
out.value.as_array.length = 3;
|
|
|
|
out.value.as_array.values = values;
|
|
|
|
Dart_PostCObject(thePort, &out);
|
|
|
|
theStruct.lastHeader.clear();
|
|
|
|
}
|
2019-04-29 08:22:36 +00:00
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
settings.on_body = [](http_parser *parser, const char *at, size_t length) {
|
2019-05-01 04:29:21 +00:00
|
|
|
Dart_CObject obj;
|
|
|
|
obj.type = Dart_CObject_kTypedData;
|
|
|
|
obj.value.as_typed_data.type = Dart_TypedData_kUint8;
|
|
|
|
obj.value.as_typed_data.length = length;
|
|
|
|
obj.value.as_typed_data.values = (uint8_t *)at;
|
|
|
|
Dart_PostCObject(thePort, &obj);
|
2019-04-29 08:22:36 +00:00
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
size_t len = 80 * 1024, nparsed = 0;
|
|
|
|
char buf[len];
|
|
|
|
ssize_t recved = 0;
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
// http_parser parser;
|
|
|
|
auto *parser = (http_parser *)malloc(sizeof(http_parser));
|
|
|
|
http_parser_init(parser, HTTP_BOTH);
|
2019-05-01 04:29:21 +00:00
|
|
|
parser->data = &httpData;
|
2019-04-29 08:22:36 +00:00
|
|
|
|
|
|
|
while ((recved = recv(fd, buf, len, 0)) >= 0)
|
|
|
|
{
|
|
|
|
if (false) // (isUpgrade)
|
|
|
|
{
|
|
|
|
// send_string(&parser, buf, (size_t)recved, 7, true);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Start up / continue the parser.
|
|
|
|
* Note we pass recved==0 to signal that EOF has been received.
|
|
|
|
*/
|
|
|
|
nparsed = http_parser_execute(parser, &settings, buf, recved);
|
|
|
|
|
|
|
|
if (nparsed != recved)
|
|
|
|
{
|
|
|
|
// TODO: End it...!
|
|
|
|
}
|
|
|
|
else if (recved == 0)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if ((isUpgrade = parser.upgrade) == 1)
|
|
|
|
// {
|
|
|
|
// send_notification(&parser, 6);
|
|
|
|
// }
|
|
|
|
// else if (nparsed != recved)
|
|
|
|
// {
|
|
|
|
// close(rq->sock);
|
|
|
|
// return;
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
|
|
|
|
// memset(buf, 0, len);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|