static void timeout_handler(lcb_timer_t tm, lcb_t i, const void *cookie) { http_provider *http = (http_provider *)cookie; const lcb_host_t *curhost = lcb_connection_get_host(&http->connection); lcb_log(LOGARGS(http, ERR), "HTTP Provider timed out on host %s:%s waiting for I/O", curhost->host, curhost->port); /** * If we're not the current provider then ignore the timeout until we're * actively requested to do so */ if (&http->base != http->base.parent->cur_provider || lcb_confmon_is_refreshing(http->base.parent) == 0) { lcb_log(LOGARGS(http, DEBUG), "Ignoring timeout because we're either not in a refresh " "or not the current provider"); return; } io_error(http, LCB_ETIMEDOUT); (void)tm; (void)i; }
static void connect_done_handler(lcb_connection_t conn, lcb_error_t err) { http_provider *http = (http_provider *)conn->data; const lcb_host_t *host = lcb_connection_get_host(conn); if (err != LCB_SUCCESS) { lcb_log(LOGARGS(http, ERR), "Connection to REST API @%s:%s failed with code=0x%x", host->host, host->port, err); io_error(http, err); return; } lcb_log(LOGARGS(http, DEBUG), "Successfuly connected to REST API %s:%s", host->host, host->port); lcb_connection_reset_buffers(conn); ringbuffer_strcat(conn->output, http->request_buf); lcb_assert(conn->output->nbytes > 0); lcb_sockrw_set_want(conn, LCB_RW_EVENT, 0); lcb_sockrw_apply_want(conn); lcb_timer_rearm(http->io_timer, PROVIDER_SETTING(&http->base, config_node_timeout)); }
static void timeout_handler(lcb_timer_t tm, lcb_t i, const void *cookie) { http_provider *http = (http_provider *)cookie; const lcb_host_t *curhost = lcb_connection_get_host(&http->connection); lcb_log(LOGARGS(http, ERR), "HTTP Provider timed out on host %s:%s waiting for I/O", curhost->host, curhost->port); io_error(http); (void)tm; (void)i; }
static lcb_error_t setup_request_header(http_provider *http) { lcb_settings *settings = http->base.parent->settings; char *buf = http->request_buf; const lcb_host_t *hostinfo; lcb_size_t nbuf = sizeof(http->request_buf); lcb_size_t offset = 0; http->request_buf[0] = '\0'; if (settings->conntype == LCB_TYPE_BUCKET) { offset = snprintf(buf, nbuf, REQBUCKET_FMT, settings->bucket); } else if (settings->conntype == LCB_TYPE_CLUSTER) { offset = snprintf(buf, nbuf, REQPOOLS_FMT); } else { return LCB_EINVAL; } if (settings->password) { char cred[256], b64[256]; snprintf(cred, sizeof(cred), "%s:%s", settings->username, settings->password); if (lcb_base64_encode(cred, b64, sizeof(b64)) == -1) { return LCB_EINTERNAL; } offset += snprintf(buf + offset, nbuf - offset, AUTHDR_FMT, b64); } hostinfo = lcb_connection_get_host(&http->connection); offset += snprintf(buf + offset, nbuf - offset, HOSTHDR_FMT, hostinfo->host, hostinfo->port); offset += snprintf(buf + offset, nbuf - offset, "%s\r\n", LAST_HTTP_HEADER); return LCB_SUCCESS; }
static lcb_error_t conninfo(int mode, lcb_t instance, int cmd, void *arg) { lcb_connection_t conn; struct lcb_cntl_server_st *si = arg; const lcb_host_t *host; if (mode != LCB_CNTL_GET) { return LCB_NOT_SUPPORTED; } if (si->version < 0 || si->version > 1) { return LCB_EINVAL; } if (cmd == LCB_CNTL_MEMDNODE_INFO) { lcb_server_t *server; int ix = si->v.v0.index; if (ix < 0 || ix > (int)instance->nservers) { return LCB_EINVAL; } server = instance->servers + ix; if (!server) { return LCB_NETWORK_ERROR; } if (si->version == 1) { struct negotiation_context *ctx = lcb_negotiation_get(&server->connection); si->v.v1.sasl_mech = ctx->mech; } conn = &server->connection; } else if (cmd == LCB_CNTL_CONFIGNODE_INFO) { conn = lcb_confmon_get_rest_connection(instance->confmon); } else { return LCB_EINVAL; } host = lcb_connection_get_host(conn); si->v.v0.connected = conn->state == LCB_CONNSTATE_CONNECTED; si->v.v0.host = host->host; si->v.v0.port = host->port; switch (instance->settings.io->version) { case 0: si->v.v0.sock.sockfd = conn->sockfd; break; case 1: si->v.v0.sock.sockptr = conn->sockptr; break; default: return LCB_NOT_SUPPORTED; } return LCB_SUCCESS; }
static void io_read_handler(lcb_connection_t conn) { packet_info pi; cccp_provider *cccp = conn->data; lcb_string jsonstr; lcb_error_t err; int rv; lcb_host_t curhost; memset(&pi, 0, sizeof(pi)); rv = lcb_packet_read_ringbuffer(&pi, conn->input); if (rv < 0) { LOG(cccp, ERR, "Couldn't parse packet!?"); mcio_error(cccp, LCB_EINTERNAL); return; } else if (rv == 0) { lcb_sockrw_set_want(conn, LCB_READ_EVENT, 1); lcb_sockrw_apply_want(conn); return; } if (PACKET_STATUS(&pi) != PROTOCOL_BINARY_RESPONSE_SUCCESS) { lcb_log(LOGARGS(cccp, ERR), "CCCP Packet responded with 0x%x; nkey=%d, nbytes=%lu, cmd=0x%x, seq=0x%x", PACKET_STATUS(&pi), PACKET_NKEY(&pi), PACKET_NBODY(&pi), PACKET_OPCODE(&pi), PACKET_OPAQUE(&pi)); switch (PACKET_STATUS(&pi)) { case PROTOCOL_BINARY_RESPONSE_NOT_SUPPORTED: case PROTOCOL_BINARY_RESPONSE_UNKNOWN_COMMAND: mcio_error(cccp, LCB_NOT_SUPPORTED); break; default: mcio_error(cccp, LCB_PROTOCOL_ERROR); break; } return; } if (!PACKET_NBODY(&pi)) { mcio_error(cccp, LCB_PROTOCOL_ERROR); return; } if (lcb_string_init(&jsonstr)) { mcio_error(cccp, LCB_CLIENT_ENOMEM); return; } if (lcb_string_append(&jsonstr, PACKET_BODY(&pi), PACKET_NBODY(&pi))) { mcio_error(cccp, LCB_CLIENT_ENOMEM); return; } curhost = *lcb_connection_get_host(&cccp->connection); lcb_packet_release_ringbuffer(&pi, conn->input); release_socket(cccp, 1); err = lcb_cccp_update(&cccp->base, curhost.host, &jsonstr); lcb_string_release(&jsonstr); if (err == LCB_SUCCESS) { lcb_timer_disarm(cccp->timer); cccp->server_active = 0; } else { schedule_next_request(cccp, LCB_PROTOCOL_ERROR, 0); } }
lcb_host_t * lcb_confmon_get_rest_host(lcb_confmon *mon) { http_provider *http; http = (http_provider *)mon->all_providers[LCB_CLCONFIG_HTTP]; return (lcb_host_t *)lcb_connection_get_host(&http->connection); }