int tread(spdid_t spdid, td_t td, int cbid, int sz) { td_t ntd; struct torrent *t; char *buf, *nbuf; int ret = -1; cbuf_t ncbid; if (tor_isnull(td)) return -EINVAL; t = tor_lookup(td); if (!t) ERR_THROW(-EINVAL, done); if (!(t->flags & TOR_WRITE)) ERR_THROW(-EACCES, done); assert(t->data); ntd = (td_t)t->data; buf = cbuf2buf(cbid, sz); if (!buf) ERR_THROW(-EINVAL, done); nbuf = cbuf_alloc(sz, &ncbid); assert(nbuf); /* printc("tip_tif_tread (thd %d)\n", cos_get_thd_id()); */ ret = server_tread(cos_spd_id(), ntd, ncbid, sz); if (ret < 0) goto free; /* ip_tread_cnt++; */ memcpy(buf, nbuf, ret); free: /* cbufp_deref(ncbid); */ // should keep this cbufp alive in netif for FT purpose? Jiguo cbuf_free(ncbid); done: return ret; }
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; char *local_resp; cbuf_t cb; int 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; } else { int sz; /* Make the request to the content * component */ sz = resp_sz - used; local_resp = cbuf_alloc(sz, &cb); if (!local_resp) BUG(); ret = server_tread(cos_spd_id(), r->content_id, cb, sz); if (ret < 0) { cbuf_free(local_resp); printc("https get reply returning %d.\n", ret); return ret; } local_resp_sz = ret; } /* no more data */ if (local_resp_sz == 0) { cbuf_free(local_resp); 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(local_resp); memcpy(save, local_resp, local_resp_sz); cbuf_free(local_resp); local_resp = NULL; 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 (local_resp) cbuf_free(local_resp); return -ENOMEM; } break; } memcpy(resp+used+consumed, local_resp, local_resp_sz); assert(local_resp); cbuf_free(local_resp); local_resp = 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; }