static int http_get_request(struct http_request *r) { struct cos_array *arg; int ret; assert(r && r->c); arg = cos_argreg_alloc(r->path_len + sizeof(struct cos_array) + 1); assert(arg); memcpy(arg->mem, r->path, r->path_len); arg->sz = r->path_len; arg->mem[arg->sz] = '\0'; if (0 > r->content_id ) { r->content_id = content_open(cos_spd_id(), r->c->evt_id, arg); if (r->content_id < 0) { cos_argreg_free(arg); return r->content_id; } } ret = content_request(cos_spd_id(), r->content_id, arg); cos_argreg_free(arg); return ret; }
static int create_thd(const char *pri) { struct cos_array *data; int event_thd; int sz = strlen(pri) + 1; data = cos_argreg_alloc(sizeof(struct cos_array) + sz); assert(data); strcpy(&data->mem[0], pri); //data->sz = 4; data->sz = sz; if (0 > (event_thd = sched_create_thread(cos_spd_id(), data))) assert(0); cos_argreg_free(data); return event_thd; }
static void to_data_new(struct tor_conn *tc) { int from, to, amnt; char *buf; from = tc->from; to = tc->to; buf = cos_argreg_alloc(BUFF_SZ); assert(buf); while (1) { int ret; amnt = tread_pack(cos_spd_id(), to, buf, BUFF_SZ-1); if (0 == amnt) break; else if (-EPIPE == amnt) { goto close; } else if (amnt < 0) { printc("read from fd %d produced %d.\n", from, amnt); BUG(); } if (amnt != (ret = net_send(cos_spd_id(), from, buf, amnt))) { printc("conn_mgr: write failed w/ %d on fd %d\n", ret, to); goto close; } } done: cos_argreg_free(buf); return; close: net_close(cos_spd_id(), from); trelease(cos_spd_id(), to); tor_del_pair(from, to); if (tc->feid) cvect_del(&evts, tc->feid); if (tc->teid) cvect_del(&evts, tc->teid); goto done; }
static int connection_get_reply(struct connection *c, char *resp, int resp_sz) { struct http_request *r; int used = 0; /* * Currently, this doesn't do anything interesting. In the * future it will call the content provider and get the * (ready) response. */ r = c->pending_reqs; if (NULL == r) return 0; while (r) { struct http_request *next; struct cos_array *arr = NULL; char *local_resp; int *more = NULL; int local_more, consumed, ret, local_resp_sz; assert(r->c == c); if (r->flags & HTTP_REQ_PENDING) break; assert(r->flags & HTTP_REQ_PROCESSED); assert(r->content_id >= 0); /* Previously saved response? */ if (NULL != r->resp.resp) { local_resp = r->resp.resp; local_resp_sz = r->resp.resp_len; local_more = r->resp.more; } else { /* Make the request to the content * component */ more = cos_argreg_alloc(sizeof(int)); assert(more); arr = cos_argreg_alloc(sizeof(struct cos_array) + resp_sz - used); assert(arr); arr->sz = resp_sz - used; if ((ret = content_retrieve(cos_spd_id(), r->content_id, arr, more))) { cos_argreg_free(arr); cos_argreg_free(more); if (0 > ret) { BUG(); /* FIXME send an error message. */ } printc("https get reply returning %d.\n", ret); return ret; } local_more = *more; local_resp_sz = arr->sz; local_resp = arr->mem; } /* still more date, but not available now... */ if (local_resp_sz == 0) { cos_argreg_free(arr); cos_argreg_free(more); break; } /* If the header and data couldn't fit into the * provided buffer, then we need to save the response, * so that we can send it out later... */ if (http_get_header(resp+used, resp_sz-used, local_resp_sz, &consumed)) { if (NULL == r->resp.resp) { char *save; save = malloc(local_resp_sz); assert(save); assert(arr); memcpy(save, arr->mem, local_resp_sz); cos_argreg_free(arr); r->resp.more = *more; cos_argreg_free(more); r->resp.resp = save; r->resp.resp_len = local_resp_sz; } if (0 == used) { printc("https: could not allocate either header or response of sz %d:%s\n", local_resp_sz, local_resp); if (arr) cos_argreg_free(arr); if (more) cos_argreg_free(more); return -ENOMEM; } break; } memcpy(resp+used+consumed, local_resp, local_resp_sz); if (arr) cos_argreg_free(arr); if (more) cos_argreg_free(more); more = NULL; arr = NULL; used += local_resp_sz + consumed; next = r->next; /* bookkeeping */ http_req_cnt++; http_free_request(r); r = c->pending_reqs; assert(r == next || NULL == r); } return used; }