Skip to content

Commit 9ac2c5a

Browse files
committed
HTTP: intern the version and avoid allocation
There are only a few possible reasonable values, and we can intern them to avoid any allocations for it. (We will probably do the same for the HTTP method shortly as well.)
1 parent f0e0801 commit 9ac2c5a

File tree

4 files changed

+52
-33
lines changed

4 files changed

+52
-33
lines changed

docs/man/nng_http_req_set_version.3http.adoc

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
= nng_http_req_set_version(3http)
22
//
3-
// Copyright 2018 Staysail Systems, Inc. <[email protected]>
3+
// Copyright 2024 Staysail Systems, Inc. <[email protected]>
44
// Copyright 2018 Capitar IT Group BV <[email protected]>
55
//
66
// This document is supplied under the terms of the MIT License, a
@@ -20,6 +20,9 @@ nng_http_req_set_version - set HTTP request protocol version
2020
#include <nng/nng.h>
2121
#include <nng/supplemental/http/http.h>
2222
23+
#define NNG_HTTP_VERSION_1_1 "HTTP/1.0"
24+
#define NNG_HTTP_VERSION_1_1 "HTTP/1.1"
25+
2326
int nng_http_req_set_version(nng_http_req *req, const char *version);
2427
----
2528

@@ -33,12 +36,8 @@ The default value is "HTTP/1.1".
3336

3437
A local copy of the _version_ is made in the request _req_.
3538

36-
NOTE: No validation of the version supplied is performed.
37-
3839
NOTE: The library does not contain support for versions of HTTP other than
3940
"HTTP/1.0" and "HTTP/1.1".
40-
Specifying any other version may result in unspecified behavior.
41-
4241

4342
== RETURN VALUES
4443

@@ -48,7 +47,7 @@ This function returns 0 on success, and non-zero otherwise.
4847

4948
[horizontal]
5049
`NNG_ENOMEM`:: Insufficient memory to perform the operation.
51-
`NNG_ENOTSUP`:: No support for HTTP in the library.
50+
`NNG_ENOTSUP`:: No support for HTTP in the library, or no support for the version specified.
5251

5352
== SEE ALSO
5453

docs/man/nng_http_res_set_version.3http.adoc

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
= nng_http_res_set_version(3http)
22
//
3-
// Copyright 2018 Staysail Systems, Inc. <[email protected]>
3+
// Copyright 2024 Staysail Systems, Inc. <[email protected]>
44
// Copyright 2018 Capitar IT Group BV <[email protected]>
55
//
66
// This document is supplied under the terms of the MIT License, a
@@ -20,6 +20,9 @@ nng_http_res_set_version - set HTTP response protocol version
2020
#include <nng/nng.h>
2121
#include <nng/supplemental/http/http.h>
2222
23+
#define NNG_HTTP_VERSION_1_1 "HTTP/1.0"
24+
#define NNG_HTTP_VERSION_1_1 "HTTP/1.1"
25+
2326
int nng_http_res_set_version(nng_http_res *res, const char *version);
2427
----
2528

@@ -33,12 +36,8 @@ The default value is "HTTP/1.1".
3336

3437
A local copy of the _version_ is made in the response _res_.
3538

36-
NOTE: No validation of the version supplied is performed.
37-
3839
NOTE: The library does not contain support for versions of HTTP other than
3940
"HTTP/1.0" and "HTTP/1.1".
40-
Specifying any other version may result in unspecified behavior.
41-
4241

4342
== RETURN VALUES
4443

@@ -48,7 +47,7 @@ This function returns 0 on success, and non-zero otherwise.
4847

4948
[horizontal]
5049
`NNG_ENOMEM`:: Insufficient memory to perform the operation.
51-
`NNG_ENOTSUP`:: No support for HTTP in the library.
50+
`NNG_ENOTSUP`:: No support for HTTP in the library, or no support for the version specified.
5251

5352
== SEE ALSO
5453

include/nng/supplemental/http/http.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ enum nng_http_status {
8787
NNG_HTTP_STATUS_NETWORK_AUTH_REQUIRED = 511,
8888
};
8989

90+
#define NNG_HTTP_VERSION_1_0 "HTTP/1.0"
91+
#define NNG_HTTP_VERSION_1_1 "HTTP/1.1"
92+
#define NNG_HTTP_VERSION_2 "HTTP/2"
93+
#define NNG_HTTP_VERSION_3 "HTTP/3"
94+
9095
// nng_http_req represents an HTTP request.
9196
typedef struct nng_http_req nng_http_req;
9297

src/supplemental/http/http_msg.c

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include "core/nng_impl.h"
1818
#include "http_api.h"
19+
#include "nng/supplemental/http/http.h"
1920

2021
// Note that as we parse headers, the rule is that if a header is already
2122
// present, then we can append it to the existing header, separated by
@@ -39,7 +40,7 @@ struct nng_http_req {
3940
nni_http_entity data;
4041
char *meth;
4142
char *uri;
42-
char *vers;
43+
const char *vers;
4344
char *buf;
4445
size_t bufsz;
4546
bool parsed;
@@ -50,7 +51,7 @@ struct nng_http_res {
5051
nni_http_entity data;
5152
uint16_t code;
5253
char *rsn;
53-
char *vers;
54+
const char *vers;
5455
char *buf;
5556
size_t bufsz;
5657
bool parsed;
@@ -99,14 +100,14 @@ nni_http_req_reset(nni_http_req *req)
99100
{
100101
http_headers_reset(&req->hdrs);
101102
http_entity_reset(&req->data);
102-
nni_strfree(req->vers);
103103
nni_strfree(req->meth);
104104
nni_strfree(req->uri);
105-
req->vers = req->meth = req->uri = NULL;
105+
req->meth = req->uri = NULL;
106106
nni_free(req->buf, req->bufsz);
107107
req->bufsz = 0;
108108
req->buf = NULL;
109109
req->parsed = false;
110+
req->vers = NNG_HTTP_VERSION_1_1;
110111
}
111112

112113
void
@@ -115,8 +116,7 @@ nni_http_res_reset(nni_http_res *res)
115116
http_headers_reset(&res->hdrs);
116117
http_entity_reset(&res->data);
117118
nni_strfree(res->rsn);
118-
nni_strfree(res->vers);
119-
res->vers = NULL;
119+
res->vers = NNG_HTTP_VERSION_1_1;
120120
res->rsn = NULL;
121121
res->code = 0;
122122
res->parsed = false;
@@ -532,8 +532,7 @@ http_req_prepare(nni_http_req *req)
532532
return (NNG_EINVAL);
533533
}
534534
rv = http_asprintf(&req->buf, &req->bufsz, &req->hdrs, "%s %s %s\r\n",
535-
req->meth != NULL ? req->meth : "GET", req->uri,
536-
req->vers != NULL ? req->vers : "HTTP/1.1");
535+
req->meth != NULL ? req->meth : "GET", req->uri, req->vers);
537536
return (rv);
538537
}
539538

@@ -542,7 +541,7 @@ http_res_prepare(nni_http_res *res)
542541
{
543542
int rv;
544543
rv = http_asprintf(&res->buf, &res->bufsz, &res->hdrs, "%s %d %s\r\n",
545-
nni_http_res_get_version(res), nni_http_res_get_status(res),
544+
res->vers, nni_http_res_get_status(res),
546545
nni_http_res_get_reason(res));
547546
return (rv);
548547
}
@@ -612,7 +611,7 @@ nni_http_req_alloc(nni_http_req **reqp, const nng_url *url)
612611
req->data.data = NULL;
613612
req->data.size = 0;
614613
req->data.own = false;
615-
req->vers = NULL;
614+
req->vers = NNG_HTTP_VERSION_1_1;
616615
req->meth = NULL;
617616
req->uri = NULL;
618617
if (url != NULL) {
@@ -664,7 +663,7 @@ nni_http_res_alloc(nni_http_res **resp)
664663
res->data.data = NULL;
665664
res->data.size = 0;
666665
res->data.own = false;
667-
res->vers = NULL;
666+
res->vers = NNG_HTTP_VERSION_1_1;
668667
res->rsn = NULL;
669668
res->code = 0;
670669
*resp = res;
@@ -686,31 +685,48 @@ nni_http_req_get_uri(const nni_http_req *req)
686685
const char *
687686
nni_http_req_get_version(const nni_http_req *req)
688687
{
689-
return (req->vers != NULL ? req->vers : "HTTP/1.1");
688+
return (req->vers);
690689
}
691690

692691
const char *
693692
nni_http_res_get_version(const nni_http_res *res)
694693
{
695-
return (res->vers != NULL ? res->vers : "HTTP/1.1");
694+
return (res->vers);
695+
}
696+
697+
static const char *http_versions[] = {
698+
// for efficiency, we order in most likely first
699+
"HTTP/1.1",
700+
"HTTP/2",
701+
"HTTP/3",
702+
"HTTP/1.0",
703+
"HTTP/0.9",
704+
NULL,
705+
};
706+
707+
static int
708+
http_set_version(const char **ptr, const char *vers)
709+
{
710+
vers = vers != NULL ? vers : NNG_HTTP_VERSION_1_1;
711+
for (int i = 0; http_versions[i] != NULL; i++) {
712+
if (strcmp(vers, http_versions[i]) == 0) {
713+
*ptr = http_versions[i];
714+
return (0);
715+
}
716+
}
717+
return (NNG_ENOTSUP);
696718
}
697719

698720
int
699721
nni_http_req_set_version(nni_http_req *req, const char *vers)
700722
{
701-
if ((vers != NULL) && (strcmp(vers, "HTTP/1.1") == 0)) {
702-
vers = NULL;
703-
}
704-
return (http_set_string(&req->vers, vers));
723+
return (http_set_version(&req->vers, vers));
705724
}
706725

707726
int
708727
nni_http_res_set_version(nni_http_res *res, const char *vers)
709728
{
710-
if ((vers != NULL) && (strcmp(vers, "HTTP/1.1") == 0)) {
711-
vers = NULL;
712-
}
713-
return (http_set_string(&res->vers, vers));
729+
return (http_set_version(&res->vers, vers));
714730
}
715731

716732
int

0 commit comments

Comments
 (0)