| 117 int get_start_line(HttpParser *parser) { |
117 int get_start_line(HttpParser *parser) { |
| 118 netbuf *buf = parser->netbuf; |
118 netbuf *buf = parser->netbuf; |
| 119 while(buf->pos < buf->cursize) { |
119 while(buf->pos < buf->cursize) { |
| 120 unsigned char c = buf->inbuf[buf->pos]; |
120 unsigned char c = buf->inbuf[buf->pos]; |
| 121 if(c == '\n') { |
121 if(c == '\n') { |
| 122 size_t lnlen = buf->pos - parser->offset + 1; |
122 size_t lnlen = buf->pos - parser->line_offset + 1; |
| 123 if(lnlen <= 2) { |
123 if(lnlen <= 2) { |
| 124 if(lnlen == 1 || buf->inbuf[buf->pos-1] == '\r') { |
124 if(lnlen == 1 || buf->inbuf[buf->pos-1] == '\r') { |
| 125 // skip empty line |
125 // skip empty line |
| 126 buf->pos++; |
126 buf->pos++; |
| 127 parser->offset = buf->pos; |
127 parser->line_offset = buf->pos; |
| 128 return 1; |
128 return 1; |
| 129 } |
129 } |
| 130 // insufficient chars for request, return error |
130 // insufficient chars for request, return error |
| 131 return 2; |
131 return 2; |
| 132 } |
132 } |
| 133 if(buf->inbuf[buf->pos - 1] == '\r') { |
133 if(buf->inbuf[buf->pos - 1] == '\r') { |
| 134 parser->start_line.length = lnlen - 1; |
134 parser->start_line.length = lnlen - 1; |
| 135 } else { |
135 } else { |
| 136 parser->start_line.length = lnlen; |
136 parser->start_line.length = lnlen; |
| 137 } |
137 } |
| 138 parser->start_line.ptr = (char*)buf->inbuf + parser->offset; |
138 parser->start_line.ptr = (char*)buf->inbuf + parser->line_offset; |
| 139 buf->pos++; |
139 buf->pos++; |
| 140 return 0; |
140 return 0; |
| 141 } |
141 } |
| 142 buf->pos++; |
142 buf->pos++; |
| 143 } |
143 } |
| 145 } |
145 } |
| 146 |
146 |
| 147 int http_parser_parse_header(HttpParser *parser) { |
147 int http_parser_parse_header(HttpParser *parser) { |
| 148 netbuf *buf = parser->netbuf; |
148 netbuf *buf = parser->netbuf; |
| 149 |
149 |
| 150 parser->offset = buf->pos; // line offset |
|
| 151 parser->name.ptr = NULL; |
|
| 152 parser->name.length = 0; |
|
| 153 parser->value.ptr = NULL; |
|
| 154 parser->value.length = 0; |
|
| 155 while(1) { |
150 while(1) { |
| 156 if(buf->pos >= buf->cursize) { |
151 if(buf->pos >= buf->cursize) { |
| 157 return 1; |
152 return 1; |
| 158 } |
153 } |
| 159 char c = (char)buf->inbuf[buf->pos++]; |
154 char c = (char)buf->inbuf[buf->pos++]; |
| 160 |
155 |
| 161 if(c > 32) { |
156 if(c > 32) { |
| 162 parser->wl = 0; |
157 parser->wl = 0; |
| 163 if(c == ':' && parser->value.ptr == NULL) { |
158 if(c == ':' && parser->value.ptr == NULL) { |
| 164 parser->name.ptr = (char*)buf->inbuf + parser->offset; |
159 parser->name.ptr = (char*)buf->inbuf + parser->line_offset; |
| 165 parser->name.length = buf->pos - parser->offset - 1; |
160 parser->name.length = buf->pos - parser->line_offset - 1; |
| 166 } else if(parser->name.ptr != NULL && parser->value.ptr == NULL) { |
161 } else if(parser->name.ptr != NULL && parser->value.ptr == NULL) { |
| 167 parser->value.ptr = (char*)buf->inbuf + buf->pos - 1; |
162 parser->value.ptr = (char*)buf->inbuf + buf->pos - 1; |
| 168 } |
163 } |
| 169 } else if(c == '\n') { |
164 } else if(c == '\n') { |
| 170 if(parser->wl) { |
165 if(parser->wl) { |
| 171 // line contains only white space -> end of request |
166 // line contains only white space -> end of request |
| 172 parser->state++; |
167 parser->state++; |
| 173 return 0; |
168 return 0; |
| 174 } else { |
169 } else { |
| 175 parser->offset = buf->pos; |
170 parser->line_offset = buf->pos; |
| 176 if(parser->name.length != 0) { |
171 if(parser->name.length != 0) { |
| 177 if(parser->value.ptr) { |
172 if(parser->value.ptr) { |
| 178 parser->value.length = (buf->inbuf + buf->pos - 1) |
173 parser->value.length = (buf->inbuf + buf->pos - 1) |
| 179 - (unsigned char*)parser->value.ptr; |
174 - (unsigned char*)parser->value.ptr; |
| 180 if(buf->inbuf[buf->pos-2] == '\r') { |
175 if(buf->inbuf[buf->pos-2] == '\r') { |