示例#1
0
                std::string request(http::client &client, http::method method, const string &userPath)
                {
                    char buf[http::MAX_URL_LEN + 1] = {0};

                    buffered_socket sock;

                    std::string path = userPath;

                    net::uri uri = client.uri();

                    std::string content = client.content();

                    if (client.is_secure()) {
                        sock.set_secure(true);
                    }

                    if (!uri.port().empty()) {
                        int port = stoi(uri.port());

                        if (!sock.connect(uri.host(), port)) {
                            throw socket_exception("unable to connect to " + uri.to_string());
                        }
                    } else {
                        if (!sock.connect(uri.host(),
                                          client.is_secure() ? http::DEFAULT_SECURE_PORT : http::DEFAULT_PORT)) {
                            throw socket_exception("unable to connect to " + uri.to_string());
                        }
                    }

                    if (path.empty()) {
                        path = uri.full_path();
                    }

                    // send the method and path

                    if (path.empty())
                        snprintf(buf, http::MAX_URL_LEN, http::REQUEST_PREAMBLE, http::method_names[method], "/",
                                 client.version().c_str());
                    else if (path[0] == '/')
                        snprintf(buf, http::MAX_URL_LEN, http::REQUEST_PREAMBLE, http::method_names[method],
                                 path.c_str(), client.version().c_str());
                    else
                        snprintf(buf, http::MAX_URL_LEN, http::REQUEST_PREAMBLE, http::method_names[method],
                                 ("/" + path).c_str(), client.version().c_str());

                    sock.writeln(buf);

                    bool chunked = client.has_header(http::HEADER_TRANSFER_ENCODING) &&
                                   !strcasecmp(client.header(http::HEADER_TRANSFER_ENCODING).c_str(), "chunked");

                    // specify the host
                    if (!client.has_header(http::HEADER_HOST)) {
                        snprintf(buf, http::MAX_URL_LEN, "%s: %s", http::HEADER_HOST, uri.host().c_str());
                        sock.writeln(buf);
                    }

                    if (!client.has_header(http::HEADER_ACCEPT)) {
                        snprintf(buf, http::MAX_URL_LEN, "%s: */*", http::HEADER_ACCEPT);
                        sock.writeln(buf);
                    }

                    if (!client.has_header(http::HEADER_CONNECTION)) {
                        snprintf(buf, http::MAX_URL_LEN, "%s: close", http::HEADER_CONNECTION);
                        sock.writeln(buf);
                    }

                    // add the headers
                    for (const auto &h : client.headers()) {
                        snprintf(buf, http::MAX_URL_LEN, "%s: %s", h.first.c_str(), h.second.c_str());
                        sock.writeln(buf);
                    }

                    // if we have a content, add the size
                    if (!chunked && !content.empty()) {
                        snprintf(buf, http::MAX_URL_LEN, "%s: %zu", http::HEADER_CONTENT_SIZE, content.size());
                        sock.writeln(buf);
                    }

                    // finish header
                    sock.writeln();

                    // add the content
                    if (!content.empty()) {
                        sock.write(content);
                    }

#ifdef DEBUG
                    cout << string(sock.output().begin(), sock.output().end());
#endif

                    if (!sock.write_from_buffer()) {
                        throw socket_exception("unable to write to socket");
                    }

                    if (!sock.read_to_buffer()) {
                        throw socket_exception("unable to read from socket");
                    }

                    auto input = sock.input();

                    return string(input.begin(), input.end());
                }
示例#2
0
                std::string request(http::client &client, http::method method, const std::string &userPath)
                {
                    CURLcode code;

                    char buf[http::MAX_URL_LEN + 1] = {0};

                    struct curl_slist *headers = NULL;

                    CURL *curl = NULL;

                    std::string path = userPath;

                    net::uri uri = client.uri();

                    std::string content = client.content();

                    std::string response;

                    curl = curl_easy_init();

                    if (curl == NULL) {
                        throw socket_exception("unable to initialize curl request");
                    }

                    // check if a path was specified
                    if (path.empty()) {
                        path = uri.full_path();
                    }

                    if (path.empty()) {
                        snprintf(buf, http::MAX_URL_LEN, "%s://%s", uri.scheme().c_str(), uri.host_with_port().c_str());
                    } else if (path[0] == '/') {
                        snprintf(buf, http::MAX_URL_LEN, "%s://%s%s", uri.scheme().c_str(),
                                 uri.host_with_port().c_str(), path.c_str());
                    } else {
                        snprintf(buf, http::MAX_URL_LEN, "%s://%s/%s", uri.scheme().c_str(),
                                 uri.host_with_port().c_str(), path.c_str());
                    }

                    helper::curl_set_opt(curl, CURLOPT_URL, buf);

                    helper::curl_set_opt_fun(curl, CURLOPT_WRITEFUNCTION, helper::curl_append_response_callback);

                    helper::curl_set_opt_num(curl, CURLOPT_HEADER, 1L);

#ifdef DEBUG
                    helper::curl_set_opt_num(curl, CURLOPT_VERBOSE, 1L);
#endif

                    switch (method) {
                        case http::GET:
                            helper::curl_set_opt_num(curl, CURLOPT_HTTPGET, 1L);
                            break;
                        case http::POST:
                            helper::curl_set_opt_num(curl, CURLOPT_POST, 1L);
                            if (!content.empty()) {
                                helper::curl_set_opt(curl, CURLOPT_POSTFIELDS, content.c_str());
                                helper::curl_set_opt_num(curl, CURLOPT_POSTFIELDSIZE, content.size());
                            }
                            break;
                        case http::PUT:
                            helper::curl_set_opt_num(curl, CURLOPT_PUT, 1L);
                            if (!content.empty()) {
                                helper::curl_set_opt(curl, CURLOPT_POSTFIELDS, content.c_str());
                                helper::curl_set_opt_num(curl, CURLOPT_POSTFIELDSIZE, content.size());
                            }
                            break;
                        default:
                            helper::curl_set_opt(curl, CURLOPT_CUSTOMREQUEST, http::method_names[method]);
                            break;
                    }

                    for (auto &h : client.headers()) {
                        snprintf(buf, http::MAX_URL_LEN, "%s: %s", h.first.c_str(), h.second.c_str());
                        headers = curl_slist_append(headers, buf);
                    }

                    helper::curl_set_opt(curl, CURLOPT_HTTPHEADER, headers);

                    helper::curl_set_opt_num(curl, CURLOPT_TIMEOUT, client.timeout());

                    helper::curl_set_opt(curl, CURLOPT_WRITEDATA, &response);

                    CURLcode res = curl_easy_perform(curl);

                    curl_slist_free_all(headers);

                    if (res != CURLE_OK && res != CURLE_PARTIAL_FILE) {
                        curl_easy_cleanup(curl);

                        throw socket_exception(curl_easy_strerror(res));
                    }

                    curl_easy_cleanup(curl);

                    return response;
                }