mirror of
https://github.com/rkd77/elinks.git
synced 2025-01-03 14:57:44 -05:00
[quikcjs] libdom xhr.c
This commit is contained in:
parent
e27870855f
commit
ed33b81089
@ -1,6 +1,6 @@
|
|||||||
top_builddir=../../../..
|
top_builddir=../../../..
|
||||||
include $(top_builddir)/Makefile.config
|
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
|
include $(top_srcdir)/Makefile.lib
|
||||||
|
@ -5,9 +5,17 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <sstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "ecmascript/libdom/quickjs/mapa.h"
|
#include "ecmascript/libdom/quickjs/mapa.h"
|
||||||
#include "ecmascript/quickjs.h"
|
#include "ecmascript/quickjs.h"
|
||||||
|
#include "ecmascript/quickjs/xhr.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "util/string.h"
|
||||||
|
|
||||||
void
|
void
|
||||||
attr_save_in_map(void *m, void *node, JSValueConst value)
|
attr_save_in_map(void *m, void *node, JSValueConst value)
|
||||||
@ -64,6 +72,29 @@ attr_create_new_nodelist_map(void)
|
|||||||
return (void *)mapa;
|
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 *
|
void *
|
||||||
attr_create_new_nodelist_map_rev(void)
|
attr_create_new_nodelist_map_rev(void)
|
||||||
{
|
{
|
||||||
@ -79,6 +110,23 @@ attr_clear_map(void *m)
|
|||||||
mapa->clear();
|
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
|
JSValue
|
||||||
attr_find_in_map(void *m, void *node)
|
attr_find_in_map(void *m, void *node)
|
||||||
{
|
{
|
||||||
@ -132,8 +180,162 @@ attr_find_in_map_rev(void *m, JSValueConst value)
|
|||||||
return v->second;
|
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);
|
std::map<JSValueConst, void *> *mapa = static_cast<std::map<JSValueConst, void *> *>(m);
|
||||||
mapa->erase(value);
|
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;
|
||||||
|
}
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct Xhr;
|
||||||
|
|
||||||
void attr_save_in_map(void *m, void *node, JSValueConst value);
|
void attr_save_in_map(void *m, void *node, JSValueConst value);
|
||||||
void *attr_create_new_attrs_map(void);
|
void *attr_create_new_attrs_map(void);
|
||||||
void *attr_create_new_attributes_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(void);
|
||||||
void *attr_create_new_nodelist_map_rev(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(void *m);
|
||||||
|
void attr_clear_map_str(void *m);
|
||||||
|
void delete_map_str(void *m);
|
||||||
|
|
||||||
JSValue attr_find_in_map(void *m, void *node);
|
JSValue attr_find_in_map(void *m, void *node);
|
||||||
void attr_erase_from_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_find_in_map_rev(void *m, JSValueConst value);
|
||||||
void attr_erase_from_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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -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')
|
||||||
|
1415
src/ecmascript/libdom/quickjs/xhr.c
Normal file
1415
src/ecmascript/libdom/quickjs/xhr.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -79,6 +79,8 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#ifndef CONFIG_LIBDOM
|
||||||
|
|
||||||
#define countof(x) (sizeof(x) / sizeof((x)[0]))
|
#define countof(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -1611,3 +1613,4 @@ js_xhr_init(JSContext *ctx)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
@ -2,7 +2,88 @@
|
|||||||
#define EL__ECMASCRIPT_QUICKJS_XHR_H
|
#define EL__ECMASCRIPT_QUICKJS_XHR_H
|
||||||
|
|
||||||
#include <quickjs/quickjs.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);
|
int js_xhr_init(JSContext *ctx);
|
||||||
|
char *normalize(char *value);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user