1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00

[quikcjs] libdom xhr.c

This commit is contained in:
Witold Filipczyk 2023-03-28 18:27:34 +02:00
parent e27870855f
commit ed33b81089
7 changed files with 1718 additions and 3 deletions

View File

@ -1,6 +1,6 @@
top_builddir=../../../..
include $(top_builddir)/Makefile.config
OBJS = attr.o attributes.o collection.o console.o heartbeat.o history.o keyboard.o localstorage.o location.o mapa.obj message.o navigator.o nodelist.o screen.o unibar.o
OBJS = attr.o attributes.o collection.o console.o heartbeat.o history.o keyboard.o localstorage.o location.o mapa.obj message.o navigator.o nodelist.o screen.o unibar.o xhr.o
include $(top_srcdir)/Makefile.lib

View File

@ -5,9 +5,17 @@
#endif
#include <cstddef>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
#include <vector>
#include "ecmascript/libdom/quickjs/mapa.h"
#include "ecmascript/quickjs.h"
#include "ecmascript/quickjs/xhr.h"
#include "util/memory.h"
#include "util/string.h"
void
attr_save_in_map(void *m, void *node, JSValueConst value)
@ -64,6 +72,29 @@ attr_create_new_nodelist_map(void)
return (void *)mapa;
}
struct classcomp {
bool operator() (const std::string& lhs, const std::string& rhs) const
{
return strcasecmp(lhs.c_str(), rhs.c_str()) < 0;
}
};
void *
attr_create_new_requestHeaders_map(void)
{
std::map<std::string, std::string> *mapa = new std::map<std::string, std::string>;
return (void *)mapa;
}
void *
attr_create_new_responseHeaders_map(void)
{
std::map<std::string, std::string, classcomp> *mapa = new std::map<std::string, std::string, classcomp>;
return (void *)mapa;
}
void *
attr_create_new_nodelist_map_rev(void)
{
@ -79,6 +110,23 @@ attr_clear_map(void *m)
mapa->clear();
}
void
attr_clear_map_str(void *m)
{
std::map<std::string, std::string> *mapa = static_cast<std::map<std::string, std::string> *>(m);
mapa->clear();
}
void
delete_map_str(void *m)
{
std::map<std::string, std::string> *mapa = static_cast<std::map<std::string, std::string> *>(m);
if (mapa) {
delete(mapa);
}
}
JSValue
attr_find_in_map(void *m, void *node)
{
@ -132,8 +180,162 @@ attr_find_in_map_rev(void *m, JSValueConst value)
return v->second;
}
void attr_erase_from_map_rev(void *m, JSValueConst value)
void
attr_erase_from_map_rev(void *m, JSValueConst value)
{
std::map<JSValueConst, void *> *mapa = static_cast<std::map<JSValueConst, void *> *>(m);
mapa->erase(value);
}
static const std::vector<std::string>
explode(const std::string& s, const char& c)
{
std::string buff{""};
std::vector<std::string> v;
bool found = false;
for (auto n:s) {
if (found) {
buff += n;
continue;
}
if (n != c) {
buff += n;
}
else if (n == c && buff != "") {
v.push_back(buff);
buff = "";
found = true;
}
}
if (buff != "") {
v.push_back(buff);
}
return v;
}
static std::map<std::string, std::string> *
get_requestHeaders(void *h)
{
return static_cast<std::map<std::string, std::string> *>(h);
}
static std::map<std::string, std::string, classcomp> *
get_responseHeaders(void *h)
{
return static_cast<std::map<std::string, std::string, classcomp> *>(h);
}
void
process_xhr_headers(char *head, struct Xhr *x)
{
std::istringstream headers(head);
std::string http;
int status;
std::string statusText;
std::string line;
std::getline(headers, line);
std::istringstream linestream(line);
linestream >> http >> status >> statusText;
auto responseHeaders = get_responseHeaders(x->responseHeaders);
while (1) {
std::getline(headers, line);
if (line.empty()) {
break;
}
std::vector<std::string> v = explode(line, ':');
if (v.size() == 2) {
char *value = stracpy(v[1].c_str());
if (!value) {
continue;
}
char *header = stracpy(v[0].c_str());
if (!header) {
mem_free(value);
continue;
}
char *normalized_value = normalize(value);
bool found = false;
for (auto h: *responseHeaders) {
const std::string hh = h.first;
if (!strcasecmp(hh.c_str(), header)) {
(*responseHeaders)[hh] = (*responseHeaders)[hh] + ", " + normalized_value;
found = true;
break;
}
}
if (!found) {
(*responseHeaders)[header] = normalized_value;
}
mem_free(header);
mem_free(value);
}
}
x->status = status;
mem_free_set(&x->status_text, stracpy(statusText.c_str()));
}
void
set_xhr_header(char *normalized_value, const char *h_name, struct Xhr *x)
{
bool found = false;
auto requestHeaders = get_requestHeaders(x->requestHeaders);
for (auto h: *requestHeaders) {
const std::string hh = h.first;
if (!strcasecmp(hh.c_str(), h_name)) {
(*requestHeaders)[hh] = (*requestHeaders)[hh] + ", " + normalized_value;
found = true;
break;
}
}
if (!found) {
(*requestHeaders)[h_name] = normalized_value;
}
}
const char *
get_output_headers(struct Xhr *x)
{
std::string output = "";
auto responseHeaders = get_responseHeaders(x->responseHeaders);
for (auto h: *responseHeaders) {
output += h.first + ": " + h.second + "\r\n";
}
return output.c_str();
}
const char *
get_output_header(const char *header_name, struct Xhr *x)
{
std::string output = "";
auto responseHeaders = get_responseHeaders(x->responseHeaders);
for (auto h: *responseHeaders) {
if (!strcasecmp(header_name, h.first.c_str())) {
output = h.second;
break;
}
}
if (!output.empty()) {
return output.c_str();
}
return NULL;
}

View File

@ -7,6 +7,8 @@
extern "C" {
#endif
struct Xhr;
void attr_save_in_map(void *m, void *node, JSValueConst value);
void *attr_create_new_attrs_map(void);
void *attr_create_new_attributes_map(void);
@ -16,7 +18,13 @@ void *attr_create_new_collections_map_rev(void);
void *attr_create_new_nodelist_map(void);
void *attr_create_new_nodelist_map_rev(void);
void *attr_create_new_requestHeaders_map(void);
void *attr_create_new_responseHeaders_map(void);
void attr_clear_map(void *m);
void attr_clear_map_str(void *m);
void delete_map_str(void *m);
JSValue attr_find_in_map(void *m, void *node);
void attr_erase_from_map(void *m, void *node);
@ -25,6 +33,12 @@ void attr_clear_map_rev(void *m);
void *attr_find_in_map_rev(void *m, JSValueConst value);
void attr_erase_from_map_rev(void *m, JSValueConst value);
void process_xhr_headers(char *head, struct Xhr *x);
void set_xhr_header(char *normalized_value, const char *h_name, struct Xhr *x);
const char *get_output_headers(struct Xhr *x);
const char *get_output_header(const char *header_name, struct Xhr *x);
#ifdef __cplusplus
}
#endif

View File

@ -1 +1 @@
srcs += files('attr.c', 'attributes.c', 'collection.c', 'console.c', 'heartbeat.c', 'history.c', 'keyboard.c', 'localstorage.c', 'location.c', 'mapa.cpp', 'message.c', 'navigator.c', 'nodelist.c', 'screen.c', 'unibar.c')
srcs += files('attr.c', 'attributes.c', 'collection.c', 'console.c', 'heartbeat.c', 'history.c', 'keyboard.c', 'localstorage.c', 'location.c', 'mapa.cpp', 'message.c', 'navigator.c', 'nodelist.c', 'screen.c', 'unibar.c', 'xhr.c')

File diff suppressed because it is too large Load Diff

View File

@ -79,6 +79,8 @@
#include <sstream>
#include <vector>
#ifndef CONFIG_LIBDOM
#define countof(x) (sizeof(x) / sizeof((x)[0]))
enum {
@ -1611,3 +1613,4 @@ js_xhr_init(JSContext *ctx)
return 0;
}
#endif

View File

@ -2,7 +2,88 @@
#define EL__ECMASCRIPT_QUICKJS_XHR_H
#include <quickjs/quickjs.h>
#include "session/download.h"
#include "util/lists.h"
#ifdef __cplusplus
extern "C" {
#endif
enum {
XHR_EVENT_ABORT = 0,
XHR_EVENT_ERROR,
XHR_EVENT_LOAD,
XHR_EVENT_LOAD_END,
XHR_EVENT_LOAD_START,
XHR_EVENT_PROGRESS,
XHR_EVENT_READY_STATE_CHANGED,
XHR_EVENT_TIMEOUT,
XHR_EVENT_MAX,
};
enum {
XHR_RSTATE_UNSENT = 0,
XHR_RSTATE_OPENED,
XHR_RSTATE_HEADERS_RECEIVED,
XHR_RSTATE_LOADING,
XHR_RSTATE_DONE,
};
enum {
XHR_RTYPE_DEFAULT = 0,
XHR_RTYPE_TEXT,
XHR_RTYPE_ARRAY_BUFFER,
XHR_RTYPE_JSON,
};
struct emcascript_interpreter;
struct xhr_listener {
LIST_HEAD(struct xhr_listener);
char *typ;
JSValue fun;
};
struct Xhr {
// std::map<std::string, std::string> requestHeaders;
// std::map<std::string, std::string, classcomp> responseHeaders;
void *requestHeaders;
void *responseHeaders;
struct download download;
struct ecmascript_interpreter *interpreter;
LIST_OF(struct xhr_listener) listeners;
JSValue events[XHR_EVENT_MAX];
JSValue thisVal;
struct uri *uri;
bool sent;
bool async;
short response_type;
unsigned long timeout;
unsigned short ready_state;
int status;
char *status_text;
char *response_text;
size_t response_length;
struct {
JSValue url;
JSValue headers;
JSValue response;
} result;
char *responseURL;
int method;
};
int js_xhr_init(JSContext *ctx);
char *normalize(char *value);
#ifdef __cplusplus
}
#endif
#endif