Changeset a35b458 in mainline for uspace/lib/http
- Timestamp:
- 2018-03-02T20:10:49Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- Location:
- uspace/lib/http
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/http/include/http/receive-buffer.h
r3061bc1 ra35b458 56 56 size_t in; 57 57 size_t out; 58 58 59 59 void *client_data; 60 60 receive_func_t receive; 61 61 62 62 list_t marks; 63 63 } receive_buffer_t; -
uspace/lib/http/src/headers.c
r3061bc1 ra35b458 64 64 return NULL; 65 65 } 66 66 67 67 header->value = str_dup(value); 68 68 if (header->value == NULL) { … … 101 101 if (name_end) 102 102 recv_mark_update(rb, name_end); 103 103 104 104 errno_t rc = recv_char(rb, &c, true); 105 105 if (rc != EOK) 106 106 return rc; 107 107 } while (is_token(c)); 108 108 109 109 if (c != ':') 110 110 return EINVAL; 111 111 112 112 return EOK; 113 113 } … … 118 118 errno_t rc = EOK; 119 119 char c = 0; 120 120 121 121 /* Ignore any inline LWS */ 122 122 while (true) { 123 123 if (value_start) 124 124 recv_mark_update(rb, value_start); 125 125 126 126 rc = recv_char(rb, &c, false); 127 127 if (rc != EOK) 128 128 return rc; 129 129 130 130 if (c != ' ' && c != '\t') 131 131 break; 132 132 133 133 rc = recv_char(rb, &c, true); 134 134 if (rc != EOK) 135 135 return rc; 136 136 } 137 137 138 138 while (true) { 139 139 recv_mark_update(rb, value_end); 140 140 141 141 rc = recv_char(rb, &c, true); 142 142 if (rc != EOK) 143 143 return rc; 144 144 145 145 if (c != '\r' && c != '\n') 146 146 continue; 147 147 148 148 size_t nrecv; 149 149 rc = recv_discard(rb, (c == '\r' ? '\n' : '\r'), &nrecv); 150 150 if (rc != EOK) 151 151 return rc; 152 152 153 153 rc = recv_char(rb, &c, false); 154 154 if (rc != EOK) 155 155 return rc; 156 156 157 157 if (c != ' ' && c != '\t') 158 158 break; 159 159 160 160 /* Ignore the char */ 161 161 rc = recv_char(rb, &c, true); … … 163 163 return rc; 164 164 } 165 165 166 166 return EOK; 167 167 } … … 172 172 receive_buffer_mark_t mark_start; 173 173 receive_buffer_mark_t mark_end; 174 174 175 175 recv_mark(rb, &mark_start); 176 176 recv_mark(rb, &mark_end); 177 177 178 178 errno_t rc = http_header_receive_name(rb, &mark_end); 179 179 if (rc != EOK) 180 180 goto end; 181 181 182 182 size_t name_size = mark_end.offset - mark_start.offset; 183 183 if (size_limit > 0 && name_size > size_limit) { … … 185 185 goto end; 186 186 } 187 187 188 188 char *name = NULL; 189 189 rc = recv_cut_str(rb, &mark_start, &mark_end, &name); 190 190 if (rc != EOK) 191 191 goto end; 192 192 193 193 rc = http_header_receive_value(rb, &mark_start, &mark_end); 194 194 if (rc != EOK) 195 195 goto end_with_name; 196 196 197 197 size_t value_size = mark_end.offset - mark_start.offset; 198 198 if (size_limit > 0 && (name_size + value_size) > size_limit) { … … 200 200 goto end_with_name; 201 201 } 202 202 203 203 char *value = NULL; 204 204 rc = recv_cut_str(rb, &mark_start, &mark_end, &value); 205 205 if (rc != EOK) 206 206 goto end_with_name; 207 207 208 208 if (out_bytes_used) 209 209 *out_bytes_used = name_size + value_size; 210 210 211 211 header->name = name; 212 212 header->value = value; … … 228 228 size_t read_index = 0; 229 229 size_t write_index = 0; 230 230 231 231 while (is_lws(value[read_index])) read_index++; 232 232 233 233 while (value[read_index] != 0) { 234 234 if (is_lws(value[read_index])) { 235 235 while (is_lws(value[read_index])) read_index++; 236 236 237 237 if (value[read_index] != 0) 238 238 value[write_index++] = ' '; 239 239 240 240 continue; 241 241 } 242 242 243 243 value[write_index++] = value[read_index++]; 244 244 } 245 245 246 246 value[write_index] = 0; 247 247 } … … 266 266 if (!http_header_name_match(header->name, name)) 267 267 continue; 268 268 269 269 if (found == NULL) { 270 270 found = header; … … 274 274 } 275 275 } 276 276 277 277 if (found == NULL) 278 278 return HTTP_EMISSING_HEADER; 279 279 280 280 *out_header = found; 281 281 return EOK; … … 288 288 if (header == NULL) 289 289 return ENOMEM; 290 290 291 291 http_headers_append_header(headers, header); 292 292 return EOK; … … 300 300 if (rc != EOK && rc != HTTP_EMISSING_HEADER) 301 301 return rc; 302 302 303 303 if (rc == HTTP_EMISSING_HEADER) 304 304 return http_headers_append(headers, name, value); 305 305 306 306 char *new_value = str_dup(value); 307 307 if (new_value == NULL) 308 308 return ENOMEM; 309 309 310 310 free(header->value); 311 311 header->value = new_value; … … 319 319 if (rc != EOK) 320 320 return rc; 321 321 322 322 *value = header->value; 323 323 return EOK; … … 329 329 errno_t rc = EOK; 330 330 unsigned added = 0; 331 331 332 332 while (true) { 333 333 char c = 0; … … 335 335 if (rc != EOK) 336 336 goto error; 337 337 338 338 if (c == '\n' || c == '\r') 339 339 break; 340 340 341 341 if (limit_count > 0 && added >= limit_count) { 342 342 rc = ELIMIT; 343 343 goto error; 344 344 } 345 345 346 346 http_header_t *header = malloc(sizeof(http_header_t)); 347 347 if (header == NULL) { … … 350 350 } 351 351 http_header_init(header); 352 352 353 353 size_t header_size; 354 354 rc = http_header_receive(rb, header, limit_alloc, &header_size); … … 358 358 } 359 359 limit_alloc -= header_size; 360 360 361 361 http_headers_append_header(headers, header); 362 362 added++; 363 363 } 364 364 365 365 return EOK; 366 366 error: -
uspace/lib/http/src/http.c
r3061bc1 ra35b458 60 60 if (http == NULL) 61 61 return NULL; 62 62 63 63 http->host = str_dup(host); 64 64 if (http->host == NULL) { … … 67 67 } 68 68 http->port = port; 69 69 70 70 http->buffer_size = 4096; 71 71 errno_t rc = recv_buffer_init(&http->recv_buffer, http->buffer_size, … … 75 75 return NULL; 76 76 } 77 77 78 78 return http; 79 79 } … … 83 83 if (http->conn != NULL) 84 84 return EBUSY; 85 85 86 86 errno_t rc = inet_host_plookup_one(http->host, ip_any, &http->addr, NULL, 87 87 NULL); 88 88 if (rc != EOK) 89 89 return rc; 90 90 91 91 inet_ep2_t epp; 92 92 93 93 inet_ep2_init(&epp); 94 94 epp.remote.addr = http->addr; 95 95 epp.remote.port = http->port; 96 96 97 97 rc = tcp_create(&http->tcp); 98 98 if (rc != EOK) 99 99 return rc; 100 100 101 101 rc = tcp_conn_create(http->tcp, &epp, NULL, NULL, &http->conn); 102 102 if (rc != EOK) 103 103 return rc; 104 104 105 105 rc = tcp_conn_wait_connected(http->conn); 106 106 if (rc != EOK) 107 107 return rc; 108 108 109 109 return rc; 110 110 } … … 114 114 if (http->conn == NULL) 115 115 return EINVAL; 116 116 117 117 tcp_conn_destroy(http->conn); 118 118 http->conn = NULL; 119 119 tcp_destroy(http->tcp); 120 120 http->tcp = NULL; 121 121 122 122 return EOK; 123 123 } -
uspace/lib/http/src/receive-buffer.c
r3061bc1 ra35b458 48 48 rb->receive = receive; 49 49 rb->client_data = client_data; 50 50 51 51 rb->in = 0; 52 52 rb->out = 0; 53 53 rb->size = buffer_size; 54 54 55 55 list_initialize(&rb->marks); 56 56 57 57 rb->buffer = malloc(buffer_size); 58 58 if (rb->buffer == NULL) … … 73 73 if (rc != EOK) 74 74 return rc; 75 75 76 76 memcpy(rb->buffer, buf, size); 77 77 rb->in = size; … … 111 111 if (a->offset > b->offset) 112 112 return EINVAL; 113 113 114 114 size_t size = b->offset - a->offset; 115 115 void *buf = malloc(size); 116 116 if (buf == NULL) 117 117 return ENOMEM; 118 118 119 119 memcpy(buf, rb->buffer + a->offset, size); 120 120 *out_buf = buf; … … 127 127 if (a->offset > b->offset) 128 128 return EINVAL; 129 129 130 130 size_t size = b->offset - a->offset; 131 131 char *buf = malloc(size + 1); 132 132 if (buf == NULL) 133 133 return ENOMEM; 134 134 135 135 memcpy(buf, rb->buffer + a->offset, size); 136 136 buf[size] = 0; … … 156 156 min_mark = min(min_mark, mark->offset); 157 157 } 158 158 159 159 if (min_mark == 0) 160 160 return ELIMIT; 161 161 162 162 size_t new_in = rb->in - min_mark; 163 163 memmove(rb->buffer, rb->buffer + min_mark, new_in); … … 168 168 } 169 169 } 170 170 171 171 size_t nrecv; 172 172 errno_t rc = rb->receive(rb->client_data, rb->buffer + rb->in, free, &nrecv); 173 173 if (rc != EOK) 174 174 return rc; 175 175 176 176 rb->in = nrecv; 177 177 } 178 178 179 179 *c = rb->buffer[rb->out]; 180 180 if (consume) … … 194 194 return EOK; 195 195 } 196 196 197 197 return rb->receive(rb->client_data, buf, buf_size, nrecv); 198 198 } … … 248 248 if (rc != EOK) 249 249 return rc; 250 250 251 251 if (!class(c)) 252 252 break; 253 253 254 254 rc = recv_char(rb, &c, true); 255 255 if (rc != EOK) 256 256 return rc; 257 257 } 258 258 259 259 return EOK; 260 260 } … … 272 272 if (rc != EOK) 273 273 return rc; 274 274 275 275 if (c != '\r' && c != '\n') { 276 276 *nrecv = 0; 277 277 return EOK; 278 278 } 279 279 280 280 rc = recv_char(rb, &c, true); 281 281 if (rc != EOK) 282 282 return rc; 283 283 284 284 size_t nr; 285 285 rc = recv_discard(rb, (c == '\r' ? '\n' : '\r'), &nr); 286 286 if (rc != EOK) 287 287 return rc; 288 288 289 289 *nrecv = 1 + nr; 290 290 return EOK; … … 296 296 size_t written = 0; 297 297 size_t nr; 298 298 299 299 while (written < size) { 300 300 char c = 0; … … 321 321 line[written++] = c; 322 322 } 323 323 324 324 return ELIMIT; 325 325 } -
uspace/lib/http/src/request.c
r3061bc1 ra35b458 52 52 if (req == NULL) 53 53 return NULL; 54 54 55 55 req->method = str_dup(method); 56 56 if (req->method == NULL) { … … 58 58 return NULL; 59 59 } 60 60 61 61 req->path = str_dup(path); 62 62 if (req->path == NULL) { … … 65 65 return NULL; 66 66 } 67 67 68 68 http_headers_init(&req->headers); 69 69 70 70 return req; 71 71 } … … 98 98 return EINVAL; 99 99 size_t size = meth_size; 100 100 101 101 http_headers_foreach(req->headers, header) { 102 102 ssize_t header_size = http_header_encode(header, NULL, 0); … … 106 106 } 107 107 size += str_length(HTTP_REQUEST_LINE); 108 108 109 109 char *buf = malloc(size); 110 110 if (buf == NULL) 111 111 return ENOMEM; 112 112 113 113 char *pos = buf; 114 114 size_t pos_size = size; … … 120 120 pos += written; 121 121 pos_size -= written; 122 122 123 123 http_headers_foreach(req->headers, header) { 124 124 written = http_header_encode(header, pos, pos_size); … … 130 130 pos_size -= written; 131 131 } 132 132 133 133 size_t rlsize = str_size(HTTP_REQUEST_LINE); 134 134 memcpy(pos, HTTP_REQUEST_LINE, rlsize); 135 135 pos_size -= rlsize; 136 136 assert(pos_size == 0); 137 137 138 138 *out_buf = buf; 139 139 *out_buf_size = size; … … 145 145 char *buf = NULL; 146 146 size_t buf_size = 0; 147 147 148 148 errno_t rc = http_request_format(req, &buf, &buf_size); 149 149 if (rc != EOK) 150 150 return rc; 151 151 152 152 rc = tcp_conn_send(http->conn, buf, buf_size); 153 153 free(buf); 154 154 155 155 return rc; 156 156 } -
uspace/lib/http/src/response.c
r3061bc1 ra35b458 51 51 receive_buffer_mark_t start; 52 52 receive_buffer_mark_t end; 53 53 54 54 recv_mark(rb, &start); 55 55 errno_t rc = recv_while(rb, is_digit); … … 59 59 } 60 60 recv_mark(rb, &end); 61 61 62 62 rc = recv_cut_str(rb, &start, &end, str); 63 63 recv_unmark(rb, &start); … … 70 70 char *str = NULL; 71 71 errno_t rc = receive_number(rb, &str); 72 73 if (rc != EOK) 74 return rc; 75 72 73 if (rc != EOK) 74 return rc; 75 76 76 rc = str_uint8_t(str, NULL, 10, true, out_value); 77 77 free(str); 78 78 79 79 return rc; 80 80 } … … 84 84 char *str = NULL; 85 85 errno_t rc = receive_number(rb, &str); 86 87 if (rc != EOK) 88 return rc; 89 86 87 if (rc != EOK) 88 return rc; 89 90 90 rc = str_uint16_t(str, NULL, 10, true, out_value); 91 91 free(str); 92 92 93 93 return rc; 94 94 } … … 116 116 uint16_t status; 117 117 char *message = NULL; 118 118 119 119 errno_t rc = expect(rb, "HTTP/"); 120 120 if (rc != EOK) 121 121 return rc; 122 122 123 123 rc = receive_uint8_t(rb, &version.major); 124 124 if (rc != EOK) 125 125 return rc; 126 126 127 127 rc = expect(rb, "."); 128 128 if (rc != EOK) 129 129 return rc; 130 130 131 131 rc = receive_uint8_t(rb, &version.minor); 132 132 if (rc != EOK) 133 133 return rc; 134 134 135 135 rc = expect(rb, " "); 136 136 if (rc != EOK) 137 137 return rc; 138 138 139 139 rc = receive_uint16_t(rb, &status); 140 140 if (rc != EOK) 141 141 return rc; 142 142 143 143 rc = expect(rb, " "); 144 144 if (rc != EOK) 145 145 return rc; 146 146 147 147 receive_buffer_mark_t msg_start; 148 148 recv_mark(rb, &msg_start); 149 149 150 150 rc = recv_while(rb, is_not_newline); 151 151 if (rc != EOK) { … … 153 153 return rc; 154 154 } 155 155 156 156 receive_buffer_mark_t msg_end; 157 157 recv_mark(rb, &msg_end); 158 158 159 159 if (out_message) { 160 160 rc = recv_cut_str(rb, &msg_start, &msg_end, &message); … … 165 165 } 166 166 } 167 167 168 168 recv_unmark(rb, &msg_start); 169 169 recv_unmark(rb, &msg_end); 170 170 171 171 size_t nrecv; 172 172 rc = recv_eol(rb, &nrecv); … … 177 177 return rc; 178 178 } 179 179 180 180 if (out_version) 181 181 *out_version = version; … … 195 195 memset(resp, 0, sizeof(http_response_t)); 196 196 http_headers_init(&resp->headers); 197 197 198 198 errno_t rc = http_receive_status(rb, &resp->version, &resp->status, 199 199 &resp->message); 200 200 if (rc != EOK) 201 201 goto error; 202 202 203 203 rc = http_headers_receive(rb, &resp->headers, max_headers_size, 204 204 max_headers_count); 205 205 if (rc != EOK) 206 206 goto error; 207 207 208 208 size_t nrecv; 209 209 rc = recv_eol(rb, &nrecv); … … 212 212 if (rc != EOK) 213 213 goto error; 214 214 215 215 *out_response = resp; 216 216 217 217 return EOK; 218 218 error:
Note:
See TracChangeset
for help on using the changeset viewer.