kcar RubyGem user+dev discussion/patches/pulls/bugs/help
 help / color / mirror / code / Atom feed
Search results ordered by [date|relevance]  view[summary|nested|Atom feed]
thread overview below | download mbox.gz: |
* [ANN] kcar 0.7.0 - bytestream to Rack response converter
@ 2020-02-21  2:32  5% Eric Wong
  0 siblings, 0 replies; 2+ results
From: Eric Wong @ 2020-02-21  2:32 UTC (permalink / raw)
  To: kcar-public

kcar features an HTTP parser that will convert a bytestream into a
3-element array suitable for use as a Rack response.  It is IO interface
agnostic, so it may be used with HTTP streams over Unix domain sockets,
regular files, FIFOs, StringIOs as well as traditional TCP sockets.

* homepage: https://yhbt.net/kcar/
* public inbox: kcar-public@yhbt.net
* git clone https://yhbt.net/kcar.git
* mailing list archives: https://yhbt.net/kcar-public/

Changes:

46 changes since 0.6.0 (2015-08-04):
      README: fix reference to HTTP git viewer
      doc: move site to HTTPS
      pkg.mk: avoid network for "gem install"
      gemspec: use SPDX compatible terms for the license(s)
      archive/slrnpull.conf: add a note explaining the purpose
      drop rb_str_set_len compatibility replacement
      remove rb_str_modify workaround
      TypedData C-API conversion
      test_parser: add lone CR test
      reduce parser size to 88 bytes on 64-bit
      extconf: remove unneeded -fPIC CFLAGS
      rely on String#-@ (str_uminus) to dedupe headers
      update comment about freezing values
      http: reject non-LWS CTL chars (0..31 + 127) in field values
      doc: remove references to a server
      update documentation for contributions, remove private address
      doc: minor updates to describe classes, better
      response: remove unnecessary constant alias
      response: more documentation cleanups
      favor require_relative to speed up loading
      response: remove Ruby 1.8-compatibility check
      fix signedness check on 32-bit systems
      shorten and improve readability of assertion
      HACKING: remove copy+pasted line about N
      olddoc: include NNTP archive link
      gemspec: remove olddoc dev dependency
      README: add info about mailing list subscription
      nodoc Kcar::VERSION
      pkg.mk: support VALGRIND variable for unit tests
      introduce new str_new_dd_freeze internal function
      begin implementing request parsing
      favor bitfields instead flags + macros
      implement request parsing with tests
      pkg.mk: enable warnings by default for tests
      filter_body: rename variables to be like memcpy(3)
      flesh out filter_body for request parsing
      do not assume SERVER_PORT
      do not set "HTTP/0.9" for pre-1.0 requests
      always set non-negative Content-Length for requests
      avoid String#-@ call on request parsing under Ruby 2.6
      request: set env["FRAGMENT"] for WebDAV litmus test
      extconf: fix rb_hash_aset deduplication test
      use rb_gc_register_mark_object
      website: use dark216 to save electricity
      doc: update URLs to point to YHBT.net
      doc: update git:// URLs to HTTPS

^ permalink raw reply	[relevance 5%]

* [PATCH] reduce parser size to 88 bytes on 64-bit
@ 2017-03-05  1:10  7% Eric Wong
  0 siblings, 0 replies; 2+ results
From: Eric Wong @ 2017-03-05  1:10 UTC (permalink / raw)
  To: kcar-public

The actual struct we manage is 48 bytes, along with
40 bytes for object overhead.
---
 ext/kcar/kcar.rl | 42 ++++++++++++++++++++++++++++++++----------
 1 file changed, 32 insertions(+), 10 deletions(-)

diff --git a/ext/kcar/kcar.rl b/ext/kcar/kcar.rl
index 4c66fb5..e015bdb 100644
--- a/ext/kcar/kcar.rl
+++ b/ext/kcar/kcar.rl
@@ -10,6 +10,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
+#include <limits.h>
 #include "c_util.h"
 
 static VALUE eParserError;
@@ -47,15 +48,15 @@ DEF_MAX_LENGTH(HEADER, (1024 * (80 + 32)));
 struct http_parser {
   int cs; /* Ragel internal state */
   unsigned int flags;
-  size_t mark;
-  size_t offset;
+  unsigned int mark;
+  unsigned int offset;
   union { /* these 2 fields don't nest */
-    size_t field;
-    size_t query;
+    unsigned int field;
+    unsigned int query;
   } start;
   union {
-    size_t field_len; /* only used during header processing */
-    size_t dest_offset; /* only used during body processing */
+    unsigned int field_len; /* only used during header processing */
+    unsigned int dest_offset; /* only used during body processing */
   } s;
   VALUE cont; /* Qfalse: unset, Qnil: ignored header, T_STRING: append */
   VALUE status; /* String or Qnil */
@@ -65,9 +66,21 @@ struct http_parser {
   } len;
 };
 
+static unsigned int ulong2uint(unsigned long n)
+{
+  unsigned int i = (unsigned int)n;
+
+  if (sizeof(unsigned int) != sizeof(unsigned long)) {
+    if ((unsigned long)i != n) {
+      rb_raise(rb_eRangeError, "too large to be 32-bit uint: %lu", n);
+    }
+  }
+  return i;
+}
+
 #define REMAINING (unsigned long)(pe - p)
-#define LEN(AT, FPC) (FPC - buffer - hp->AT)
-#define MARK(M,FPC) (hp->M = (FPC) - buffer)
+#define LEN(AT, FPC) (ulong2uint(FPC - buffer) - hp->AT)
+#define MARK(M,FPC) (hp->M = ulong2uint((FPC) - buffer))
 #define PTR_TO(F) (buffer + hp->F)
 #define STR_NEW(M,FPC) rb_str_new(PTR_TO(M), LEN(M, FPC))
 #define STRIPPED_STR_NEW(M,FPC) stripped_str_new(PTR_TO(M), LEN(M, FPC))
@@ -403,7 +416,7 @@ static void http_parser_execute(struct http_parser *hp,
 post_exec: /* "_out:" also goes here */
   if (hp->cs != http_parser_error)
     hp->cs = cs;
-  hp->offset = p - buffer;
+  hp->offset = ulong2uint(p - buffer);
 
   assert(p <= pe && "buffer overflow after parsing execute");
   assert(hp->offset <= len && "offset longer than length");
@@ -537,6 +550,12 @@ static VALUE chunked(VALUE self)
   return HP_FL_TEST(hp, CHUNKED) ? Qtrue : Qfalse;
 }
 
+static void check_buffer_size(long dlen)
+{
+  if (dlen > UINT_MAX)
+    rb_raise(rb_eRangeError, "headers too large to process (%ld bytes)", dlen);
+}
+
 /**
  * Document-method: headers
  * call-seq:
@@ -552,8 +571,10 @@ static VALUE chunked(VALUE self)
 static VALUE headers(VALUE self, VALUE hdr, VALUE data)
 {
   struct http_parser *hp = data_get(self);
+  long dlen = RSTRING_LEN(data);
 
-  http_parser_execute(hp, hdr, RSTRING_PTR(data), RSTRING_LEN(data));
+  check_buffer_size(dlen);
+  http_parser_execute(hp, hdr, RSTRING_PTR(data), dlen);
   VALIDATE_MAX_LENGTH(hp->offset, HEADER);
 
   if (hp->cs == http_parser_first_final ||
@@ -653,6 +674,7 @@ static VALUE filter_body(VALUE self, VALUE buf, VALUE data)
 
   dptr = RSTRING_PTR(data);
   dlen = RSTRING_LEN(data);
+  check_buffer_size(dlen);
 
   StringValue(buf);
   rb_str_modify(buf);
-- 
EW


^ permalink raw reply related	[relevance 7%]

Results 1-2 of 2 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2017-03-05  1:10  7% [PATCH] reduce parser size to 88 bytes on 64-bit Eric Wong
2020-02-21  2:32  5% [ANN] kcar 0.7.0 - bytestream to Rack response converter Eric Wong

Code repositories for project(s) associated with this public inbox

	https://yhbt.net/kcar.git/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).