1 /*
2  * Copyright (C) the libgit2 contributors. All rights reserved.
3  *
4  * This file is part of libgit2, distributed under the GNU GPL v2 with
5  * a Linking Exception. For full terms see the included COPYING file.
6  */
7 
8 #ifndef INCLUDE_transports_httpclient_h__
9 #define INCLUDE_transports_httpclient_h__
10 
11 #include "common.h"
12 #include "net.h"
13 
14 #define GIT_HTTP_STATUS_CONTINUE                      100
15 #define GIT_HTTP_STATUS_OK                            200
16 #define GIT_HTTP_MOVED_PERMANENTLY                    301
17 #define GIT_HTTP_FOUND                                302
18 #define GIT_HTTP_SEE_OTHER                            303
19 #define GIT_HTTP_TEMPORARY_REDIRECT                   307
20 #define GIT_HTTP_PERMANENT_REDIRECT                   308
21 #define GIT_HTTP_STATUS_UNAUTHORIZED                  401
22 #define GIT_HTTP_STATUS_PROXY_AUTHENTICATION_REQUIRED 407
23 
24 typedef struct git_http_client git_http_client;
25 
26 /** Method for the HTTP request */
27 typedef enum {
28 	GIT_HTTP_METHOD_GET,
29 	GIT_HTTP_METHOD_POST,
30 	GIT_HTTP_METHOD_CONNECT
31 } git_http_method;
32 
33 /** An HTTP request */
34 typedef struct {
35 	git_http_method method;            /**< Method for the request */
36 	git_net_url *url;                  /**< Full request URL */
37 	git_net_url *proxy;                /**< Proxy to use */
38 
39 	/* Headers */
40 	const char *accept;                /**< Contents of the Accept header */
41 	const char *content_type;          /**< Content-Type header (for POST) */
42 	git_credential *credentials;       /**< Credentials to authenticate with */
43 	git_credential *proxy_credentials; /**< Credentials for proxy */
44 	git_strarray *custom_headers;      /**< Additional headers to deliver */
45 
46 	/* To POST a payload, either set content_length OR set chunked. */
47 	size_t content_length;             /**< Length of the POST body */
48 	unsigned chunked : 1,              /**< Post with chunking */
49 	         expect_continue : 1;      /**< Use expect/continue negotiation */
50 } git_http_request;
51 
52 typedef struct {
53 	int status;
54 
55 	/* Headers */
56 	char *content_type;
57 	size_t content_length;
58 	char *location;
59 
60 	/* Authentication headers */
61 	unsigned server_auth_schemetypes; /**< Schemes requested by remote */
62 	unsigned server_auth_credtypes;   /**< Supported cred types for remote */
63 
64 	unsigned proxy_auth_schemetypes;  /**< Schemes requested by proxy */
65 	unsigned proxy_auth_credtypes;    /**< Supported cred types for proxy */
66 
67 	unsigned chunked : 1,             /**< Response body is chunked */
68 	         resend_credentials : 1;  /**< Resend with authentication */
69 } git_http_response;
70 
71 typedef struct {
72 	/** Certificate check callback for the remote */
73 	git_transport_certificate_check_cb server_certificate_check_cb;
74 	void *server_certificate_check_payload;
75 
76 	/** Certificate check callback for the proxy */
77 	git_transport_certificate_check_cb proxy_certificate_check_cb;
78 	void *proxy_certificate_check_payload;
79 } git_http_client_options;
80 
81 /**
82  * Create a new httpclient instance with the given options.
83  *
84  * @param out pointer to receive the new instance
85  * @param opts options to create the client with or NULL for defaults
86  */
87 extern int git_http_client_new(
88 	git_http_client **out,
89 	git_http_client_options *opts);
90 
91 /*
92  * Sends a request to the host specified by the request URL.  If the
93  * method is POST, either the content_length or the chunked flag must
94  * be specified.  The body should be provided in subsequent calls to
95  * git_http_client_send_body.
96  *
97  * @param client the client to write the request to
98  * @param request the request to send
99  */
100 extern int git_http_client_send_request(
101 	git_http_client *client,
102 	git_http_request *request);
103 
104 /*
105  * After sending a request, there may already be a response to read --
106  * either because there was a non-continue response to an expect: continue
107  * request, or because the server pipelined a response to us before we even
108  * sent the request.  Examine the state.
109  *
110  * @param client the client to examine
111  * @return true if there's already a response to read, false otherwise
112  */
113 extern bool git_http_client_has_response(git_http_client *client);
114 
115 /**
116  * Sends the given buffer to the remote as part of the request body.  The
117  * request must have specified either a content_length or the chunked flag.
118  *
119  * @param client the client to write the request body to
120  * @param buffer the request body
121  * @param buffer_len number of bytes of the buffer to send
122  */
123 extern int git_http_client_send_body(
124 	git_http_client *client,
125 	const char *buffer,
126 	size_t buffer_len);
127 
128 /**
129  * Reads the headers of a response to a request.  This will consume the
130  * entirety of the headers of a response from the server.  The body (if any)
131  * can be read by calling git_http_client_read_body.  Callers must free
132  * the response with git_http_response_dispose.
133  *
134  * @param response pointer to the response object to fill
135  * @param client the client to read the response from
136  */
137 extern int git_http_client_read_response(
138 	git_http_response *response,
139 	git_http_client *client);
140 
141 /**
142  * Reads some or all of the body of a response.  At most buffer_size (or
143  * INT_MAX) bytes will be read and placed into the buffer provided.  The
144  * number of bytes read will be returned, or 0 to indicate that the end of
145  * the body has been read.
146  *
147  * @param client the client to read the response from
148  * @param buffer pointer to the buffer to fill
149  * @param buffer_size the maximum number of bytes to read
150  * @return the number of bytes read, 0 on end of body, or error code
151  */
152 extern int git_http_client_read_body(
153 	git_http_client *client,
154 	char *buffer,
155 	size_t buffer_size);
156 
157 /**
158  * Reads all of the (remainder of the) body of the response and ignores it.
159  * None of the data from the body will be returned to the caller.
160  *
161  * @param client the client to read the response from
162  * @return 0 or an error code
163  */
164 extern int git_http_client_skip_body(git_http_client *client);
165 
166 /**
167  * Examines the status code of the response to determine if it is a
168  * redirect of any type (eg, 301, 302, etc).
169  *
170  * @param response the response to inspect
171  * @return true if the response is a redirect, false otherwise
172  */
173 extern bool git_http_response_is_redirect(git_http_response *response);
174 
175 /**
176  * Frees any memory associated with the response.
177  *
178  * @param response the response to free
179  */
180 extern void git_http_response_dispose(git_http_response *response);
181 
182 /**
183  * Frees any memory associated with the client.  If any sockets are open,
184  * they will be closed.
185  *
186  * @param client the client to free
187  */
188 extern void git_http_client_free(git_http_client *client);
189 
190 #endif
191