Introduction
Introduction Statistics Contact Development Disclaimer Help
servedir: some line reading buffer optimizations - gopherproxy-c - Gopher HTTP …
git clone git://git.codemadness.org/gopherproxy-c
Log
Files
Refs
README
LICENSE
---
commit 00c13341a4b18c68b1ea0b157c84b840c5f89245
parent 407a5ede41c92b0b9b711bd376493a579995da36
Author: Hiltjo Posthuma <[email protected]>
Date: Mon, 4 Aug 2025 13:31:21 +0200
servedir: some line reading buffer optimizations
Diffstat:
M gopherproxy.c | 66 +++++++++++++++++++----------…
1 file changed, 41 insertions(+), 25 deletions(-)
---
diff --git a/gopherproxy.c b/gopherproxy.c
@@ -26,6 +26,9 @@ static struct tls *t;
static struct tls_config *tls_config;
#endif
+#define MAX_LINE_SIZ 2048 /* max size of a DirEntry in bytes */
+#define READ_BUF_SIZ 16384 /* read buffer size in bytes */
+
#define MAX_RESPONSETIMEOUT 10 /* timeout in seconds */
#define MAX_RESPONSESIZ 4000000 /* max download size in bytes */
@@ -53,6 +56,19 @@ struct visited {
char port[8];
};
+struct linebuf {
+ /* line buffer */
+ char *line;
+ char linebuf[MAX_LINE_SIZ];
+ size_t linelen;
+ size_t lineoff;
+ /* read buffer */
+ char buf[READ_BUF_SIZ];
+ char *bufoff, *bufend;
+ int err;
+ int eof;
+};
+
/* parsed URI */
static struct uri u;
/* socket fd */
@@ -338,21 +354,11 @@ plain_readbuf(char *buf, size_t bufsiz)
return len;
}
-struct linebuf {
- /* line buffer */
- char line[2048];
- size_t linelen;
- size_t lineoff;
- /* read buffer */
- char buf[4096];
- char *bufoff, *bufend;
- int err;
-};
-
void
linebuf_init(struct linebuf *b)
{
memset(b, 0, sizeof(struct linebuf));
+ b->line = b->linebuf;
}
ssize_t
@@ -362,7 +368,8 @@ linebuf_get(struct linebuf *b)
ssize_t n;
char *p;
- while (!(b->err)) {
+ b->line = b->linebuf;
+ while (!(b->err) && !(b->eof)) {
/* need to read more */
if (b->bufoff >= b->bufend) {
b->bufoff = b->buf;
@@ -372,8 +379,10 @@ linebuf_get(struct linebuf *b)
b->err = EIO;
/* use remaining data even if not terminated by a newl…
- if (n == 0 && b->linelen > 0)
- return b->linelen;
+ if (n == 0 && b->lineoff > 0) {
+ b->eof = 1;
+ return b->lineoff;
+ }
if (n > 0)
b->bufend = b->buf + n;
@@ -384,16 +393,22 @@ linebuf_get(struct linebuf *b)
/* search first newline */
if ((p = memchr(b->bufoff, '\n', b->bufend - b->bufoff))) {
len = (p - b->bufoff);
+ /* full line in buffer, no need to copy to line buffer…
+ if (b->lineoff == 0)
+ b->line = b->bufoff; /* just point to buffer, …
} else {
- /* copy remaining data into line buffer and read more …
+ /* use remaining data into line buffer and read more */
len = (b->bufend - b->bufoff);
}
- if (b->lineoff + len + 1 >= sizeof(b->line)) {
- b->err = ENOMEM;
- return -1;
+ if (b->line == b->linebuf) {
+ if (b->lineoff + len + 1 >= sizeof(b->linebuf)) {
+ b->err = ENOMEM;
+ return -1;
+ }
+ memcpy(b->linebuf + b->lineoff, b->bufoff, len);
}
- memcpy(b->line + b->lineoff, b->bufoff, len);
+
b->lineoff += len;
b->linelen = b->lineoff;
b->line[b->linelen] = '\0';
@@ -453,7 +468,7 @@ typestr(int c)
void
servefile(const char *server, const char *port, const char *path, const char *…
{
- char buf[1024];
+ char buf[READ_BUF_SIZ];
int r, w;
size_t totalsiz = 0;
@@ -484,7 +499,7 @@ servedir(const char *server, const char *port, const char *…
struct visited v;
struct linebuf lb;
const char *prefix = "";
- char buf[1024], uri[2048];
+ char buf[1024], *uri;
char *line;
size_t totalsiz, linenr;
ssize_t n;
@@ -507,11 +522,11 @@ servedir(const char *server, const char *port, const char…
die(500, "servedir: writebuf failed\n");
linebuf_init(&lb);
- line = lb.line;
totalsiz = 0;
-
for (linenr = 1; (n = linebuf_get(&lb)) > 0; linenr++) {
+ line = lb.line;
+
/* too big total response */
if (n > 0)
totalsiz += n;
@@ -593,11 +608,12 @@ servedir(const char *server, const char *port, const char…
}
if (!strcmp(v.port, "70"))
- snprintf(uri, sizeof(uri), "%s%s/%c%s",
+ snprintf(buf, sizeof(buf), "%s%s/%c%s",
prefix, v.server, primarytype, v.path);
else
- snprintf(uri, sizeof(uri), "%s%s:%s/%c%s",
+ snprintf(buf, sizeof(buf), "%s%s:%s/%c%s",
prefix, v.server, v.port, primarytype, v.path);
+ uri = buf;
switch (primarytype) {
case 'i': /* info */
You are viewing proxied material from codemadness.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.