open/read work on url file!!!

Use string keys for opcodes to simplify the code.
This commit is contained in:
Omar Rizwan 2018-11-23 22:15:29 -08:00
parent b6f46e166d
commit 528467a55b
2 changed files with 141 additions and 61 deletions

View file

@ -1,14 +1,5 @@
const ws = new WebSocket("ws://localhost:8888");
const ops = {
NONE: 0,
GETATTR: 1,
OPEN: 2,
READDIR: 3,
READ: 4
};
const unix = {
EPERM: 1,
ENOENT: 2,
@ -34,10 +25,51 @@ function UnixError(error) {
}
UnixError.prototype = Error.prototype;
function getTab(id) {
return new Promise((resolve, reject) => chrome.tabs.get(id, resolve));
}
function queryTabs() {
return new Promise((resolve, reject) => chrome.tabs.query({}, resolve));
}
function sendDebuggerCommand(tab, method, commandParams) {
return new Promise(resolve => chrome.debugger.sendCommand({tabId: id}, method, commandParams, resolve));
}
const fhManager = (function() {
const handles = {};
let nextFh = 0;
return {
allocate(obj) { // -> fh
const fh = nextFh++;
handles[fh] = obj;
return fh;
},
ref(fh) {
if (!handles[fh]) throw new UnixError(unix.EIO);
return handles[fh];
},
free(fh) {
delete handles[fh];
}
};
})();
// tabs/by-id/ID/title
// tabs/by-id/ID/url
// tabs/by-id/ID/console
// tabs/by-id/ID/mem (?)
// tabs/by-id/ID/cpu (?)
// tabs/by-id/ID/screenshot.png
// tabs/by-id/ID/printed.pdf
// tabs/by-id/ID/control
// tabs/by-id/ID/sources/
function pathComponent(path, i) {
const components = path.split('/');
return components[i >= 0 ? i : components.length + i];
}
const router = {
"tabs": {
"by-id": {
@ -47,13 +79,34 @@ const router = {
},
"*": {
async getattr() {
return {
st_mode: unix.S_IFREG | 0444,
st_nlink: 1,
st_size: 10 // FIXME
};
}
"url": {
async getattr() {
return {
st_mode: unix.S_IFREG | 0444,
st_nlink: 1,
st_size: 100 // FIXME
};
},
async open(path) {
return fhManager.allocate(await getTab(parseInt(pathComponent(path, -2))));
},
async read(path, fh, size, offset) {
const tab = fhManager.ref(fh);
return tab.url.substr(offset, size);
},
async release(path, fh) {
fhManager.free(fh);
}
},
/* "title": fileFromProperty('title'),
* "sources": folderFromResource(
* (tab, path) => new Promise(resolve => chrome.debugger.attach(
* { tabId: tab.id }, "1-3", resolve)),
* {
* readdir() {
* }
* }*/
}
}
}
@ -73,7 +126,7 @@ function findRoute(path) {
async function getattr(path) {
let route = findRoute(path);
if (route.getattr) {
return route.getattr();
return route.getattr(path);
} else {
return {
st_mode: unix.S_IFDIR | 0755,
@ -84,39 +137,62 @@ async function getattr(path) {
async function readdir(path) {
let route = findRoute(path);
if (route.readdir) {
return route.readdir();
}
if (route.readdir) return route.readdir(path);
return Object.keys(route);
}
async function open(path) {
let route = findRoute(path);
if (route.open) return route.open(path);
}
async function read(path, fh, size, offset) {
let route = findRoute(path);
if (route.read) return route.read(path, fh, size, offset);
}
async function release(path, fh) {
let route = findRoute(path);
if (route.read) return route.release(path, fh);
}
ws.onmessage = async function(event) {
const req = JSON.parse(event.data);
console.log('req', Object.entries(ops).find(([op, opcode]) => opcode === req.op)[0], req);
let response = { op: req.op, error: unix.EIO };
try {
if (req.op === ops.GETATTR) {
if (req.op === 'getattr') {
response = {
op: ops.GETATTR,
op: 'getattr',
st_mode: 0,
st_nlink: 0,
st_size: 0,
...(await getattr(req.path))
};
} else if (req.op === ops.OPEN) {
throw new UnixError(unix.EIO);
} else if (req.op === ops.READDIR) {
} else if (req.op === 'open') {
response = {
op: ops.READDIR,
op: 'open',
fh: await open(req.path)
};
} else if (req.op === 'readdir') {
response = {
op: 'readdir',
entries: [".", "..", ...(await readdir(req.path))]
};
} else if (req.op === ops.READ) {
} else if (req.op === 'read') {
const buf = await read(req.path, req.fh, req.size, req.offset)
response = {
op: ops.READ,
buf: await read(req.path)
op: 'read',
buf,
size: buf.length
};
} else if (req.op === 'release') {
await release(req.path, req.fh);
response = {
op: 'release'
};
}
@ -127,6 +203,5 @@ ws.onmessage = async function(event) {
}
}
console.log('response', Object.entries(ops).find(([op, opcode]) => opcode === response.op)[0], response);
ws.send(JSON.stringify(response));
};

View file

@ -20,15 +20,6 @@ struct wby_con *con = NULL;
pthread_mutex_t request_data_mutex = PTHREAD_MUTEX_INITIALIZER;
char *request_data = NULL;
enum opcode {
NONE = 0,
GETATTR,
OPEN,
READDIR,
READ
};
pthread_cond_t response_cv = PTHREAD_COND_INITIALIZER;
pthread_mutex_t response_mutex = PTHREAD_MUTEX_INITIALIZER;
cJSON *response = NULL;
@ -88,7 +79,7 @@ static cJSON *await_response() {
if (disconnected) { ret = -EIO; goto done; } \
\
req = cJSON_CreateObject(); \
cJSON_AddNumberToObject(req, "op", (int) op); \
cJSON_AddStringToObject(req, "op", op); \
req_body \
\
dispatch_send_req(req); \
@ -101,9 +92,9 @@ static cJSON *await_response() {
if (ret != 0) goto done; \
} \
\
ret = -1; \
resp_handler \
\
ret = 0; \
done: \
if (req != NULL) cJSON_Delete(req); \
if (resp != NULL) cJSON_Delete(resp); \
@ -121,25 +112,29 @@ hello_getattr(const char *path, struct stat *stbuf)
memset(stbuf, 0, sizeof(struct stat));
printf("\n\ngetattr(%s)\n", path);
MAKE_REQ(GETATTR, {
MAKE_REQ("getattr", {
cJSON_AddStringToObject(req, "path", path);
}, {
JSON_GET_PROP_INT(stbuf->st_mode, "st_mode");
JSON_GET_PROP_INT(stbuf->st_nlink, "st_nlink");
JSON_GET_PROP_INT(stbuf->st_size, "st_size");
printf("returning re getattr(%s)\n", path);
ret = 0;
});
}
static int
hello_open(const char *path, struct fuse_file_info *fi)
{
MAKE_REQ(OPEN, {
MAKE_REQ("open", {
cJSON_AddStringToObject(req, "path", path);
cJSON_AddNumberToObject(req, "flags", fi->flags);
}, {
cJSON *fh_item = cJSON_GetObjectItemCaseSensitive(resp, "fh");
if (fh_item) fi->fh = fh_item->valueint;
ret = 0;
});
}
@ -149,8 +144,8 @@ hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
{
printf("\n\nreaddir(%s)\n", path);
// send {op: READDIR, path} to the websocket handler
MAKE_REQ(READDIR, {
// send {op: "readdir", path} to the websocket handler
MAKE_REQ("readdir", {
cJSON_AddStringToObject(req, "path", path);
}, {
cJSON *entries = cJSON_GetObjectItemCaseSensitive(resp, "entries");
@ -159,6 +154,8 @@ hello_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
filler(buf, cJSON_GetStringValue(entry), NULL, 0);
printf("entry: [%s]\n", cJSON_GetStringValue(entry));
}
ret = 0;
});
}
@ -166,7 +163,7 @@ static int
hello_read(const char *path, char *buf, size_t size, off_t offset,
struct fuse_file_info *fi)
{
MAKE_REQ(OPEN, {
MAKE_REQ("read", {
cJSON_AddStringToObject(req, "path", path);
cJSON_AddNumberToObject(req, "size", size);
cJSON_AddNumberToObject(req, "offset", offset);
@ -174,27 +171,35 @@ hello_read(const char *path, char *buf, size_t size, off_t offset,
cJSON_AddNumberToObject(req, "fh", fi->fh);
cJSON_AddNumberToObject(req, "flags", fi->flags);
}, {
size_t resp_size;
JSON_GET_PROP_INT(resp_size, "size");
size = resp_size < size ? resp_size : size;
cJSON *resp_buf_item = cJSON_GetObjectItemCaseSensitive(resp, "buf");
char *resp_buf = cJSON_GetStringValue(resp_buf_item);
size_t resp_buf_len = strlen(resp_buf);
size = resp_buf_len < size ? resp_buf_len : size;
memcpy(buf, resp_buf, size);
ret = size;
});
}
if (strcmp(path, file_path) != 0)
return -ENOENT;
if (offset >= file_size) /* Trying to read past the end of file. */
return 0;
if (offset + size > file_size) /* Trim the read to the file size. */
size = file_size - offset;
memcpy(buf, file_content + offset, size); /* Provide the content. */
return size;
static int hello_release(const char *path, struct fuse_file_info *fi) {
MAKE_REQ("release", {
cJSON_AddStringToObject(req, "path", path);
cJSON_AddNumberToObject(req, "fh", fi->fh);
}, {
ret = 0;
});
}
static struct fuse_operations hello_filesystem_operations = {
.getattr = hello_getattr, /* To provide size, permissions, etc. */
.open = hello_open, /* To enforce read-only access. */
.read = hello_read, /* To provide file content. */
.release = hello_release,
.readdir = hello_readdir, /* To provide directory listing. */
};