Commit eacecebd by Edward Thomson

httpclient: introduce a simple http implementation

Introduce a new http client implementation that can GET and POST to
remote URLs.

Consumers can use `git_http_client_init` to create a new client,
`git_http_client_send_request` to send a request to the remote server
and `git_http_client_read_response` to read the response.

The http client implementation will perform the I/O with the remote
server (http or https) but does not understand the git smart transfer
protocol.  This allows us to split the concerns of the http subtransport
from the actual http implementation.
parent a591f362
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#ifndef INCLUDE_transports_httpclient_h__
#define INCLUDE_transports_httpclient_h__
#include "common.h"
#include "net.h"
typedef struct git_http_client git_http_client;
/** Method for the HTTP request */
typedef enum {
GIT_HTTP_METHOD_GET,
GIT_HTTP_METHOD_POST
} git_http_method;
/** An HTTP request */
typedef struct {
git_http_method method; /**< Method for the request */
git_net_url *url; /**< Full request URL */
git_net_url *proxy; /**< Proxy to use */
/* Headers */
const char *accept; /**< Contents of the Accept header */
const char *content_type; /**< Content-Type header (for POST) */
git_strarray *custom_headers; /**< Additional headers to deliver */
/* To POST a payload, either set content_length OR set chunked. */
size_t content_length; /**< Length of the POST body */
unsigned chunked : 1, /**< Post with chunking */
expect_continue : 1; /**< Use expect/continue negotiation */
} git_http_request;
typedef struct {
int status;
/* Headers */
char *content_type;
size_t content_length;
char *location;
} git_http_response;
typedef struct {
/** Certificate check callback for the remote */
git_transport_certificate_check_cb server_certificate_check_cb;
void *server_certificate_check_payload;
/** Certificate check callback for the proxy */
git_transport_certificate_check_cb proxy_certificate_check_cb;
void *proxy_certificate_check_payload;
} git_http_client_options;
/**
* Create a new httpclient instance with the given options.
*
* @param out pointer to receive the new instance
* @param opts options to create the client with or NULL for defaults
*/
extern int git_http_client_new(
git_http_client **out,
git_http_client_options *opts);
/*
* Sends a request to the host specified by the request URL. If the
* method is POST, either the the content_length or the chunked flag must
* be specified. The body should be provided in subsequent calls to
* git_http_client_send_body.
*
* @param client the client to write the request to
* @param request the request to send
*/
extern int git_http_client_send_request(
git_http_client *client,
git_http_request *request);
/**
* Sends the given buffer to the remote as part of the request body. The
* request must have specified either a content_length or the chunked flag.
*
* @param client the client to write the request body to
* @param buffer the request body
* @param buffer_len number of bytes of the buffer to send
*/
extern int git_http_client_send_body(
git_http_client *client,
const char *buffer,
size_t buffer_len);
/**
* Reads the headers of a response to a request. This will consume the
* entirety of the headers of a response from the server. The body (if any)
* can be read by calling git_http_client_read_body. Callers must free
* the response with git_http_response_dispose.
*
* @param response pointer to the response object to fill
* @param client the client to read the response from
*/
extern int git_http_client_read_response(
git_http_response *response,
git_http_client *client);
/**
* Reads some or all of the body of a response. At most buffer_size (or
* INT_MAX) bytes will be read and placed into the buffer provided. The
* number of bytes read will be returned, or 0 to indicate that the end of
* the body has been read.
*
* @param client the client to read the response from
* @param buffer pointer to the buffer to fill
* @param buffer_size the maximum number of bytes to read
* @return the number of bytes read, 0 on end of body, or error code
*/
extern int git_http_client_read_body(
git_http_client *client,
char *buffer,
size_t buffer_size);
/**
* Examines the status code of the response to determine if it is a
* redirect of any type (eg, 301, 302, etc).
*
* @param response the response to inspect
* @return true if the response is a redirect, false otherwise
*/
extern bool git_http_response_is_redirect(git_http_response *response);
/**
* Frees any memory associated with the response.
*
* @param response the response to free
*/
extern void git_http_response_dispose(git_http_response *response);
/**
* Frees any memory associated with the client. If any sockets are open,
* they will be closed.
*
* @param client the client to free
*/
extern void git_http_client_free(git_http_client *client);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment