void http_field(void *data, const char *field, size_t flen, const char *value, size_t vlen) { VALUE req = (VALUE)data; VALUE v = Qnil; VALUE f = Qnil; VALIDATE_MAX_LENGTH(flen, FIELD_NAME); VALIDATE_MAX_LENGTH(vlen, FIELD_VALUE); v = rb_str_new(value, vlen); f = find_common_field_value(field, flen); if (f == Qnil) { /* * We got a strange header that we don't have a memoized value for. * Fallback to creating a new string to use as a hash key. * * using rb_str_new(NULL, len) here is faster than rb_str_buf_new(len) * in my testing, because: there's no minimum allocation length (and * no check for it, either), RSTRING_LEN(f) does not need to be * written twice, and and RSTRING_PTR(f) will already be * null-terminated for us. */ f = rb_str_new(NULL, HTTP_PREFIX_LEN + flen); memcpy(RSTRING_PTR(f), HTTP_PREFIX, HTTP_PREFIX_LEN); memcpy(RSTRING_PTR(f) + HTTP_PREFIX_LEN, field, flen); assert(*(RSTRING_PTR(f) + RSTRING_LEN(f)) == '\0'); /* paranoia */ /* fprintf(stderr, "UNKNOWN HEADER <%s>\n", RSTRING_PTR(f)); */ } rb_hash_aset(req, f, v); }
void http_field(http_parser* hp, const char *field, size_t flen, const char *value, size_t vlen) { VALUE v = Qnil; VALUE f = Qnil; VALIDATE_MAX_LENGTH(flen, FIELD_NAME); VALIDATE_MAX_LENGTH(vlen, FIELD_VALUE); v = rb_str_new(value, vlen); f = find_common_field_value(field, flen); if (f == Qnil) { /* * We got a strange header that we don't have a memoized value for. * Fallback to creating a new string to use as a hash key. */ size_t new_size = HTTP_PREFIX_LEN + flen; assert(new_size < BUFFER_LEN); memcpy(hp->buf, HTTP_PREFIX, HTTP_PREFIX_LEN); memcpy(hp->buf + HTTP_PREFIX_LEN, field, flen); f = rb_str_new(hp->buf, new_size); } rb_hash_aset(hp->request, f, v); }