int32_t elasticsearch_connection_init(const char *url, bool debug,
                                      struct elasticsearch_connection **conn_r,
                                      const char **error_r)
{
    struct http_client_settings http_set;
    struct elasticsearch_connection *conn = NULL;
    struct http_url *http_url = NULL;
    const char *error = NULL;

    if (error_r == NULL || url == NULL || conn_r == NULL) {
        i_debug("fts_elasticsearch: error initialising ElasticSearch connection");
        return -1;
    } else {
        /* safe to continue */
    }

    /* validate the url */
    if (http_url_parse(url, NULL, 0, pool_datastack_create(),
               &http_url, &error) < 0) {
        *error_r = t_strdup_printf(
            "fts_elasticsearch: Failed to parse HTTP url: %s", error);

        return -1;
    }

    conn = i_new(struct elasticsearch_connection, 1);
    conn->http_host = i_strdup(http_url->host_name);
    conn->http_port = http_url->port;
    conn->http_base_url = i_strconcat(http_url->path, http_url->enc_query, NULL);
    conn->http_ssl = http_url->have_ssl;
    conn->debug = debug;

    /* guard against init being called multiple times */
    if (elasticsearch_http_client == NULL) {
        memset(&http_set, 0, sizeof(http_set));
        http_set.max_idle_time_msecs = 5 * 1000;
        http_set.max_parallel_connections = 1;
        http_set.max_pipelined_requests = 1;
        http_set.max_redirects = 1;
        http_set.max_attempts = 3;
        http_set.debug = debug;
        elasticsearch_http_client = http_client_init(&http_set);
    }

    *conn_r = conn;

    return 0;
}
Example #2
0
int solr_connection_init(const char *url, bool debug,
			 struct solr_connection **conn_r, const char **error_r)
{
	struct http_client_settings http_set;
	struct solr_connection *conn;
	struct http_url *http_url;
	const char *error;

	if (http_url_parse(url, NULL, 0, pool_datastack_create(),
			   &http_url, &error) < 0) {
		*error_r = t_strdup_printf(
			"fts_solr: Failed to parse HTTP url: %s", error);
		return -1;
	}

	conn = i_new(struct solr_connection, 1);
	conn->http_host = i_strdup(http_url->host.name);
	conn->http_port = http_url->port;
	conn->http_base_url = i_strconcat(http_url->path, http_url->enc_query, NULL);
	conn->http_ssl = http_url->have_ssl;
	conn->debug = debug;

	if (solr_http_client == NULL) {
		memset(&http_set, 0, sizeof(http_set));
		http_set.max_idle_time_msecs = 5*1000;
		http_set.max_parallel_connections = 1;
		http_set.max_pipelined_requests = 1;
		http_set.max_redirects = 1;
		http_set.max_attempts = 3;
		http_set.debug = debug;
		http_set.connect_timeout_msecs = 5*1000;
		http_set.request_timeout_msecs = 60*1000;
		solr_http_client = http_client_init(&http_set);
	}

	conn->xml_parser = XML_ParserCreate("UTF-8");
	if (conn->xml_parser == NULL) {
		i_fatal_status(FATAL_OUTOFMEM,
			       "fts_solr: Failed to allocate XML parser");
	}
	*conn_r = conn;
	return 0;
}
Example #3
0
static int
tika_get_http_client_url(struct mail_user *user, struct http_url **http_url_r)
{
	struct fts_parser_tika_user *tuser = TIKA_USER_CONTEXT(user);
	struct http_client_settings http_set;
	const char *url, *error;

	url = mail_user_plugin_getenv(user, "fts_tika");
	if (url == NULL) {
		/* fts_tika disabled */
		return -1;
	}

	if (tuser != NULL) {
		*http_url_r = tuser->http_url;
		return *http_url_r == NULL ? -1 : 0;
	}

	tuser = p_new(user->pool, struct fts_parser_tika_user, 1);
	MODULE_CONTEXT_SET(user, fts_parser_tika_user_module, tuser);

	if (http_url_parse(url, NULL, 0, user->pool,
			   &tuser->http_url, &error) < 0) {
		i_error("fts_tika: Failed to parse HTTP url %s: %s", url, error);
		return -1;
	}

	if (tika_http_client == NULL) {
		memset(&http_set, 0, sizeof(http_set));
		http_set.max_idle_time_msecs = 100;
		http_set.max_parallel_connections = 1;
		http_set.max_pipelined_requests = 1;
		http_set.max_redirects = 1;
		http_set.max_attempts = 3;
		http_set.connect_timeout_msecs = 5*1000;
		http_set.request_timeout_msecs = 60*1000;
		http_set.debug = user->mail_debug;
		tika_http_client = http_client_init(&http_set);
	}
	*http_url_r = tuser->http_url;
	return 0;
}
Example #4
0
File: url.c Project: galdor/libhttp
int
main(int argc, char **argv) {
    struct c_command_line *cmdline;
    const char *url_string;
    struct http_url *url;
    char *result;

    cmdline = c_command_line_new();

    c_command_line_add_argument(cmdline, "the url string", "url");

    if (c_command_line_parse(cmdline, argc, argv) == -1)
        httpex_die("%s", c_get_error());

    url_string = c_command_line_argument_value(cmdline, 0);

    url = http_url_parse(url_string);
    if (!url)
        httpex_die("cannot parse url: %s", c_get_error());

    if (http_url_scheme(url))
        printf("- %-12s  '%s'\n", "scheme", http_url_scheme(url));
    if (http_url_user(url))
        printf("- %-12s  '%s'\n", "user", http_url_user(url));
    if (http_url_password(url))
        printf("- %-12s  '%s'\n", "password", http_url_password(url));
    if (http_url_host(url))
        printf("- %-12s  '%s'\n", "host", http_url_host(url));
    if (http_url_port(url)) {
        printf("- %-12s  '%s'\n", "port", http_url_port(url));
        printf("  %-12s  %u\n", "port number", http_url_port_number(url));
    }
    if (http_url_path(url))
        printf("- %-12s  '%s'\n", "path", http_url_path(url));
    if (http_url_query(url)) {
        size_t nb_params;

        printf("- %-12s  '%s'\n", "query", http_url_query(url));

        nb_params = http_url_nb_query_parameters(url);
        for (size_t i = 0; i < nb_params; i++) {
            const char *name, *value;

            name = http_url_nth_query_parameter(url, i, &value);

            if (value) {
                printf("  %-12s  %s\n", name, value);
            } else {
                printf("  %-12s\n", name);
            }
        }
    }
    if (http_url_fragment(url))
        printf("- %-12s  '%s'\n", "fragment", http_url_fragment(url));

    result = http_url_to_string(url);
    printf("\n%s\n", result);
    c_free(result);

    http_url_delete(url);

    c_command_line_delete(cmdline);
    return 0;
}
Example #5
0
void http_client_request_redirect(struct http_client_request *req,
	unsigned int status, const char *location)
{
	struct http_url *url;
	const char *error, *target, *origin_url;

	i_assert(!req->payload_wait);

	/* parse URL */
	if (http_url_parse(location, NULL, 0,
			   pool_datastack_create(), &url, &error) < 0) {
		http_client_request_error(&req, HTTP_CLIENT_REQUEST_ERROR_INVALID_REDIRECT,
			t_strdup_printf("Invalid redirect location: %s", error));
		return;
	}

	if (++req->redirects > req->client->set.max_redirects) {
		if (req->client->set.max_redirects > 0) {
			http_client_request_error(&req,
				HTTP_CLIENT_REQUEST_ERROR_INVALID_REDIRECT,
				t_strdup_printf("Redirected more than %d times",
					req->client->set.max_redirects));
		} else {
			http_client_request_error(&req,
				HTTP_CLIENT_REQUEST_ERROR_INVALID_REDIRECT,
					"Redirect refused");
		}
		return;
	}

	/* rewind payload stream */
	if (req->payload_input != NULL && req->payload_size > 0 && status != 303) {
		if (req->payload_input->v_offset != req->payload_offset &&
			!req->payload_input->seekable) {
			http_client_request_error(&req,
				HTTP_CLIENT_REQUEST_ERROR_ABORTED,
				"Redirect failed: Cannot resend payload; stream is not seekable");
			return;
		} else {
			i_stream_seek(req->payload_input, req->payload_offset);
		}
	}

	/* drop payload output stream from previous attempt */
	if (req->payload_output != NULL)
		o_stream_unref(&req->payload_output);

	target = http_url_create_target(url);

	http_url_copy(req->pool, &req->origin_url, url);
	req->target = p_strdup(req->pool, target);
	
	req->host = NULL;
	req->conn = NULL;

	origin_url = http_url_create(&req->origin_url);

	http_client_request_debug(req, "Redirecting to %s%s",
		origin_url, target);

	req->label = p_strdup_printf(req->pool, "[%s %s%s]",
		req->method, origin_url, req->target);

	/* RFC 7231, Section 6.4.4:
	
	   -> A 303 `See Other' redirect status response is handled a bit differently.
	   Basically, the response content is located elsewhere, but the original
	   (POST) request is handled already.
	 */
	if (status == 303 && strcasecmp(req->method, "HEAD") != 0 &&
		strcasecmp(req->method, "GET") != 0) {
		// FIXME: should we provide the means to skip this step? The original
		// request was already handled at this point.
		req->method = p_strdup(req->pool, "GET");

		/* drop payload */
		if (req->payload_input != NULL)
			i_stream_unref(&req->payload_input);
		req->payload_size = 0;
		req->payload_offset = 0;
	}

	/* resubmit */
	req->state = HTTP_REQUEST_STATE_NEW;
	http_client_request_do_submit(req);
}
Example #6
0
static int
http_response_preprocess_headers(struct http_response *response) {
#define HTTP_FAIL(fmt_, ...)                  \
    do {                                      \
        if (fmt_)                             \
            c_set_error(fmt_, ##__VA_ARGS__); \
        return -1;                            \
    } while (0)

    for (size_t i = 0; i < http_response_nb_headers(response); i++) {
        const char *name, *value;

        name = http_response_nth_header(response, i, &value);

#define HTTP_HEADER_IS(name_) (strcasecmp(name, name_) == 0)

        /* -- Content-Length ---------------------------------------------- */
        if (HTTP_HEADER_IS("Content-Length")) {
            response->has_content_length = true;

            if (c_parse_size(value, &response->content_length,
                             NULL) == -1) {
                HTTP_FAIL("cannot parse %s header: %s", name, c_get_error());
            }

        /* -- Content-Encoding -------------------------------------------- */
        } else if (HTTP_HEADER_IS("Content-Encoding")) {
            struct c_ptr_vector *tokens;

            tokens = http_list_parse(value);
            if (!tokens)
                HTTP_FAIL("cannot parse %s header: %s", name, c_get_error());

            response->content_codings = c_vector_new(
                sizeof(enum http_content_coding));

            for (size_t i = 0; i < c_ptr_vector_length(tokens); i++) {
                enum http_content_coding coding;
                const char *token;

                token = c_ptr_vector_entry(tokens, i);
                if (http_content_coding_parse(token, &coding) == -1) {
                    http_string_vector_delete(tokens);
                    HTTP_FAIL("unknown content coding '%s'", token);
                }

                c_vector_append(response->content_codings, &coding);
            }

            http_string_vector_delete(tokens);

        /* -- Connection -------------------------------------------------- */
        } else if (HTTP_HEADER_IS("Connection")) {
            if (strcasecmp(value, "close") == 0)
                response->has_connection_close = true;

        /* -- Transfer-Encoding ------------------------------------------- */
        } else if (HTTP_HEADER_IS("Transfer-Encoding")) {
            struct c_ptr_vector *tokens;

            tokens = http_list_parse(value);
            if (!tokens)
                HTTP_FAIL("cannot parse %s header: %s", name, c_get_error());

            for (size_t i = 0; i < c_ptr_vector_length(tokens); i++) {
                const char *token;

                token = c_ptr_vector_entry(tokens, i);

                if (strcasecmp(token, "chunked") == 0) {
                    response->is_body_chunked = true;
                } else if (strcasecmp(token, "compressed") == 0
                        || strcasecmp(token, "deflate") == 0
                        || strcasecmp(token, "gzip") == 0) {
                    http_string_vector_delete(tokens);
                    HTTP_FAIL("'%s' transfer coding not supported", token);
                } else {
                    http_string_vector_delete(tokens);
                    HTTP_FAIL("unknown transfer coding '%s'", token);
                }
            }

            http_string_vector_delete(tokens);

        /* -- Location ---------------------------------------------------- */
        } else if (HTTP_HEADER_IS("Location")) {
            if (response->status >= 300 && response->status < 400) {
                struct http_url *url;

                url = http_url_parse(value);
                if (!url)
                    HTTP_FAIL("invalid %s header: %s", name, c_get_error());

                response->redirection_location = url;
            }

        }

#undef HTTP_HEADER_IS
    }

#undef HTTP_FAIL

    return 0;
}
Example #7
0
int main() {
	int logi, ch, y, x;

	display_log_type = INFO;
	log_init(&log);
	log_register_message_callback(&log, message_logged);

	current_action = NO_ACTION;

	initscr();
	create_windows();
	cdk_screen = initCDKScreen(log_window);
	log_swindow = newCDKSwindow(cdk_screen, 0, 0, log_lines, log_cols, "", 255, 0, 0);

	draw_stdscr();
	draw_url_input();
	draw_commands();

	select_form();

	raw();
	noecho();
	keypad(stdscr, TRUE);

	while ((ch = wgetch(input_window)) != '' || current_action & CANCEL_SHOWING)
		if (ch == KEY_LEFT)
			form_driver(url_form, REQ_LEFT_CHAR);
		else if (ch == KEY_RIGHT)
			form_driver(url_form, REQ_RIGHT_CHAR);
		else if (ch == KEY_BACKSPACE || ch == 127) {
			getyx(input_window, y, x);

			if (x == FIELD_START + 1) {
				form_driver(url_form, REQ_SCR_HBHALF);
				form_driver(url_form, REQ_END_LINE);
			}

			form_driver(url_form, REQ_LEFT_CHAR);
			form_driver(url_form, REQ_DEL_CHAR);
		} else if (ch == KEY_DC)
			form_driver(url_form, REQ_DEL_CHAR);
		else if (ch == KEY_HOME)
			form_driver(url_form, REQ_BEG_FIELD);
		else if (ch == KEY_END)
			form_driver(url_form, REQ_END_FIELD);
		else if (ch == KEY_UP || ch == KEY_DOWN)
			injectCDKSwindow(log_swindow, ch);
		else if (ch == '')
			cleanCDKSwindow(log_swindow);
		else if (ch == '	')
			change_display_log_type(INFO);
		else if (ch == '')
			change_display_log_type(DETAILS);
		else if (ch == '\n' && current_action & URL_INPUTTING) {
			int ret;

			form_driver(url_form, REQ_END_FIELD);
			form_driver(url_form, 'a');
			form_driver(url_form, REQ_VALIDATION);
			strncpy(url, field_buffer(url_field[0], 0), FIELD_BUF_SIZE);
			url[FIELD_BUF_SIZE - 1] = '\0';
			*strrchr(url, 'a') = '\0';

			http_url_init(&http_url);
			if (ret = http_url_parse(&http_url, url)) {
				char *message;

				switch (ret) {
					case INVALID_SERVER_AUTHORITY:
						message = "Invalid server authority";
						break;
					case INVALID_SCHEME:
						message = "Invalid scheme";
						break;
					case INVALID_PORT:
						message = "Invalid port";
						break;
					default:
						message = "Invalid URI";
						break;
				}

				log_printf(&log, INFO, "http_url_parse", "%s", message);

				draw_url_input();
				draw_commands();
			} else {
				draw_method_selection();
				draw_cancel();
			}
		} else if (tolower(ch) == 'g' && current_action & METHOD_SELECTING) {
			http_init(&http, &http_url, GET, NULL, 0, 3, &log);
			pthread_create(&http_thread, NULL, http_run_thread, &http);
			draw_cancel();
		} else if (tolower(ch) == 'h' && current_action & METHOD_SELECTING) {
			http_init(&http, &http_url, HEAD, NULL, 0, 3, &log);
			pthread_create(&http_thread, NULL, http_run_thread, &http);
			draw_cancel();
		} else if (tolower(ch) == 'p' && current_action & METHOD_SELECTING) {
			draw_post_input();
			draw_cancel();
			select_form();
		} else if (ch == '\n' && current_action & POST_INPUTTING) {
			form_driver(url_form, REQ_END_FIELD);
			form_driver(url_form, 'a');
			form_driver(url_form, REQ_VALIDATION);
			strncpy(post, field_buffer(url_field[0], 0), FIELD_BUF_SIZE);
			post[FIELD_BUF_SIZE - 1] = '\0';
			*strrchr(post, 'a') = '\0';

			http_init(&http, &http_url, POST, post, strlen(post), 3, &log);
			pthread_create(&http_thread, NULL, http_run_thread, &http);
			draw_cancel();
		} else if (ch == '\n' && current_action & FILE_INPUTTING) {
			form_driver(url_form, REQ_END_FIELD);
			form_driver(url_form, 'a');
			form_driver(url_form, REQ_VALIDATION);
			strncpy(file, field_buffer(url_field[0], 0), FIELD_BUF_SIZE);
			file[FIELD_BUF_SIZE - 1] = '\0';
			*strrchr(file, 'a') = '\0';

			pthread_mutex_lock(&input_mutex);
			inputted = 1;
			pthread_cond_broadcast(&input_cond);
			pthread_mutex_unlock(&input_mutex);
		} else if ((ch == 'y' || ch == 'Y') && current_action & OVERWRITE_INPUTTING) {
			do_overwrite = 1;

			pthread_mutex_lock(&input_mutex);
			inputted = 1;
			pthread_cond_broadcast(&input_cond);
			pthread_mutex_unlock(&input_mutex);
		} else if ((ch == 'n' || ch == 'N') && current_action & OVERWRITE_INPUTTING) {
			do_overwrite = 0;
			
			pthread_mutex_lock(&input_mutex);
			inputted = 1;
			pthread_cond_broadcast(&input_cond);
			pthread_mutex_unlock(&input_mutex);
		}else if (ch == '') {
			if (http.status != DISCONNECTED)
				http_disconnect(&http);
			draw_url_input();
			draw_commands();
			select_form();
		} else
			form_driver(url_form, ch);

	delete_input_form();
	destroyCDKSwindow(log_swindow);
	destroyCDKScreen(cdk_screen);
	endwin();

	pthread_mutex_destroy(&input_mutex);
	pthread_cond_destroy(&input_cond);

	return 0;
}