Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTP: intern the version and avoid allocation #2005

Merged
merged 1 commit into from
Dec 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions docs/man/nng_http_req_set_version.3http.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
= nng_http_req_set_version(3http)
//
// Copyright 2018 Staysail Systems, Inc. <[email protected]>
// Copyright 2024 Staysail Systems, Inc. <[email protected]>
// Copyright 2018 Capitar IT Group BV <[email protected]>
//
// This document is supplied under the terms of the MIT License, a
Expand All @@ -20,6 +20,9 @@ nng_http_req_set_version - set HTTP request protocol version
#include <nng/nng.h>
#include <nng/supplemental/http/http.h>

#define NNG_HTTP_VERSION_1_1 "HTTP/1.0"
#define NNG_HTTP_VERSION_1_1 "HTTP/1.1"

int nng_http_req_set_version(nng_http_req *req, const char *version);
----

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

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

NOTE: No validation of the version supplied is performed.

NOTE: The library does not contain support for versions of HTTP other than
"HTTP/1.0" and "HTTP/1.1".
Specifying any other version may result in unspecified behavior.


== RETURN VALUES

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

[horizontal]
`NNG_ENOMEM`:: Insufficient memory to perform the operation.
`NNG_ENOTSUP`:: No support for HTTP in the library.
`NNG_ENOTSUP`:: No support for HTTP in the library, or no support for the version specified.

== SEE ALSO

Expand Down
11 changes: 5 additions & 6 deletions docs/man/nng_http_res_set_version.3http.adoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
= nng_http_res_set_version(3http)
//
// Copyright 2018 Staysail Systems, Inc. <[email protected]>
// Copyright 2024 Staysail Systems, Inc. <[email protected]>
// Copyright 2018 Capitar IT Group BV <[email protected]>
//
// This document is supplied under the terms of the MIT License, a
Expand All @@ -20,6 +20,9 @@ nng_http_res_set_version - set HTTP response protocol version
#include <nng/nng.h>
#include <nng/supplemental/http/http.h>

#define NNG_HTTP_VERSION_1_1 "HTTP/1.0"
#define NNG_HTTP_VERSION_1_1 "HTTP/1.1"

int nng_http_res_set_version(nng_http_res *res, const char *version);
----

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

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

NOTE: No validation of the version supplied is performed.

NOTE: The library does not contain support for versions of HTTP other than
"HTTP/1.0" and "HTTP/1.1".
Specifying any other version may result in unspecified behavior.


== RETURN VALUES

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

[horizontal]
`NNG_ENOMEM`:: Insufficient memory to perform the operation.
`NNG_ENOTSUP`:: No support for HTTP in the library.
`NNG_ENOTSUP`:: No support for HTTP in the library, or no support for the version specified.

== SEE ALSO

Expand Down
5 changes: 5 additions & 0 deletions include/nng/supplemental/http/http.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ enum nng_http_status {
NNG_HTTP_STATUS_NETWORK_AUTH_REQUIRED = 511,
};

#define NNG_HTTP_VERSION_1_0 "HTTP/1.0"
#define NNG_HTTP_VERSION_1_1 "HTTP/1.1"
#define NNG_HTTP_VERSION_2 "HTTP/2"
#define NNG_HTTP_VERSION_3 "HTTP/3"

// nng_http_req represents an HTTP request.
typedef struct nng_http_req nng_http_req;

Expand Down
58 changes: 37 additions & 21 deletions src/supplemental/http/http_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include "core/nng_impl.h"
#include "http_api.h"
#include "nng/supplemental/http/http.h"

// Note that as we parse headers, the rule is that if a header is already
// present, then we can append it to the existing header, separated by
Expand All @@ -39,7 +40,7 @@
nni_http_entity data;
char *meth;
char *uri;
char *vers;
const char *vers;
char *buf;
size_t bufsz;
bool parsed;
Expand All @@ -50,7 +51,7 @@
nni_http_entity data;
uint16_t code;
char *rsn;
char *vers;
const char *vers;
char *buf;
size_t bufsz;
bool parsed;
Expand Down Expand Up @@ -99,14 +100,14 @@
{
http_headers_reset(&req->hdrs);
http_entity_reset(&req->data);
nni_strfree(req->vers);
nni_strfree(req->meth);
nni_strfree(req->uri);
req->vers = req->meth = req->uri = NULL;
req->meth = req->uri = NULL;
nni_free(req->buf, req->bufsz);
req->bufsz = 0;
req->buf = NULL;
req->parsed = false;
req->vers = NNG_HTTP_VERSION_1_1;
}

void
Expand All @@ -115,8 +116,7 @@
http_headers_reset(&res->hdrs);
http_entity_reset(&res->data);
nni_strfree(res->rsn);
nni_strfree(res->vers);
res->vers = NULL;
res->vers = NNG_HTTP_VERSION_1_1;
res->rsn = NULL;
res->code = 0;
res->parsed = false;
Expand Down Expand Up @@ -532,8 +532,7 @@
return (NNG_EINVAL);
}
rv = http_asprintf(&req->buf, &req->bufsz, &req->hdrs, "%s %s %s\r\n",
req->meth != NULL ? req->meth : "GET", req->uri,
req->vers != NULL ? req->vers : "HTTP/1.1");
req->meth != NULL ? req->meth : "GET", req->uri, req->vers);
return (rv);
}

Expand All @@ -542,7 +541,7 @@
{
int rv;
rv = http_asprintf(&res->buf, &res->bufsz, &res->hdrs, "%s %d %s\r\n",
nni_http_res_get_version(res), nni_http_res_get_status(res),
res->vers, nni_http_res_get_status(res),
nni_http_res_get_reason(res));
return (rv);
}
Expand Down Expand Up @@ -612,7 +611,7 @@
req->data.data = NULL;
req->data.size = 0;
req->data.own = false;
req->vers = NULL;
req->vers = NNG_HTTP_VERSION_1_1;
req->meth = NULL;
req->uri = NULL;
if (url != NULL) {
Expand Down Expand Up @@ -664,7 +663,7 @@
res->data.data = NULL;
res->data.size = 0;
res->data.own = false;
res->vers = NULL;
res->vers = NNG_HTTP_VERSION_1_1;
res->rsn = NULL;
res->code = 0;
*resp = res;
Expand All @@ -686,31 +685,48 @@
const char *
nni_http_req_get_version(const nni_http_req *req)
{
return (req->vers != NULL ? req->vers : "HTTP/1.1");
return (req->vers);
}

const char *
nni_http_res_get_version(const nni_http_res *res)
{
return (res->vers != NULL ? res->vers : "HTTP/1.1");
return (res->vers);

Check warning on line 694 in src/supplemental/http/http_msg.c

View check run for this annotation

Codecov / codecov/patch

src/supplemental/http/http_msg.c#L694

Added line #L694 was not covered by tests
}

static const char *http_versions[] = {
// for efficiency, we order in most likely first
"HTTP/1.1",
"HTTP/2",
"HTTP/3",
"HTTP/1.0",
"HTTP/0.9",
NULL,
};

static int
http_set_version(const char **ptr, const char *vers)
{
vers = vers != NULL ? vers : NNG_HTTP_VERSION_1_1;
for (int i = 0; http_versions[i] != NULL; i++) {
if (strcmp(vers, http_versions[i]) == 0) {
*ptr = http_versions[i];
return (0);
}
}
return (NNG_ENOTSUP);

Check warning on line 717 in src/supplemental/http/http_msg.c

View check run for this annotation

Codecov / codecov/patch

src/supplemental/http/http_msg.c#L717

Added line #L717 was not covered by tests
}

int
nni_http_req_set_version(nni_http_req *req, const char *vers)
{
if ((vers != NULL) && (strcmp(vers, "HTTP/1.1") == 0)) {
vers = NULL;
}
return (http_set_string(&req->vers, vers));
return (http_set_version(&req->vers, vers));
}

int
nni_http_res_set_version(nni_http_res *res, const char *vers)
{
if ((vers != NULL) && (strcmp(vers, "HTTP/1.1") == 0)) {
vers = NULL;
}
return (http_set_string(&res->vers, vers));
return (http_set_version(&res->vers, vers));
}

int
Expand Down
Loading