Fri, 30 May 2025 14:48:42 +0200
add show-emojis, dir-icon, file-icon, show-hidden parameters to common-index SAF
| 1 | 1 | /* |
| 2 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. | |
| 3 | * | |
|
44
3da1f7b6847f
added some error messages
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
25
diff
changeset
|
4 | * Copyright 2013 Olaf Wintermann. All rights reserved. |
| 1 | 5 | * |
| 6 | * Redistribution and use in source and binary forms, with or without | |
| 7 | * modification, are permitted provided that the following conditions are met: | |
| 8 | * | |
| 9 | * 1. Redistributions of source code must retain the above copyright | |
| 10 | * notice, this list of conditions and the following disclaimer. | |
| 11 | * | |
| 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
| 13 | * notice, this list of conditions and the following disclaimer in the | |
| 14 | * documentation and/or other materials provided with the distribution. | |
| 15 | * | |
| 16 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
| 17 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
| 18 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
| 19 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | |
| 20 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
| 21 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
| 22 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
| 23 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
| 24 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
| 25 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
| 26 | * POSSIBILITY OF SUCH DAMAGE. | |
| 27 | */ | |
| 28 | ||
| 29 | #include <stdio.h> | |
| 30 | #include <stdlib.h> | |
| 31 | ||
| 32 | #include "httpparser.h" | |
|
14
b8bf95b39952
New source folder layout
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
1
diff
changeset
|
33 | #include "../public/nsapi.h" |
| 1 | 34 | //include "request.h" |
| 35 | ||
| 36 | ||
| 37 | HttpParser* http_parser_new(HTTPRequest *request) { | |
|
183
f33974f0dce0
fixes http parser init
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
182
diff
changeset
|
38 | HttpParser *parser = calloc(1, sizeof(HttpParser)); |
| 1 | 39 | parser->request = request; |
| 40 | ||
| 41 | parser->state = 0; | |
| 42 | parser->start_line.ptr = (char*)request->netbuf->inbuf; | |
| 43 | parser->start_line.length = 0; | |
|
101
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
44 | |
|
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
45 | parser->offset = 0; |
| 1 | 46 | |
| 47 | return parser; | |
| 48 | } | |
| 49 | ||
| 50 | void http_parser_free(HttpParser *parser) { | |
| 51 | free(parser); | |
| 52 | } | |
| 53 | ||
| 54 | int http_parser_process(HttpParser *parser) { | |
| 55 | switch(parser->state) { | |
| 56 | case 0: { | |
| 57 | int r = get_start_line(parser); | |
| 58 | switch(r) { | |
| 59 | case 0: break; | |
| 60 | default: return r; | |
| 61 | } | |
| 62 | parse_request_line(parser); | |
| 63 | parser->state++; | |
| 64 | } | |
| 65 | case 1: { | |
| 66 | return http_parser_parse_header(parser); | |
| 67 | } | |
| 68 | case 2: { | |
| 69 | return 0; | |
| 70 | } | |
| 71 | } | |
|
25
5dee29c7c530
Fixed config parser bug
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
20
diff
changeset
|
72 | return -1; |
| 1 | 73 | } |
| 74 | ||
|
180
98462e878ca7
fixes crash with broken http requests
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
163
diff
changeset
|
75 | int http_parser_validate(HttpParser *parser) { |
|
98462e878ca7
fixes crash with broken http requests
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
163
diff
changeset
|
76 | HTTPRequest *req = parser->request; |
|
98462e878ca7
fixes crash with broken http requests
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
163
diff
changeset
|
77 | if( |
|
98462e878ca7
fixes crash with broken http requests
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
163
diff
changeset
|
78 | !req->method.ptr || req->method.length == 0 |
|
182
b982cc285c40
fixes http_parser_validate
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
180
diff
changeset
|
79 | || !req->uri.ptr || req->uri.length == 0 |
|
180
98462e878ca7
fixes crash with broken http requests
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
163
diff
changeset
|
80 | || !req->httpv.ptr || req->httpv.length == 0) |
|
98462e878ca7
fixes crash with broken http requests
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
163
diff
changeset
|
81 | { |
|
98462e878ca7
fixes crash with broken http requests
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
163
diff
changeset
|
82 | return 0; |
|
98462e878ca7
fixes crash with broken http requests
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
163
diff
changeset
|
83 | } |
|
98462e878ca7
fixes crash with broken http requests
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
163
diff
changeset
|
84 | return 1; |
|
98462e878ca7
fixes crash with broken http requests
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
163
diff
changeset
|
85 | } |
|
98462e878ca7
fixes crash with broken http requests
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
163
diff
changeset
|
86 | |
| 1 | 87 | int get_start_line(HttpParser *parser) { |
| 88 | netbuf *buf = parser->request->netbuf; | |
| 89 | while(buf->pos < buf->cursize) { | |
| 90 | unsigned char c = buf->inbuf[buf->pos]; | |
| 91 | if(c == '\n') { | |
|
101
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
92 | size_t lnlen = buf->pos - parser->offset + 1; |
|
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
93 | if(lnlen <= 2) { |
|
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
94 | if(lnlen == 1 || buf->inbuf[buf->pos-1] == '\r') { |
|
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
95 | // skip empty line |
|
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
96 | buf->pos++; |
|
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
97 | parser->offset = buf->pos; |
|
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
98 | return 1; |
|
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
99 | } |
| 1 | 100 | // insufficient chars for request, return error |
| 101 | return 2; | |
| 102 | } | |
| 103 | if(buf->inbuf[buf->pos - 1] == '\r') { | |
|
101
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
104 | parser->start_line.length = lnlen - 1; |
| 1 | 105 | } else { |
|
101
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
106 | parser->start_line.length = lnlen; |
| 1 | 107 | } |
|
101
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
108 | parser->start_line.ptr = (char*)buf->inbuf + parser->offset; |
| 1 | 109 | buf->pos++; |
| 110 | return 0; | |
| 111 | } | |
| 112 | buf->pos++; | |
| 113 | } | |
| 114 | return 1; | |
| 115 | } | |
| 116 | ||
| 117 | int http_parser_parse_header(HttpParser *parser) { | |
| 118 | netbuf *buf = parser->request->netbuf; | |
| 119 | ||
| 120 | parser->offset = buf->pos; // line offset | |
| 121 | parser->name.ptr = NULL; | |
|
101
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
122 | parser->name.length = 0; |
| 1 | 123 | parser->value.ptr = NULL; |
|
101
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
124 | parser->value.length = 0; |
| 1 | 125 | while(1) { |
| 126 | if(buf->pos >= buf->cursize) { | |
| 127 | return 1; | |
| 128 | } | |
| 129 | char c = (char)buf->inbuf[buf->pos++]; | |
| 130 | ||
| 131 | if(c > 32) { | |
| 132 | parser->wl = 0; | |
| 133 | if(c == ':' && parser->value.ptr == NULL) { | |
| 134 | parser->name.ptr = (char*)buf->inbuf + parser->offset; | |
|
101
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
135 | parser->name.length = buf->pos - parser->offset - 1; |
| 1 | 136 | } else if(parser->name.ptr != NULL && parser->value.ptr == NULL) { |
| 137 | parser->value.ptr = (char*)buf->inbuf + buf->pos - 1; | |
| 138 | } | |
| 139 | } else if(c == '\n') { | |
| 140 | if(parser->wl) { | |
| 141 | // line contains only white space -> end of request | |
| 142 | parser->state++; | |
| 143 | return 0; | |
| 144 | } else { | |
| 145 | parser->offset = buf->pos; | |
|
162
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
101
diff
changeset
|
146 | if(parser->name.length != 0) { |
|
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
101
diff
changeset
|
147 | if(parser->value.ptr) { |
|
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
101
diff
changeset
|
148 | parser->value.length = (buf->inbuf + buf->pos - 1) |
|
101
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
149 | - (unsigned char*)parser->value.ptr; |
|
162
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
101
diff
changeset
|
150 | if(buf->inbuf[buf->pos-2] == '\r') { |
|
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
101
diff
changeset
|
151 | parser->value.length--; |
|
b169992137a8
improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
101
diff
changeset
|
152 | } |
|
163
3589ed579127
fixes empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
162
diff
changeset
|
153 | } else { |
|
3589ed579127
fixes empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
162
diff
changeset
|
154 | parser->value.ptr = ""; |
|
20
7b235fa88008
Some fixes for mod_jk
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
14
diff
changeset
|
155 | } |
| 1 | 156 | // add header |
| 157 | header_add( | |
| 158 | parser->request->headers, | |
|
101
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
159 | parser->name, |
|
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
160 | parser->value); |
| 1 | 161 | } else { |
| 162 | // error: no value | |
| 163 | return 2; | |
| 164 | } | |
| 165 | parser->name.ptr = NULL; | |
| 166 | parser->value.ptr = NULL; | |
|
101
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
167 | parser->name.length = 0; |
|
7fbcdbad0baa
added support for absolute URIs and improved keep alive
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
44
diff
changeset
|
168 | parser->value.length = 0; |
| 1 | 169 | parser->wl = 1; |
| 170 | } | |
| 171 | } | |
| 172 | } | |
| 173 | } | |
| 174 | ||
| 175 | int parse_request_line(HttpParser *parser) { | |
|
415
d938228c382e
switch from ucx 2 to 3
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
351
diff
changeset
|
176 | cxmutstr line = parser->start_line; |
| 1 | 177 | parser->request->request_line = line; |
| 178 | ||
| 179 | /* | |
| 180 | * parse method, url and http version | |
| 181 | */ | |
| 182 | ||
| 183 | int i = 0; | |
| 184 | int ns = 0; | |
| 185 | ||
| 186 | parser->request->method.ptr = line.ptr; | |
| 187 | for(;i<line.length;i++) { | |
| 188 | if(!ns && line.ptr[i] == ' ') { | |
| 189 | ns = 1; | |
| 190 | parser->request->method.length = i; | |
| 191 | } else if(ns) { | |
| 192 | if(line.ptr[i] != ' ') { | |
| 193 | break; | |
| 194 | } | |
| 195 | } | |
| 196 | } | |
| 197 | ||
| 198 | parser->request->uri.ptr = line.ptr + i; | |
| 199 | ns = 0; | |
| 200 | int s = i; | |
| 201 | for(;i<line.length;i++) { | |
|
351
5533db9b64e2
fix parse_request_line not detecting the uri correctly in some cases
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
183
diff
changeset
|
202 | if(!ns && isspace(line.ptr[i])) { |
| 1 | 203 | ns = 1; |
| 204 | parser->request->uri.length = i - s; | |
| 205 | } else if(ns) { | |
| 206 | if(line.ptr[i] > 32) { | |
| 207 | break; | |
| 208 | } | |
| 209 | } | |
| 210 | } | |
| 211 | ||
| 212 | parser->request->httpv.ptr = line.ptr + i; | |
| 213 | ns = 0; | |
| 214 | s = i; | |
| 215 | for(;i<line.length;i++) { | |
|
351
5533db9b64e2
fix parse_request_line not detecting the uri correctly in some cases
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
183
diff
changeset
|
216 | if(!ns && isspace(line.ptr[i])) { |
| 1 | 217 | ns = 1; |
| 218 | parser->request->httpv.length = i - s; | |
| 219 | } else if(ns) { | |
| 220 | if(line.ptr[i] > 32) { | |
| 221 | break; | |
| 222 | } | |
| 223 | } | |
| 224 | } | |
| 225 | ||
| 226 | return 0; | |
| 227 | } |