1 /*===========================================================================
2 *
3 *                            PUBLIC DOMAIN NOTICE
4 *               National Center for Biotechnology Information
5 *
6 *  This software/database is a "United States Government Work" under the
7 *  terms of the United States Copyright Act.  It was written as part of
8 *  the author's official duties as a United States Government employee and
9 *  thus cannot be copyrighted.  This software/database is freely available
10 *  to the public for use. The National Library of Medicine and the U.S.
11 *  Government have not placed any restriction on its use or reproduction.
12 *
13 *  Although all reasonable efforts have been taken to ensure the accuracy
14 *  and reliability of the software and data, the NLM and the U.S.
15 *  Government do not and cannot warrant the performance or results that
16 *  may be obtained by using this software or data. The NLM and the U.S.
17 *  Government disclaim all warranties, express or implied, including
18 *  warranties of performance, merchantability or fitness for any particular
19 *  purpose.
20 *
21 *  Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26 
27 #ifndef _h_kns_http_
28 #define _h_kns_http_
29 
30 #ifndef _h_kns_extern_
31 #include <kns/extern.h>
32 #endif
33 
34 #ifndef _h_klib_defs_
35 #include <klib/defs.h>
36 #endif
37 
38 #include <stdarg.h>
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 
45 /*--------------------------------------------------------------------------
46  * forwards
47  */
48 struct KFile;
49 struct String;
50 struct KStream;
51 struct KNSManager;
52 
53 
54 /*--------------------------------------------------------------------------
55  * KNSManager
56  */
57 
58 /* SetHTTPTimeouts
59  *  sets default read/write timeouts to supply to HTTP connections
60  *
61  *  "readMillis" [ IN ] and "writeMillis" - when negative, infinite timeout
62  *   when 0, return immediately, positive gives maximum wait time in mS
63  *   for reads and writes respectively.
64  */
65 KNS_EXTERN rc_t CC KNSManagerSetHTTPTimeouts ( struct KNSManager * self,
66     int32_t readMillis, int32_t writeMillis );
67 
68 
69 /* GetHTTPProxyPath
70  *  returns path to HTTP proxy server ( if set ) or NULL.
71  *  return status is 0 if the path is valid, non-zero otherwise
72  *
73  *  returned reference to String must be freed via StringWhack.
74  *
75  * DEPRECATED : THIS FUNCTION IS INCORRECT !!!
76  */
77 KNS_EXTERN rc_t CC KNSManagerGetHTTPProxyPath ( struct KNSManager const * self,
78     struct String const ** proxy );
79 
80 
81 /* SetHTTPProxyPath
82  *  sets a path to HTTP proxy server.
83  *  a NULL path format value removes all proxy settings.
84  */
85 KNS_EXTERN rc_t CC KNSManagerSetHTTPProxyPath ( struct KNSManager * self,
86     const char * fmt, ... );
87 KNS_EXTERN rc_t CC KNSManagerVSetHTTPProxyPath ( struct KNSManager * self,
88     const char * fmt, va_list args );
89 
90 
91 /* GetHTTPProxyEnabled
92  *  returns true iff a non-NULL proxy path exists and user wants to use it
93  *  users indicate desire to use proxy through configuration or SetHTTPProxyEnabled
94  */
95 KNS_EXTERN bool CC KNSManagerGetHTTPProxyEnabled ( struct KNSManager const * self );
96 
97 
98 /* SetHTTPProxyEnabled
99  *  sets http-proxy enabled state to supplied value
100  *  returns the prior value as a convenience
101  */
102 KNS_EXTERN bool CC KNSManagerSetHTTPProxyEnabled ( struct KNSManager * self, bool enabled );
103 
104 
105 /*------------------------------------------------------------------------------
106  * KFile
107  *  a KFile over HTTP
108  */
109 
110 /* Make
111  */
112 KNS_EXTERN rc_t CC KNSManagerMakeHttpFile ( struct KNSManager const *self,
113     struct KFile const **file, struct KStream *conn, ver_t vers, const char *url, ... );
114 KNS_EXTERN rc_t CC KNSManagerVMakeHttpFile ( struct KNSManager const *self,
115     struct KFile const **file, struct KStream *conn, ver_t vers, const char *url, va_list args );
116 
117 
118 /*--------------------------------------------------------------------------
119  * KClientHttp
120  *  hyper text transfer protocol
121  */
122 typedef struct KClientHttp KClientHttp, KHttp;
123 
124 
125 /* MakeClientHttp
126  *  create an HTTP protocol
127  *
128  *  "http" [ OUT ] - return parameter for HTTP object
129  *
130  *  "opt_conn" [ IN, NULL OKAY ] - previously opened stream for communications.
131  *
132  *  "vers" [ IN ] - http version
133  *   the only legal types are 1.0 ( 0x01000000 ) and 1.1 ( 0x01010000 )
134  *
135  *  "readMillis" [ IN ] and "writeMillis" - when negative, infinite timeout
136  *   when 0, return immediately, positive gives maximum wait time in mS
137  *   for reads and writes respectively.
138  *
139  *  "host" [ IN ] - parameter to give the host dns name for the connection
140  *
141  *  "port" [ IN, DEFAULT ZERO ] - if zero, defaults to standard for scheme
142  *   if non-zero, is taken as explicit port specification
143  */
144 KNS_EXTERN rc_t CC KNSManagerMakeClientHttp ( struct KNSManager const *self,
145     KClientHttp **http, struct KStream *conn, ver_t vers,
146     struct String const *host, uint32_t port );
147 
148 KNS_EXTERN rc_t CC KNSManagerMakeTimedClientHttp ( struct KNSManager const *self,
149     KClientHttp **http, struct KStream *opt_conn, ver_t vers,
150     int32_t readMillis, int32_t writeMillis,
151     struct String const *host, uint32_t port );
152 
153 
154 /* MakeClientHttps
155  *  create an HTTPS protocol
156  *
157  *  "https" [ OUT ] - return parameter for HTTPS object
158  *
159  *  "opt_conn" [ IN, NULL OKAY ] - previously opened stream for communications.
160  *
161  *  "vers" [ IN ] - https version
162  *   the only legal types are 1.0 ( 0x01000000 ) and 1.1 ( 0x01010000 )
163  *
164  *  "readMillis" [ IN ] and "writeMillis" - when negative, infinite timeout
165  *   when 0, return immediately, positive gives maximum wait time in mS
166  *   for reads and writes respectively.
167  *
168  *  "host" [ IN ] - parameter to give the host dns name for the connection
169  *
170  *  "port" [ IN, DEFAULT ZERO ] - if zero, defaults to standard for scheme
171  *   if non-zero, is taken as explicit port specification
172  */
173 KNS_EXTERN rc_t CC KNSManagerMakeClientHttps ( struct KNSManager const *self,
174     KClientHttp **https, struct KStream *conn, ver_t vers,
175     struct String const *host, uint32_t port );
176 
177 KNS_EXTERN rc_t CC KNSManagerMakeTimedClientHttps ( struct KNSManager const *self,
178     KClientHttp **https, struct KStream *opt_conn, ver_t vers,
179     int32_t readMillis, int32_t writeMillis,
180     struct String const *host, uint32_t port );
181 
182 
183 /* AddRef
184  * Release
185  *  ignores NULL references
186  */
187 KNS_EXTERN rc_t CC KClientHttpAddRef ( const KClientHttp *self );
188 KNS_EXTERN rc_t CC KClientHttpRelease ( const KClientHttp *self );
189 
190 /* compatibility for existing code */
191 #define KNSManagerMakeHttp KNSManagerMakeClientHttp
192 #define KNSManagerMakeTimedHttp KNSManagerMakeTimedClientHttp
193 #define KHttpAddRef KClientHttpAddRef
194 #define KHttpRelease KClientHttpRelease
195 
196 
197 /*------------------------------------------------------------------------------
198  * KClientHttpRequest
199  *  hyper text transfer protocol
200  *  a client request
201  */
202 typedef struct KClientHttpRequest KClientHttpRequest, KHttpRequest;
203 
204 
205 /* MakeRequest
206  *  create a request that can be used to contact HTTP server
207  *
208  *  "req" [ OUT ] - return parameter for HTTP request object
209  *
210  *  "vers" [ IN ] - http version
211  *
212  *  "conn" [ IN, NULL OKAY ] - previously opened stream for communications.
213  *
214  *  "url" [ IN ] - full resource identifier. if "conn" is NULL,
215  *   the url is parsed for remote endpoint and is opened by mgr.
216  */
217 KNS_EXTERN rc_t CC KClientHttpMakeRequest ( const KClientHttp *self,
218     KClientHttpRequest **req, const char *url, ... );
219 
220 KNS_EXTERN rc_t CC KNSManagerMakeClientRequest ( struct KNSManager const *self,
221     KClientHttpRequest **req, ver_t version, struct KStream *conn, const char *url, ... );
222 
223 
224 /* AddRef
225  * Release
226  *  ignores NULL references
227  */
228 KNS_EXTERN rc_t CC KClientHttpRequestAddRef ( const KClientHttpRequest *self );
229 KNS_EXTERN rc_t CC KClientHttpRequestRelease ( const KClientHttpRequest *self );
230 
231 
232 /* Connection
233  *  sets connection management headers
234  *
235  *  "close" [ IN ] - if "true", inform the server to close the connection
236  *   after its response ( default for version 1.0 ). when "false" ( default
237  *   for version 1.1 ), ask the server to keep the connection open.
238  *
239  * NB - the server is not required to honor the request
240  */
241 KNS_EXTERN rc_t CC KClientHttpRequestConnection ( KClientHttpRequest *self, bool close );
242 
243 
244 /* SetNoCache
245  *  guard against over-eager proxies that try to cache entire files
246  *  and handle byte-ranges locally.
247  */
248 KNS_EXTERN rc_t CC KClientHttpRequestSetNoCache ( KClientHttpRequest *self );
249 
250 
251 /* ByteRange
252  *  set requested byte range of response
253  *
254  *  "pos" [ IN ] - beginning offset within remote entity
255  *
256  *  "bytes" [ IN ] - the number of bytes being requested
257  */
258 KNS_EXTERN rc_t CC KClientHttpRequestByteRange ( KClientHttpRequest *self, uint64_t pos, size_t bytes );
259 
260 
261 /* AddHeader
262  *  allow addition of an arbitrary HTTP header to message
263  */
264 KNS_EXTERN rc_t CC KClientHttpRequestAddHeader ( KClientHttpRequest *self,
265     const char *name, const char *val, ... );
266 
267 /* GetHeader
268  *  retrieve named header if present
269  *  this can potentially return a comma separated value list
270  */
271 KNS_EXTERN rc_t CC KClientHttpRequestGetHeader ( const KClientHttpRequest *self, const char *name,
272     char *buffer, size_t bsize, size_t *num_read );
273 
274 /* GetHost
275  *  retrieve host
276  */
277 KNS_EXTERN rc_t CC KClientHttpRequestGetHost(const KClientHttpRequest *self,
278     char *buffer, size_t bsize, size_t *num_read);
279 
280 /* GetPath
281  *  retrieve path
282  */
283 KNS_EXTERN rc_t CC KClientHttpRequestGetPath(const KClientHttpRequest *self,
284     char *buffer, size_t bsize, size_t *num_read);
285 
286 /* AddQueryParam
287  *  adds a parameter to the query part of the URL, as "[opt_name=]value" (value is the result of formatting)
288  *  inserts ? before the first parameter and & between parameters
289  *  if opt_name is NULL or empty, there will be no '=' before the value
290  *  URL-encodes the formatted value
291  */
292 KNS_EXTERN rc_t CC KClientHttpRequestAddQueryParam ( KClientHttpRequest *self, const char * opt_name, const char *fmt, ... );
293 KNS_EXTERN rc_t CC KClientHttpRequestVAddQueryParam ( KClientHttpRequest *self, const char * opt_name, const char *fmt, va_list args );
294 
295 /* AddPostParam
296  *  adds a parameter for POST
297  */
298 KNS_EXTERN rc_t CC KClientHttpRequestAddPostParam ( KClientHttpRequest *self, const char *fmt, ... );
299 KNS_EXTERN rc_t CC KClientHttpRequestVAddPostParam ( KClientHttpRequest *self, const char *fmt, va_list args );
300 
301 /* AddPostFileParam
302  *  adds a file to be transmitted with POST on the URL in the form "name=<base64encodedContentsOfTheFile>"
303  *  "name" [ IN ] - field name identifying this file in the resulting HTML form. An empty name is OK
304  *  "path" [ IN ] - NUL terminated string in directory-native character set denoting target file
305 **/
306 KNS_EXTERN rc_t CC KClientHttpRequestAddPostFileParam ( KClientHttpRequest *self, const char *name, const char *path );
307 
308 KNS_EXTERN rc_t CC KClientHttpRequestSetCloudParams(KClientHttpRequest * self,
309     bool ceRequired, bool payRequired);
310 
311 /* compatibility for existing code */
312 #define KHttpMakeRequest KClientHttpMakeRequest
313 #define KNSManagerMakeRequest KNSManagerMakeClientRequest
314 #define KHttpRequestAddRef KClientHttpRequestAddRef
315 #define KHttpRequestRelease KClientHttpRequestRelease
316 #define KHttpRequestConnection KClientHttpRequestConnection
317 #define KHttpRequestByteRange KClientHttpRequestByteRange
318 #define KHttpRequestAddHeader KClientHttpRequestAddHeader
319 #define KHttpRequestAddPostParam KClientHttpRequestAddPostParam
320 #define KHttpRequestVAddPostParam KClientHttpRequestVAddPostParam
321 #define KHttpRequestSetCloudParams KClientHttpRequestSetCloudParams
322 
323 /*--------------------------------------------------------------------------
324  * KClientHttpResult
325  *  hyper text transfer protocol
326  */
327 typedef struct KClientHttpResult KClientHttpResult, KHttpResult;
328 
329 
330 /* AddRef
331  * Release
332  *  ignores NULL references
333  */
334 KNS_EXTERN rc_t CC KClientHttpResultAddRef ( const KClientHttpResult *self );
335 KNS_EXTERN rc_t CC KClientHttpResultRelease ( const KClientHttpResult *self );
336 
337 
338 /* HEAD
339  *  send HEAD message
340  */
341 KNS_EXTERN rc_t CC KClientHttpRequestHEAD ( KClientHttpRequest *self, KClientHttpResult **rslt );
342 
343 /* GET
344  *  send GET message
345  *  all query AND post parameters are combined in URL
346  */
347 KNS_EXTERN rc_t CC KClientHttpRequestGET ( KClientHttpRequest *self, KClientHttpResult **rslt );
348 
349 /* POST
350  *  send POST message
351  *  query parameters are sent in URL
352  *  post parameters are sent in body
353  */
354 KNS_EXTERN rc_t CC KClientHttpRequestPOST ( KClientHttpRequest *self, KClientHttpResult **rslt );
355 
356 
357 /* Status
358  *  access the response status code
359  *  and optionally the message
360  *
361  *  "code" [ OUT ] - return parameter for status code
362  *
363  *  "msg_buff" [ IN, NULL OKAY ] and "buff_size" [ IN, ZERO OKAY ] -
364  *   buffer for capturing returned message
365  *
366  *  "msg_size" [ OUT, NULL OKAY ] - size of returned message in bytes
367  */
368 KNS_EXTERN rc_t CC KClientHttpResultStatus ( const KClientHttpResult *self, uint32_t *code,
369     char *msg_buff, size_t buff_size, size_t *msg_size );
370 
371 
372 /* KeepAlive
373  *  retrieves keep-alive property of response
374  *  requires HTTP/1.1
375  */
376 KNS_EXTERN bool CC KClientHttpResultKeepAlive ( const KClientHttpResult *self );
377 
378 
379 /* Range
380  *  retrieves position and partial size for partial requests
381  *
382  *  "pos" [ OUT ] - offset to beginning portion of response
383  *
384  *  "bytes" [ OUT ] - size of range
385  */
386 KNS_EXTERN rc_t CC KClientHttpResultRange ( const KClientHttpResult *self, uint64_t *pos, size_t *bytes );
387 
388 
389 /* Size
390  *  retrieves overall size of entity, if known
391  *
392  *  "response_size" [ OUT ] - size in bytes of response
393  *   this is the number of bytes that may be expected from the input stream
394  */
395 KNS_EXTERN bool CC KClientHttpResultSize ( const KClientHttpResult *self, uint64_t *size );
396 
397 
398 /* AddHeader
399  *  allow addition of an arbitrary HTTP header to RESPONSE
400  *  this can be used to repair or normalize odd server behavior
401  */
402 KNS_EXTERN rc_t CC KClientHttpResultAddHeader ( KClientHttpResult *self,
403     const char *name, const char *val, ... );
404 
405 
406 /* GetHeader
407  *  retrieve named header if present
408  *  this can potentially return a comma separated value list
409  */
410 KNS_EXTERN rc_t CC KClientHttpResultGetHeader ( const KClientHttpResult *self, const char *name,
411     char *buffer, size_t bsize, size_t *num_read );
412 
413 
414 /* TestHeaderValue
415  *  test for existence of header and a particular value
416  *  if the header exists and has a comma-separated list of values,
417  *  test each value individually, i.e. splits on comma before comparison
418  */
419 KNS_EXTERN bool CC KClientHttpResultTestHeaderValue ( const KClientHttpResult *self,
420     const char *name, const char *value );
421 
422 
423 /* GetInputStream
424  *  access the body of response as a stream
425  *  only reads are supported
426  *
427  *  "s" [ OUT ] - return parameter for input stream reference
428  *   must be released via KStreamRelease
429  */
430 KNS_EXTERN rc_t CC KClientHttpResultGetInputStream ( KClientHttpResult *self,
431     struct KStream  ** s );
432 
433 KNS_EXTERN bool CC KFileIsKHttpFile ( const struct KFile * self );
434 
435     /* compatibility defines */
436 #define KHttpResultAddRef KClientHttpResultAddRef
437 #define KHttpResultRelease KClientHttpResultRelease
438 #define KHttpRequestHEAD KClientHttpRequestHEAD
439 #define KHttpRequestGET KClientHttpRequestGET
440 #define KHttpRequestPOST KClientHttpRequestPOST
441 #define KHttpResultStatus KClientHttpResultStatus
442 #define KHttpResultKeepAlive KClientHttpResultKeepAlive
443 #define KHttpResultRange KClientHttpResultRange
444 #define KHttpResultSize KClientHttpResultSize
445 #define KHttpResultAddHeader KClientHttpResultAddHeader
446 #define KHttpResultGetHeader KClientHttpResultGetHeader
447 #define KHttpResultGetInputStream KClientHttpResultGetInputStream
448 
449 
450 #ifdef __cplusplus
451 }
452 #endif
453 
454 #endif /* _h_kns_http_ */
455