void one_add(struct tcuplinks *ups, struct uplink*up) { int hash; struct uplink *nup; nup = mem_alloc(sizeof(struct uplink), uplink_de); if(!nup) return; memcpy(nup, up, sizeof(struct uplink)); memset(nup, 0, sizeof(struct le)); mem_ref((void*)nup->uri.p); hash = hash_joaat_ci(up->uri.p, up->uri.l); void *found; found = hash_lookup(ups->data_c, hash, apply_find, NULL); hash_append(ups->uris_c, hash, &nup->le, nup); if (ups->up_h == NULL) { return; } if(found) { ups->up_h(up, 2, ups->up_arg); } else { ups->up_h(up, 1, ups->up_arg); } }
void one_rm(struct tcuplinks *ups, struct uplink*up) { void *found=NULL; int hash; hash = hash_joaat_ci(up->uri.p, up->uri.l); found = hash_lookup(ups->uris_c, hash, apply_find, NULL); if(!found) ups->up_h(up, 0, ups->up_arg); }
int parse_headers(struct request *req, char *start, size_t len, struct pl *body) { int br=0; size_t *ct; enum http_hdr_id id; char *p = start; struct pl header, hval; header.p = start; header.l = 0; hval.p = NULL; hval.l = -2; ct = &header.l; while(len) { switch(*p) { case '\n': case '\r': br++; break; case ':': if(ct == &header.l) { ct = &hval.l; hval.p = p+2; } default: br = 0; } if(br) { if(header.l) { id = (enum http_hdr_id)hash_joaat_ci(header.p, header.l) & 0xFFF; hdr_add(req, id, &header, &hval); } header.p = p+1; header.l = -1; hval.l = -2; ct = &header.l; hval.p = NULL; } p++; (*ct)++; len--; if(br>3) { body->p = p; body->l = len; } } return 0; }
static enum sip_hdrid hdr_hash(const struct pl *name) { if (!name->l) return SIP_HDR_NONE; if (name->l > 1) { switch (name->p[0]) { case 'x': case 'X': if (name->p[1] == '-') return SIP_HDR_NONE; /*@fallthrough@*/ default: return (enum sip_hdrid) (hash_joaat_ci(name->p, name->l) & 0xfff); } } /* compact headers */ switch (tolower(name->p[0])) { case 'a': return SIP_HDR_ACCEPT_CONTACT; case 'b': return SIP_HDR_REFERRED_BY; case 'c': return SIP_HDR_CONTENT_TYPE; case 'd': return SIP_HDR_REQUEST_DISPOSITION; case 'e': return SIP_HDR_CONTENT_ENCODING; case 'f': return SIP_HDR_FROM; case 'i': return SIP_HDR_CALL_ID; case 'j': return SIP_HDR_REJECT_CONTACT; case 'k': return SIP_HDR_SUPPORTED; case 'l': return SIP_HDR_CONTENT_LENGTH; case 'm': return SIP_HDR_CONTACT; case 'n': return SIP_HDR_IDENTITY_INFO; case 'o': return SIP_HDR_EVENT; case 'r': return SIP_HDR_REFER_TO; case 's': return SIP_HDR_SUBJECT; case 't': return SIP_HDR_TO; case 'u': return SIP_HDR_ALLOW_EVENTS; case 'v': return SIP_HDR_VIA; case 'x': return SIP_HDR_SESSION_EXPIRES; case 'y': return SIP_HDR_IDENTITY; default: return SIP_HDR_NONE; } }
static enum http_hdrid hdr_hash(const struct pl *name) { if (!name->l) return HTTP_HDR_NONE; switch (name->p[0]) { case 'x': case 'X': if (name->l > 1 && name->p[1] == '-') return HTTP_HDR_NONE; break; } return (enum http_hdrid)(hash_joaat_ci(name->p, name->l) & 0xfff); }
void http_header(struct request *request, char* hname, char* val) { enum http_hdr_id id; struct http_hdr *hdr; char *tmp; hdr = mem_zalloc(sizeof(struct http_hdr), hdr_destruct2); re_sdprintf(&tmp, "%s", hname); pl_set_str(&hdr->name, tmp); re_sdprintf(&tmp, "%s", val); pl_set_str(&hdr->val, tmp); id = (enum http_hdr_id)hash_joaat_ci(hdr->name.p, hdr->name.l); id &= 0xFFF; hash_append(request->hdrht, id, &hdr->he, hdr); }
void http_request_h(struct http_conn *conn, const struct http_msg *msg, void *arg) { int err; enum app_cmd cmd; const struct http_hdr * expect_hdr; struct mbuf *mb = msg->mb; uint8_t *ret_buf; size_t ret_len; if(pl_strcmp(&msg->met, "POST")) { http_creply(conn, 405, "Method not allowed", "text/plain", "EMET"); return; } expect_hdr = http_msg_hdr(msg, HTTP_HDR_EXPECT); if(expect_hdr != NULL && version_cmp(version, &expect_hdr->val) < 0) { http_creply(conn, 417, "Expectation Failed", "text/plain", "%s", version); return; } cmd = (enum app_cmd)(hash_joaat_ci(msg->path.p, msg->path.l) & 0xfff); err = app_handle(cmd, mbuf_buf(mb), mbuf_get_left(mb), &ret_buf, &ret_len); if(err < 0) { http_creply(conn, 500, "Internal Server Error", "text/plain", "EINT"); return; } if(err > 200) { http_creply(conn, err, "Error", "text/plain", "NO", 2); return; } if(err == 0) { http_creply(conn, 200, "OK", "text/plain; charset=utf-8", "%b", ret_buf, ret_len); } else { http_creply(conn, 403, "Forbidden", "text/plain", "%b", ret_buf, ret_len); } free(ret_buf); }
/** * Calculate hash-value for a case-insensitive pointer-length object * * @param pl Pointer-length object * * @return Calculated hash-value */ uint32_t hash_joaat_pl_ci(const struct pl *pl) { return pl ? hash_joaat_ci(pl->p, pl->l) : 0; }