static isc_result_t gssapi_adddata(dst_context_t *dctx, const isc_region_t *data) { gssapi_ctx_t *ctx = dctx->opaque; isc_buffer_t *newbuffer = NULL; isc_region_t r; unsigned int length; isc_result_t result; result = isc_buffer_copyregion(ctx->buffer, data); if (result == ISC_R_SUCCESS) return (ISC_R_SUCCESS); length = isc_buffer_length(ctx->buffer) + data->length + BUFFER_EXTRA; result = isc_buffer_allocate(dctx->mctx, &newbuffer, length); if (result != ISC_R_SUCCESS) return (result); isc_buffer_usedregion(ctx->buffer, &r); (void) isc_buffer_copyregion(newbuffer, &r); (void) isc_buffer_copyregion(newbuffer, data); isc_buffer_free(&ctx->buffer); ctx->buffer = newbuffer; return (ISC_R_SUCCESS); }
/** * @pre closure points to a valid isc_buffer * @pre isc_buffer has non-NULL mctx * @pre isc_buffer has NULL buffer OR a buffer allocated from mctx * * @post closure contains \0 terminated string which is concatenation * of previous context and input text */ static void buffer_append_str(void *closure, const char *text, int textlen) { isc_buffer_t *out_buf = closure; isc_region_t new_space; isc_region_t old_space; REQUIRE(ISC_BUFFER_VALID(out_buf)); REQUIRE(out_buf->mctx != NULL); REQUIRE(text != NULL); /* Allocate sufficiently long output buffer. */ isc_buffer_region(out_buf, &old_space); new_space.length = isc_buffer_length(out_buf) + textlen + 1; new_space.base = isc_mem_get(out_buf->mctx, new_space.length); RUNTIME_CHECK(new_space.base != NULL); isc_buffer_reinit(out_buf, new_space.base, new_space.length); if (old_space.base != NULL) isc_mem_put(out_buf->mctx, old_space.base, old_space.length); /* Append output text and \0-terminate it. * Overwrite \0 at the end if needed. */ if (isc_buffer_usedlength(out_buf) != 0) /* Previous string is \0 terminated, chop \0. */ isc_buffer_subtract(out_buf, 1); isc_buffer_putstr(out_buf, text); isc_buffer_putuint8(out_buf, '\0'); }
static void isc_httpd_senddone(isc_task_t *task, isc_event_t *ev) { isc_httpd_t *httpd = ev->ev_arg; isc_region_t r; isc_socketevent_t *sev = (isc_socketevent_t *)ev; ENTER("senddone"); INSIST(ISC_HTTPD_ISSEND(httpd)); /* * First, unlink our header buffer from the socket's bufflist. This * is sort of an evil hack, since we know our buffer will be there, * and we know it's address, so we can just remove it directly. */ NOTICE("senddone unlinked header"); ISC_LIST_UNLINK(sev->bufferlist, &httpd->headerbuffer, link); /* * We will always want to clean up our receive buffer, even if we * got an error on send or we are shutting down. * * We will pass in the buffer only if there is data in it. If * there is no data, we will pass in a NULL. */ if (httpd->freecb != NULL) { isc_buffer_t *b = NULL; if (isc_buffer_length(&httpd->bodybuffer) > 0) b = &httpd->bodybuffer; httpd->freecb(b, httpd->freecb_arg); NOTICE("senddone free callback performed"); } if (ISC_LINK_LINKED(&httpd->bodybuffer, link)) { ISC_LIST_UNLINK(sev->bufferlist, &httpd->bodybuffer, link); NOTICE("senddone body buffer unlinked"); } if (sev->result != ISC_R_SUCCESS) { destroy_client(&httpd); goto out; } if ((httpd->flags & HTTPD_CLOSE) != 0) { destroy_client(&httpd); goto out; } ISC_HTTPD_SETRECV(httpd); NOTICE("senddone restarting recv on socket"); reset_client(httpd); r.base = (unsigned char *)httpd->recvbuf; r.length = HTTP_RECVLEN - 1; /* check return code? */ (void)isc_socket_recv(httpd->sock, &r, 1, task, isc_httpd_recvdone, httpd); out: isc_event_free(&ev); EXIT("senddone"); }
static void isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) { isc_region_t r; isc_result_t result; isc_httpd_t *httpd = ev->ev_arg; isc_socketevent_t *sev = (isc_socketevent_t *)ev; isc_httpdurl_t *url; isc_time_t now; char datebuf[32]; /* Only need 30, but safety first */ ENTER("recv"); INSIST(ISC_HTTPD_ISRECV(httpd)); if (sev->result != ISC_R_SUCCESS) { NOTICE("recv destroying client"); destroy_client(&httpd); goto out; } result = process_request(httpd, sev->n); if (result == ISC_R_NOTFOUND) { if (httpd->recvlen >= HTTP_RECVLEN - 1) { destroy_client(&httpd); goto out; } r.base = (unsigned char *)httpd->recvbuf + httpd->recvlen; r.length = HTTP_RECVLEN - httpd->recvlen - 1; /* check return code? */ (void)isc_socket_recv(httpd->sock, &r, 1, task, isc_httpd_recvdone, httpd); goto out; } else if (result != ISC_R_SUCCESS) { destroy_client(&httpd); goto out; } ISC_HTTPD_SETSEND(httpd); /* * XXXMLG Call function here. Provide an add-header function * which will append the common headers to a response we generate. */ isc_buffer_initnull(&httpd->bodybuffer); isc_time_now(&now); isc_time_formathttptimestamp(&now, datebuf, sizeof(datebuf)); url = ISC_LIST_HEAD(httpd->mgr->urls); while (url != NULL) { if (strcmp(httpd->url, url->url) == 0) break; url = ISC_LIST_NEXT(url, link); } if (url == NULL) result = httpd->mgr->render_404(httpd->url, NULL, httpd->querystring, NULL, NULL, &httpd->retcode, &httpd->retmsg, &httpd->mimetype, &httpd->bodybuffer, &httpd->freecb, &httpd->freecb_arg); else result = url->action(httpd->url, url, httpd->querystring, httpd->headers, url->action_arg, &httpd->retcode, &httpd->retmsg, &httpd->mimetype, &httpd->bodybuffer, &httpd->freecb, &httpd->freecb_arg); if (result != ISC_R_SUCCESS) { result = httpd->mgr->render_500(httpd->url, url, httpd->querystring, NULL, NULL, &httpd->retcode, &httpd->retmsg, &httpd->mimetype, &httpd->bodybuffer, &httpd->freecb, &httpd->freecb_arg); RUNTIME_CHECK(result == ISC_R_SUCCESS); } isc_httpd_response(httpd); isc_httpd_addheader(httpd, "Content-Type", httpd->mimetype); isc_httpd_addheader(httpd, "Date", datebuf); isc_httpd_addheader(httpd, "Expires", datebuf); if (url != NULL && url->isstatic) { char loadbuf[32]; isc_time_formathttptimestamp(&url->loadtime, loadbuf, sizeof(loadbuf)); isc_httpd_addheader(httpd, "Last-Modified", loadbuf); isc_httpd_addheader(httpd, "Cache-Control: public", NULL); } else { isc_httpd_addheader(httpd, "Last-Modified", datebuf); isc_httpd_addheader(httpd, "Pragma: no-cache", NULL); isc_httpd_addheader(httpd, "Cache-Control: no-cache", NULL); } isc_httpd_addheader(httpd, "Server: libisc", NULL); isc_httpd_addheaderuint(httpd, "Content-Length", isc_buffer_usedlength(&httpd->bodybuffer)); isc_httpd_endheaders(httpd); /* done */ ISC_LIST_APPEND(httpd->bufflist, &httpd->headerbuffer, link); /* * Link the data buffer into our send queue, should we have any data * rendered into it. If no data is present, we won't do anything * with the buffer. */ if (isc_buffer_length(&httpd->bodybuffer) > 0) ISC_LIST_APPEND(httpd->bufflist, &httpd->bodybuffer, link); /* check return code? */ (void)isc_socket_sendv(httpd->sock, &httpd->bufflist, task, isc_httpd_senddone, httpd); out: isc_event_free(&ev); EXIT("recv"); }