Protocol-HTTP

 view release on metacpan or  search on metacpan

clib/src/panda/protocol/http/Request.cc  view on Meta::CPAN

        // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Host
        sz_host = eff_uri->host().length();
        auto& scheme = eff_uri->scheme();
        auto port = eff_uri->port();
        if ((!scheme) || (scheme == "http" && port != 80) || (scheme == "https" && port != 443)) {
            sz_host_port = 6;
        }
    }

    string out_accept_encoding;
    if (compression_prefs && compression_prefs != static_cast<compression::storage_t>(Compression::IDENTITY) && !headers.has("Accept-Encoding")) {
        string comp_pos, comp_neg;
        int index_pos = 0, index_neg = 0;
        compression::for_each(compression_prefs, [&](auto value, bool negation){
            const char* val = nullptr;
            switch (value) {
                case Compression::GZIP   : val = "gzip"; break;
                case Compression::BROTLI : val = "br";   break;
                default: return;
            }
            if (negation) {
                if (index_neg) { comp_neg += ", "; }
                comp_neg += val;
                comp_neg += ";q=0";

clib/src/panda/protocol/http/Request.cc  view on Meta::CPAN

    return _to_vector(ctx, [&]() { return _compile_prepare(ctx); }, [&]() { return _http_header(ctx); });
}

bool Request::expects_continue () const {
    for (auto& val : headers.get_multi("Expect")) if (val == "100-continue") return true;
    return false;
}

std::uint8_t Request::allowed_compression (bool inverse) const noexcept {
    std::uint8_t result = 0;
    compression::for_each(compression_prefs, [&](auto value, bool negation){
        if (inverse == negation) {
            result |= value;
        }
    });
    return result;
}

static string form_trailer(const string& boundary) noexcept {
    auto sz = boundary.size() + 6;
    string r(sz);

clib/src/panda/protocol/http/Request.h  view on Meta::CPAN

        void to_uri  (URI& uri, const URISP original_uri) const ;
        EncType _enc_type = EncType::Multipart;
        friend struct Request;
    };


    URISP   uri;
    Cookies cookies;
    Form    form;

    compression::storage_t compression_prefs = Compression::IDENTITY;

    Request () {}

    Request (Method method, const URISP& uri, Headers&& header = Headers(), Body&& body = Body(), bool chunked = false, int http_version = 0) :
        Message(std::move(header), std::move(body), chunked, http_version), uri(uri), _method(method)
    {
    }

    bool expects_continue () const;

clib/src/panda/protocol/http/Request.h  view on Meta::CPAN

        r += "--\r\n";
        return r;
    }

    Method  _method = Method::Unspecified;
    FormStreaming _form_streaming = FormStreaming::None;
    string _form_boundary;

    template<typename... PrefN>
    void _allow_compression (Compression::Type p, PrefN... prefn) {
        compression::pack(this->compression_prefs, p);
        return _allow_compression(prefn...);
    }
    void _allow_compression () {}
    void form_file_finalize (string& out) noexcept;

    ~Request () {} // restrict stack allocation

private:
    friend struct RequestParser;

clib/src/panda/protocol/http/compression/Compression.h  view on Meta::CPAN

};

bool is_valid_compression (std::uint8_t) noexcept;

using storage_t = std::uint64_t;
constexpr std::uint64_t ITEM_MASK = 0b11111111ull;
constexpr std::uint64_t ITEM_VALUE_MASK = 0b00111111ull;
constexpr std::uint64_t FILLED_MASK = 0b11111111ull << (7 * 8);

template<typename F>
void for_each (storage_t ordered_prefs, F&& fn) noexcept {
    for(int i = sizeof (storage_t) - 1; i >= 0; --i) {
        auto mask = ITEM_MASK << (i * 8);
        auto item_shifted = (ordered_prefs & mask);
        if (!item_shifted) { continue; }
        auto item = item_shifted >> (i * 8);
        bool negation = false;
        if (item > Compression::LAST) {
            item = ~item & ITEM_VALUE_MASK;
            negation = true;
        }
        fn(item, negation);
    }
}

bool inline pack (storage_t& ordered_prefs, Compression::Type value) {
    if (ordered_prefs & FILLED_MASK) return false;
    ordered_prefs = (ordered_prefs << 8) | (value & ITEM_MASK);
    return true;
}

}}}}

clib/tests/compile/compression.cc  view on Meta::CPAN

    CHECK(is_valid_compression(5) == false);
    CHECK(is_valid_compression(6) == false);
}

TEST("[SRV-1757] allow_compression accumulates identity") {
    auto req = Request::Builder()
        .method(Method::Get)
        .allow_compression(Compression::IDENTITY)
        .uri("/")
        .build();
    CHECK(req->compression_prefs != Compression::IDENTITY);
    int count = 0;
    compression::for_each(req->compression_prefs, [&](auto val, bool neg){
       if (val == static_cast<int>(Compression::IDENTITY) && !neg) {
           ++count;
       }
    });
    CHECK(count == 2);
}



( run in 1.707 second using v1.01-cache-2.11-cpan-5a3173703d6 )