platform/lib/src/http.cc

192 lines
6.3 KiB
C++
Raw Normal View History

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);
}
}
}