Module: NodeRb::Modules::Http::Parser

Included in:
RackParser
Defined in:
lib/noderb/modules/http/parser.rb,
ext/noderb_http_extension/noderb_http.c

Instance Method Summary collapse

Instance Method Details

#disposeObject



119
120
121
122
123
124
125
126
127
128
129
130
# File 'ext/noderb_http_extension/noderb_http.c', line 119

VALUE nodeRb_http_dispose(VALUE self) {
    http_parser_settings* settings;
    http_parser* parser;

    Data_Get_Struct(rb_iv_get(self, "settings"), http_parser_settings, settings);
    Data_Get_Struct(rb_iv_get(self, "parser"), http_parser, parser);

    free(parser->data);
    free(settings);
    free(parser);
    return self;
};

#on_body(body) ⇒ Object



73
74
75
# File 'lib/noderb/modules/http/parser.rb', line 73

def on_body body
  @body << body if @_active
end

#on_error(name, description) ⇒ Object



81
82
83
84
# File 'lib/noderb/modules/http/parser.rb', line 81

def on_error name, description
  @_active = true
  on_message_error(name, description)
end

#on_header(name, value) ⇒ Object



44
45
46
# File 'lib/noderb/modules/http/parser.rb', line 44

def on_header name, value
  @headers[name] = value if @_active
end

#on_header_field(name) ⇒ Object



28
29
30
31
32
33
34
35
36
# File 'lib/noderb/modules/http/parser.rb', line 28

def on_header_field name
  if @_header_state == :value
    on_header(@_header_name, @_header_value)
    @_header_name = ""
    @_header_value = ""
  end
  @_header_state = :field
  @_header_name << name
end

#on_header_value(value) ⇒ Object



38
39
40
41
42
# File 'lib/noderb/modules/http/parser.rb', line 38

def on_header_value value
  @_header_state = :value
  @_header_value ||= ""
  @_header_value << value
end

#on_headers_completeObject



61
62
63
64
65
66
# File 'lib/noderb/modules/http/parser.rb', line 61

def on_headers_complete
  on_header(@_header_name, @_header_value)
  @_header_name = ""
  @_header_value = ""
  on_message_header
end

#on_keep_alive(keep_alive) ⇒ Object



57
58
59
# File 'lib/noderb/modules/http/parser.rb', line 57

def on_keep_alive keep_alive
  @keep_alive = keep_alive if @_active
end

#on_message_beginObject



7
8
9
10
11
12
13
14
15
16
17
18
# File 'lib/noderb/modules/http/parser.rb', line 7

def on_message_begin
  @_header_name = ""
  @_header_value = ""
  @headers = {}
  @body = ""
  @method = ""
  @url = ""
  @status_code = 0
  @upgrade = false
  @keep_alive = false
  @_active = true
end

#on_message_bodyObject



99
100
101
102
# File 'lib/noderb/modules/http/parser.rb', line 99

def on_message_body
  # User overrides this to get whole message body
  # @body => String
end

#on_message_completeObject



77
78
79
# File 'lib/noderb/modules/http/parser.rb', line 77

def on_message_complete
  on_message_body
end

#on_message_error(name, description) ⇒ Object



104
105
106
# File 'lib/noderb/modules/http/parser.rb', line 104

def on_message_error name, description
  # User overrides this to be notified of errors
end

#on_message_headerObject



86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/noderb/modules/http/parser.rb', line 86

def on_message_header
  # User overrides this to get whole message header
  # ------
  # @headers => Hash
  # @url => String
  # @version_major => Integer
  # @version_minor => Integer
  # @status_code (response) => Integer
  # @method (request) => String
  # @upgrade => Boolean
  # @keep_alive => Boolean
end

#on_method(method) ⇒ Object



20
21
22
# File 'lib/noderb/modules/http/parser.rb', line 20

def on_method method
  @method = method
end

#on_status_code(status_code) ⇒ Object



53
54
55
# File 'lib/noderb/modules/http/parser.rb', line 53

def on_status_code status_code
  @status_code = status_code if @_active
end

#on_upgradeObject



68
69
70
71
# File 'lib/noderb/modules/http/parser.rb', line 68

def on_upgrade
  @_active = false
  @upgrade = true
end

#on_url(url) ⇒ Object



24
25
26
# File 'lib/noderb/modules/http/parser.rb', line 24

def on_url url
  @url = url
end

#on_version(major, minor) ⇒ Object



48
49
50
51
# File 'lib/noderb/modules/http/parser.rb', line 48

def on_version major, minor
  @version_major = major if @_active
  @version_minor = minor if @_active
end

#parse(data) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'ext/noderb_http_extension/noderb_http.c', line 97

VALUE nodeRb_http_parse(VALUE self, VALUE data) {

    http_parser_settings* settings;
    http_parser* parser;

    VALUE rsettings = rb_iv_get(self, "settings");
    VALUE rparser = rb_iv_get(self, "parser");

    Data_Get_Struct(rsettings, http_parser_settings, settings);
    Data_Get_Struct(rparser, http_parser, parser);

    size_t parsed = http_parser_execute(parser, settings, rb_string_value_cstr(&data), RSTRING_LEN(data));

    if (parser->upgrade) {
        rb_funcall(self, rb_intern("on_upgrade"), 0);
    } else if (parsed != (unsigned) RSTRING_LEN(data)) {
        rb_funcall(self, rb_intern("on_error"), 2, rb_str_new2(http_errno_name(parser->http_errno)), rb_str_new2(http_errno_description(parser->http_errno)));
    };

    return self;
};

#setup(type) ⇒ Object

Methods



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'ext/noderb_http_extension/noderb_http.c', line 63

VALUE nodeRb_http_setup(VALUE self, VALUE type) {
    http_parser_settings* settings = malloc(sizeof (http_parser_settings));

    settings->on_message_begin = nodeRb_http_on_message_begin;
    
    settings->on_url = nodeRb_http_on_url;

    settings->on_header_field = nodeRb_http_on_header_field;
    settings->on_header_value = nodeRb_http_on_header_value;

    settings->on_headers_complete = nodeRb_http_on_headers_complete;
        
    settings->on_body = nodeRb_http_on_body;

    settings->on_message_complete = nodeRb_http_on_message_complete;

    http_parser* parser = malloc(sizeof (http_parser));
    
    if(ID2SYM(rb_intern("response")) == type){
        http_parser_init(parser, HTTP_RESPONSE);
    }else{
        http_parser_init(parser, HTTP_REQUEST);
    }   

    nodeRb_http* client = malloc(sizeof (nodeRb_http));
    client->parser = self;
    parser->data = client;

    rb_iv_set(self, "settings", Data_Wrap_Struct(nodeRbHttpPointer, 0, NULL, settings));
    rb_iv_set(self, "parser", Data_Wrap_Struct(nodeRbHttpPointer, 0, NULL, parser));
    
    return self;
};