Skip to content

Commit fc8060b

Browse files
committed
lib/libfetch: Add fetchXReqHTTP(3)
Modern APIs often rely on HTTP headers as part of their interface, both in requests and responses. Add a function to libfetch allowing additional request headers to be specified for an HTTP request and response headers to be returned to the caller. This function accepts an optional stream for the body content, as a nul-terminated C string may be inadequate for some content. If the length of the stream can be determined, a Content-Length header is added. Otherwise, the body is sent chunk-encoded. Handling of HTTP trailers remains unimplemented. Signed-off-by: Ryan Moeller <[email protected]>
1 parent 723445f commit fc8060b

File tree

5 files changed

+231
-35
lines changed

5 files changed

+231
-35
lines changed

lib/libfetch/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ httperr.h: http.errors ${.CURDIR}/Makefile
4848
@echo " { -1, FETCH_UNKNOWN, \"Unknown HTTP error\" }" >> ${.TARGET}
4949
@echo "};" >> ${.TARGET}
5050

51+
MLINKS+= fetch.3 fetchFreeResHeaders.3
5152
MLINKS+= fetch.3 fetchFreeURL.3
5253
MLINKS+= fetch.3 fetchGet.3
5354
MLINKS+= fetch.3 fetchGetFTP.3
@@ -77,5 +78,6 @@ MLINKS+= fetch.3 fetchXGetFTP.3
7778
MLINKS+= fetch.3 fetchXGetFile.3
7879
MLINKS+= fetch.3 fetchXGetHTTP.3
7980
MLINKS+= fetch.3 fetchXGetURL.3
81+
MLINKS+= fetch.3 fetchXReqHTTP.3
8082

8183
.include <bsd.lib.mk>

lib/libfetch/common.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,6 @@ int fetch_no_proxy_match(const char *);
161161
*/
162162
FILE *http_request(struct url *, const char *,
163163
struct url_stat *, struct url *, const char *);
164-
FILE *http_request_body(struct url *, const char *,
165-
struct url_stat *, struct url *, const char *,
166-
const char *, const char *);
167164
FILE *ftp_request(struct url *, const char *,
168165
struct url_stat *, struct url *, const char *);
169166

lib/libfetch/fetch.3

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2525
.\" SUCH DAMAGE.
2626
.\"
27-
.Dd October 7, 2023
27+
.Dd September 27, 2025
2828
.Dt FETCH 3
2929
.Os
3030
.Sh NAME
@@ -52,6 +52,8 @@
5252
.Nm fetchStatHTTP ,
5353
.Nm fetchListHTTP ,
5454
.Nm fetchReqHTTP ,
55+
.Nm fetchXReqHTTP ,
56+
.Nm fetchFreeResHeaders ,
5557
.Nm fetchXGetFTP ,
5658
.Nm fetchGetFTP ,
5759
.Nm fetchPutFTP ,
@@ -112,6 +114,11 @@
112114
.Fn fetchListHTTP "struct url *u" "const char *flags"
113115
.Ft FILE *
114116
.Fn fetchReqHTTP "struct url *u" "const char *method" "const char *flags" "const char *content_type" "const char *body"
117+
.In sys/queue.h
118+
.Ft FILE *
119+
.Fn fetchXReqHTTP "struct url *u" "struct url_stat *us" "const char *method" "const char *flags" "const struct http_headers *reqhdrs" "struct http_headers *reshdrs" "FILE *body"
120+
.Ft void
121+
.Fn fetchFreeResHeaders "struct http_headers *reshdrs"
115122
.Ft FILE *
116123
.Fn fetchXGetFTP "struct url *u" "struct url_stat *us" "const char *flags"
117124
.Ft FILE *
@@ -357,9 +364,10 @@ and password "anonymous@<hostname>".
357364
The
358365
.Fn fetchXGetHTTP ,
359366
.Fn fetchGetHTTP ,
360-
.Fn fetchPutHTTP
361-
and
367+
.Fn fetchPutHTTP ,
362368
.Fn fetchReqHTTP
369+
and
370+
.Fn fetchXReqHTTP
363371
functions implement the HTTP/1.1 protocol.
364372
With a little luck, there is
365373
even a chance that they comply with RFC2616 and RFC2617.
@@ -389,8 +397,10 @@ will send a conditional
389397
HTTP header to only fetch the content if it is newer than
390398
.Va ims_time .
391399
.Pp
392-
The function
400+
The functions
393401
.Fn fetchReqHTTP
402+
and
403+
.Fn fetchXReqHTTP
394404
can be used to make requests with an arbitrary HTTP verb,
395405
including POST, DELETE, CONNECT, OPTIONS, TRACE or PATCH.
396406
This can be done by setting the argument
@@ -401,10 +411,34 @@ and
401411
.Fa body
402412
to the content.
403413
.Pp
404-
Since there seems to be no good way of implementing the HTTP PUT
405-
method in a manner consistent with the rest of the
406-
.Nm fetch
407-
library,
414+
In addition to returning
415+
.Vt "struct url_stat"
416+
information,
417+
.Fn fetchXReqHTTP
418+
also accepts an optional list of arbitrary additional headers to send before the
419+
body,
420+
an optional list to be filled with all response headers received,
421+
and
422+
an optional
423+
.Vt "FILE"
424+
stream to send as the body.
425+
The response headers list should be freed with
426+
.Fn fetchFreeResHeaders .
427+
The
428+
.Vt http_header
429+
and
430+
.Vt http_headers
431+
structures are defined as follows in
432+
.In fetch.h :
433+
.Bd -literal
434+
struct http_header {
435+
const char *name;
436+
const char *value;
437+
TAILQ_ENTRY(http_header) headers;
438+
};
439+
TAILQ_HEAD(http_headers, http_header);
440+
.Ed
441+
.Pp
408442
.Fn fetchPutHTTP
409443
is currently unimplemented.
410444
.Sh HTTPS SCHEME

lib/libfetch/fetch.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#ifndef _FETCH_H_INCLUDED
3232
#define _FETCH_H_INCLUDED
3333

34-
#define _LIBFETCH_VER "libfetch/2.0"
34+
#define _LIBFETCH_VER "libfetch/2.1"
3535

3636
#define URL_SCHEMELEN 16
3737
#define URL_USERLEN 256
@@ -61,6 +61,15 @@ struct url_ent {
6161
struct url_stat stat;
6262
};
6363

64+
#ifdef _SYS_QUEUE_H_
65+
struct http_header {
66+
const char *name;
67+
const char *value;
68+
TAILQ_ENTRY(http_header) headers;
69+
};
70+
TAILQ_HEAD(http_headers, http_header);
71+
#endif
72+
6473
/* Recognized schemes */
6574
#define SCHEME_FTP "ftp"
6675
#define SCHEME_HTTP "http"
@@ -105,6 +114,12 @@ int fetchStatHTTP(struct url *, struct url_stat *, const char *);
105114
struct url_ent *fetchListHTTP(struct url *, const char *);
106115
FILE *fetchReqHTTP(struct url *, const char *, const char *,
107116
const char *, const char *);
117+
#ifdef _SYS_QUEUE_H_
118+
FILE *fetchXReqHTTP(struct url *, struct url_stat *, const char *,
119+
const char *, const struct http_headers *,
120+
struct http_headers *, FILE *);
121+
void fetchFreeResHeaders(struct http_headers *);
122+
#endif
108123

109124
/* FTP-specific functions */
110125
FILE *fetchXGetFTP(struct url *, struct url_stat *, const char *);

0 commit comments

Comments
 (0)