Beispiel #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());
                }