static void shutdown_http(clconfig_provider *provider) { http_provider *http = (http_provider *)provider; reset_stream_state(http); lcb_string_release(&http->stream.chunk); lcb_string_release(&http->stream.input); lcb_string_release(&http->stream.header); lcb_connection_close(&http->connection); lcb_connection_cleanup(&http->connection); if (http->current_config) { lcb_clconfig_decref(http->current_config); } if (http->disconn_timer) { lcb_timer_destroy(NULL, http->disconn_timer); } if (http->io_timer) { lcb_timer_destroy(NULL, http->io_timer); } if (http->as_schederr) { lcb_timer_destroy(NULL, http->as_schederr); } if (http->nodes) { hostlist_destroy(http->nodes); } free(http); }
static lcb_error_t start_connection(lcb_t instance) { lcb_error_t rc; char *ptr; lcb_connection_result_t connres; lcb_connection_t conn = &instance->bootstrap.via.http.connection; /** * First, close the connection, if there's an open socket from a previous * one. */ lcb_connection_close(conn); reset_stream_state(instance); conn->on_connect_complete = connect_done_handler; conn->evinfo.handler = config_v0_handler; conn->completion.read = config_v1_read_handler; conn->completion.write = config_v1_write_handler; conn->completion.error = config_v1_error_handler; conn->on_timeout = lcb_bootstrap_timeout_handler; conn->timeout.usec = instance->config.bootstrap_timeout; rc = lcb_init_next_host(instance, 8091); if (rc != LCB_SUCCESS) { return rc; } instance->last_error = LCB_SUCCESS; /* We need to fix the host part... */ ptr = strstr(instance->bootstrap.via.http.uri, LCB_LAST_HTTP_HEADER); lcb_assert(ptr); ptr += strlen(LCB_LAST_HTTP_HEADER); sprintf(ptr, "Host: %s:%s\r\n\r\n", conn->host, conn->port); connres = lcb_connection_start(conn, 1); if (connres == LCB_CONN_ERROR) { lcb_connection_close(conn); return lcb_error_handler(instance, LCB_CONNECT_ERROR, "Couldn't schedule connection"); } if (instance->config.syncmode == LCB_SYNCHRONOUS) { lcb_wait(instance); } return instance->last_error; }
/** * This is called when we still 'own' the timer. This dispatches * to the generic timeout handler */ static void initial_connect_timeout_handler(lcb_socket_t sock, short which, void *arg) { lcb_connection_t conn = (lcb_connection_t)arg; lcb_connection_close(conn); conn_do_callback(conn, 0, LCB_ETIMEDOUT); (void)which; (void)sock; }
/** * Do some basic connection failure handling. Cycles through the addrinfo * structures, and closes the socket. Returns 0 if there are more addrinfo * structures to try, -1 on error */ static int handle_conn_failure(struct lcb_connection_st *conn) { /** Reset the state */ lcb_connection_close(conn); if (conn_next_ai(conn) == 0) { conn->state = LCB_CONNSTATE_INPROGRESS; return 0; } return -1; }
void lcb_connection_cleanup(lcb_connection_t conn) { if (conn->ai) { freeaddrinfo(conn->ai); conn->ai = NULL; } if (conn->input) { ringbuffer_destruct(conn->input); free(conn->input); conn->input = NULL; } if (conn->output) { ringbuffer_destruct(conn->output); free(conn->output); conn->output = NULL; } lcb_connection_close(conn); if (conn->evinfo.ptr) { conn->instance->io->v.v0.destroy_event(conn->instance->io, conn->evinfo.ptr); conn->evinfo.ptr = NULL; } lcb_connection_cancel_timer(conn); if (conn->timeout.timer) { conn->instance->io->v.v0.destroy_timer(conn->instance->io, conn->timeout.timer); } memset(conn, 0, sizeof(*conn)); }
/** * Closes the current connection and removes the disconn timer along with it */ static void close_current(http_provider *http) { lcb_timer_disarm(http->disconn_timer); lcb_connection_close(&http->connection); }