- struct afb_context context;
- int refcount;
- struct afb_ws_json1 *aws;
- struct afb_wsreq *next;
- char *text;
- size_t size;
- int code;
- char *id;
- size_t idlen;
- char *api;
- size_t apilen;
- char *verb;
- size_t verblen;
- char *obj;
- size_t objlen;
- char *tok;
- size_t toklen;
- struct json_object *root;
-};
-
-static void wsreq_addref(struct afb_wsreq *wsreq);
-static void wsreq_unref(struct afb_wsreq *wsreq);
-static struct json_object *wsreq_json(struct afb_wsreq *wsreq);
-static struct afb_arg wsreq_get(struct afb_wsreq *wsreq, const char *name);
-static void wsreq_fail(struct afb_wsreq *wsreq, const char *status, const char *info);
-static void wsreq_success(struct afb_wsreq *wsreq, struct json_object *obj, const char *info);
-static const char *wsreq_raw(struct afb_wsreq *wsreq, size_t *size);
-static void wsreq_send(struct afb_wsreq *wsreq, const char *buffer, size_t size);
-
-
-static const struct afb_req_itf wsreq_itf = {
- .json = (void*)wsreq_json,
- .get = (void*)wsreq_get,
- .success = (void*)wsreq_success,
- .fail = (void*)wsreq_fail,
- .raw = (void*)wsreq_raw,
- .send = (void*)wsreq_send,
- .context_get = (void*)afb_context_get,
- .context_set = (void*)afb_context_set,
- .addref = (void*)wsreq_addref,
- .unref = (void*)wsreq_unref,
- .session_close = (void*)afb_context_close,
- .session_set_LOA = (void*)afb_context_change_loa
-};
-
-static int aws_wsreq_parse(struct afb_wsreq *r, char *text, size_t size)
-{
- char *pos, *end, c;
- int aux;
-
- /* scan */
- pos = text;
- end = text + size;
-
- /* scans: [ */
- while(pos < end && *pos == ' ') pos++;
- if (pos == end) goto bad_header;
- if (*pos++ != '[') goto bad_header;
-
- /* scans code: 2|3|4 */
- while(pos < end && *pos == ' ') pos++;
- if (pos == end) goto bad_header;
- switch (*pos++) {
- case '2': r->code = CALL; break;
- case '3': r->code = RETOK; break;
- case '4': r->code = RETERR; break;
- default: goto bad_header;
- }
-
- /* scans: , */
- while(pos < end && *pos == ' ') pos++;
- if (pos == end) goto bad_header;
- if (*pos++ != ',') goto bad_header;
-
- /* scans id: "id" */
- while(pos < end && *pos == ' ') pos++;
- if (pos == end) goto bad_header;
- if (*pos++ != '"') goto bad_header;
- r->id = pos;
- while(pos < end && *pos != '"') pos++;
- if (pos == end) goto bad_header;
- r->idlen = (size_t)(pos++ - r->id);
-
- /* scans: , */
- while(pos < end && *pos == ' ') pos++;
- if (pos == end) goto bad_header;
- if (*pos++ != ',') goto bad_header;
-
- /* scans the method if needed */
- if (r->code == CALL) {
- /* scans: " */
- while(pos < end && *pos == ' ') pos++;
- if (pos == end) goto bad_header;
- if (*pos++ != '"') goto bad_header;
-
- /* scans: api/ */
- r->api = pos;
- while(pos < end && *pos != '"' && *pos != '/') pos++;
- if (pos == end) goto bad_header;
- if (*pos != '/') goto bad_header;
- r->apilen = (size_t)(pos++ - r->api);
- if (r->apilen && r->api[r->apilen - 1] == '\\')
- r->apilen--;
-
- /* scans: verb" */
- r->verb = pos;
- while(pos < end && *pos != '"') pos++;
- if (pos == end) goto bad_header;
- r->verblen = (size_t)(pos++ - r->verb);
-
- /* scans: , */
- while(pos < end && *pos == ' ') pos++;
- if (pos == end) goto bad_header;
- if (*pos++ != ',') goto bad_header;
- }
-
- /* scan obj */
- while(pos < end && *pos == ' ') pos++;
- if (pos == end) goto bad_header;
- aux = 0;
- r->obj = pos;
- while (pos < end && (aux != 0 || (*pos != ',' && *pos != ']'))) {
- if (pos == end) goto bad_header;
- switch(*pos) {
- case '{': case '[': aux++; break;
- case '}': case ']': if (!aux--) goto bad_header; break;
- case '"':
- do {
- pos += 1 + (*pos == '\\');
- } while(pos < end && *pos != '"');
- default:
- break;
- }
- pos++;