Skip to content

HTTP client API for exporter developers #6

@maxgolov

Description

@maxgolov

Different OS may have alternate implementations of HTTP stack:

  • Windows: WinInet, Win 10 (WinRT) HTTP client, WinHttp
  • Linux: libcurl, poco, etc.
  • Mac OS X: libcurl, poco, Apple SDK URLRequest
  • Android: Java HttpRequest, Google HTTP client, OkHTTP
  • iOS: Apple SDK URLRequest
    etc.
  • Chromium HTTP client

An exporter that supports HTTP requires a minimum set of methods:

  • create an instance of HTTP client
  • the client must have ability to create a request with a set of custom headers, method and request body
  • it must provide async execution, with a callback that allows to obtain HTTP response state/result, status code, response headers and response body
  • the callback should, as a minimum, support ability to inspect individual HTTP state machine events (SSL handshake, attempt to connect, sending request, receiving response, etc.), as well as ability to receive the response body / response status code.

Const-correctness aside, common interface structure could define how an exporter developer may design and implement their own HTTP client.

HTTP client does not have intrinsic knowledge of the binary serialization protocol itself (be that gRPC, protobuf, JSON, MSFT Bond, etc.), but can be invoked by exporter implementation to trigger the data upload. The callback associated with each async HTTP request may further handling the retry policy in case if data collection end-point returns something else than 200 OK.

Basic set of interfaces needed to implement the HTTP client:

    class IHttpClient
    {
    public:
        IHttpRequest* CreateRequest();
        void SendRequestAsync(IHttpRequest* request, IHttpResponseCallback* callback);
        void CancelRequestAsync(std::string const& id);
        void CancelAllRequests();
    };

    class IHttpRequest
    {
    public:
        std::string& GetId();
        void SetMethod(std::string const& method);
        void SetUrl(std::string const& url);
        HttpHeaders& GetHeaders();
        void SetBody(std::vector<uint8_t>& body);
        std::vector<uint8_t>& GetBody();
    };

    class HttpHeaders : public std::multimap<std::string, std::string>
    {
    public:
	void set(std::string const& name, std::string const& value);
	void add(std::string const& name, std::string const& value);
	std::string const& get(std::string const& name);
	bool has(std::string const& name);
    }

    class IHttpResponse
    {
    public:
        std::string& GetId();
        HttpResult GetResult();
        unsigned GetStatusCode();
        HttpHeaders& GetHeaders();
        std::vector<uint8_t>& GetBody();
    };

    class IHttpResponseCallback
    {
    public:
        void OnHttpResponse(IHttpResponse* response);
        void OnHttpStateEvent(HttpStateEvent state, ...);
    };

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions