Changeset 408424e in mainline
- Timestamp:
- 2013-09-26T23:31:50Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c42f50d
- Parents:
- 4d4f656
- Location:
- uspace
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/download/main.c
r4d4f656 r408424e 171 171 172 172 http_response_t *response = NULL; 173 rc = http_receive_response( http, &response);173 rc = http_receive_response(&http->recv_buffer, &response); 174 174 if (rc != EOK) { 175 175 fprintf(stderr, "Failed receiving response: %s\n", str_error(rc)); … … 192 192 193 193 int body_size; 194 while ((body_size = http_receive_body(http, buf, buf_size)) > 0) {194 while ((body_size = recv_buffer(&http->recv_buffer, buf, buf_size)) > 0) { 195 195 fwrite(buf, 1, body_size, stdout); 196 196 } -
uspace/lib/http/include/http/http.h
r4d4f656 r408424e 124 124 extern int http_request_format(http_request_t *, char **, size_t *); 125 125 extern int http_send_request(http_t *, http_request_t *); 126 extern int http_ parse_status(const char*, http_version_t *, uint16_t *,126 extern int http_receive_status(receive_buffer_t *, http_version_t *, uint16_t *, 127 127 char **); 128 extern int http_receive_response(http_t *, http_response_t **); 129 extern int http_receive_body(http_t *, void *, size_t); 128 extern int http_receive_response(receive_buffer_t *, http_response_t **); 130 129 extern void http_response_destroy(http_response_t *); 131 130 extern int http_close(http_t *); -
uspace/lib/http/include/http/receive-buffer.h
r4d4f656 r408424e 65 65 } receive_buffer_mark_t; 66 66 67 typedef bool (*char_class_func_t)(char); 68 67 69 extern int recv_buffer_init(receive_buffer_t *, size_t, receive_func_t, void *); 68 70 extern int recv_buffer_init_const(receive_buffer_t *, void *, size_t); … … 79 81 extern ssize_t recv_buffer(receive_buffer_t *, char *, size_t); 80 82 extern ssize_t recv_discard(receive_buffer_t *, char); 83 extern ssize_t recv_discard_str(receive_buffer_t *, const char *); 84 extern ssize_t recv_while(receive_buffer_t *, char_class_func_t); 81 85 extern ssize_t recv_eol(receive_buffer_t *); 82 86 extern ssize_t recv_line(receive_buffer_t *, char *, size_t); 83 84 85 87 86 88 #endif -
uspace/lib/http/src/receive-buffer.c
r4d4f656 r408424e 210 210 } 211 211 212 /** Receive a prefix of constant string discard and return number of bytes read 213 * @return number of characters discarded or negative error code 214 */ 215 ssize_t recv_discard_str(receive_buffer_t *rb, const char *discard) 216 { 217 size_t discarded = 0; 218 while (*discard) { 219 ssize_t rc = recv_discard(rb, *discard); 220 if (rc < 0) 221 return rc; 222 if (rc == 0) 223 break; 224 discarded++; 225 discard++; 226 } 227 return discarded; 228 } 229 230 ssize_t recv_while(receive_buffer_t *rb, char_class_func_t class) 231 { 232 size_t received = 0; 233 234 while (true) { 235 char c = 0; 236 int rc = recv_char(rb, &c, false); 237 if (rc != EOK) 238 return rc; 239 240 if (!class(c)) 241 break; 242 243 rc = recv_char(rb, &c, true); 244 if (rc != EOK) 245 return rc; 246 247 received++; 248 } 249 250 return received; 251 } 252 212 253 /** Receive an end of line, either CR, LF, CRLF or LFCR 213 254 * -
uspace/lib/http/src/response.c
r4d4f656 r408424e 42 42 #include <http/errno.h> 43 43 44 int http_parse_status(const char *line, http_version_t *out_version, 44 static bool is_digit(char c) 45 { 46 return (c >= '0' && c <= '9'); 47 } 48 49 static int receive_number(receive_buffer_t *rb, char **str) 50 { 51 receive_buffer_mark_t start; 52 receive_buffer_mark_t end; 53 54 recv_mark(rb, &start); 55 int rc = recv_while(rb, is_digit); 56 if (rc < 0) { 57 recv_unmark(rb, &start); 58 return rc; 59 } 60 recv_mark(rb, &end); 61 62 rc = recv_cut_str(rb, &start, &end, str); 63 recv_unmark(rb, &start); 64 recv_unmark(rb, &end); 65 return rc; 66 } 67 68 static int receive_uint8_t(receive_buffer_t *rb, uint8_t *out_value) 69 { 70 char *str = NULL; 71 int rc = receive_number(rb, &str); 72 73 if (rc != EOK) 74 return rc; 75 76 rc = str_uint8_t(str, NULL, 10, true, out_value); 77 free(str); 78 79 return rc; 80 } 81 82 static int receive_uint16_t(receive_buffer_t *rb, uint16_t *out_value) 83 { 84 char *str = NULL; 85 int rc = receive_number(rb, &str); 86 87 if (rc != EOK) 88 return rc; 89 90 rc = str_uint16_t(str, NULL, 10, true, out_value); 91 free(str); 92 93 return rc; 94 } 95 96 static int expect(receive_buffer_t *rb, const char *expect) 97 { 98 int rc = recv_discard_str(rb, expect); 99 if (rc < 0) 100 return rc; 101 if ((size_t) rc < str_length(expect)) 102 return HTTP_EPARSE; 103 return EOK; 104 } 105 106 static bool is_not_newline(char c) 107 { 108 return (c != '\n' && c != '\r'); 109 } 110 111 int http_receive_status(receive_buffer_t *rb, http_version_t *out_version, 45 112 uint16_t *out_status, char **out_message) 46 113 { … … 49 116 char *message = NULL; 50 117 51 if (!str_test_prefix(line, "HTTP/")) 52 return EINVAL; 53 54 const char *pos_version = line + 5; 55 const char *pos = pos_version; 56 57 int rc = str_uint8_t(pos_version, &pos, 10, false, &version.major); 58 if (rc != EOK) 59 return rc; 60 if (*pos != '.') 61 return EINVAL; 62 pos++; 63 64 pos_version = pos; 65 rc = str_uint8_t(pos_version, &pos, 10, false, &version.minor); 66 if (rc != EOK) 67 return rc; 68 if (*pos != ' ') 69 return EINVAL; 70 pos++; 71 72 const char *pos_status = pos; 73 rc = str_uint16_t(pos_status, &pos, 10, false, &status); 74 if (rc != EOK) 75 return rc; 76 if (*pos != ' ') 77 return EINVAL; 78 pos++; 118 int rc = expect(rb, "HTTP/"); 119 if (rc != EOK) 120 return rc; 121 122 rc = receive_uint8_t(rb, &version.major); 123 if (rc != EOK) 124 return rc; 125 126 rc = expect(rb, "."); 127 if (rc != EOK) 128 return rc; 129 130 rc = receive_uint8_t(rb, &version.minor); 131 if (rc != EOK) 132 return rc; 133 134 rc = expect(rb, " "); 135 if (rc != EOK) 136 return rc; 137 138 rc = receive_uint16_t(rb, &status); 139 if (rc != EOK) 140 return rc; 141 142 rc = expect(rb, " "); 143 if (rc != EOK) 144 return rc; 145 146 receive_buffer_mark_t msg_start; 147 recv_mark(rb, &msg_start); 148 149 rc = recv_while(rb, is_not_newline); 150 if (rc < 0) { 151 recv_unmark(rb, &msg_start); 152 return rc; 153 } 154 155 receive_buffer_mark_t msg_end; 156 recv_mark(rb, &msg_end); 79 157 80 158 if (out_message) { 81 message = str_dup(pos); 82 if (message == NULL) 83 return ENOMEM; 159 rc = recv_cut_str(rb, &msg_start, &msg_end, &message); 160 if (rc != EOK) { 161 recv_unmark(rb, &msg_start); 162 recv_unmark(rb, &msg_end); 163 return rc; 164 } 165 } 166 167 recv_unmark(rb, &msg_start); 168 recv_unmark(rb, &msg_end); 169 170 rc = recv_eol(rb); 171 if (rc == 0) 172 rc = HTTP_EPARSE; 173 if (rc < 0) { 174 free(message); 175 return rc; 84 176 } 85 177 … … 93 185 } 94 186 95 int http_receive_response( http_t *http, http_response_t **out_response)187 int http_receive_response(receive_buffer_t *rb, http_response_t **out_response) 96 188 { 97 189 http_response_t *resp = malloc(sizeof(http_response_t)); … … 101 193 http_headers_init(&resp->headers); 102 194 103 char *line = malloc(http->buffer_size); 104 if (line == NULL) { 105 free(resp); 106 return ENOMEM; 107 } 108 109 int rc = recv_line(&http->recv_buffer, line, http->buffer_size); 110 if (rc < 0) 195 int rc = http_receive_status(rb, &resp->version, &resp->status, 196 &resp->message); 197 if (rc != EOK) 111 198 goto error; 112 199 113 rc = http_parse_status(line, &resp->version, &resp->status, 114 &resp->message); 200 rc = http_headers_receive(rb, &resp->headers); 115 201 if (rc != EOK) 116 202 goto error; 117 203 118 rc = http_headers_receive(&http->recv_buffer, &resp->headers); 119 if (rc != EOK) 120 goto error; 121 122 rc = recv_eol(&http->recv_buffer); 204 rc = recv_eol(rb); 123 205 if (rc == 0) 124 206 rc = HTTP_EPARSE; … … 130 212 return EOK; 131 213 error: 132 free(line);133 214 http_response_destroy(resp); 134 215 return rc; 135 }136 137 int http_receive_body(http_t *http, void *buf, size_t buf_size)138 {139 return recv_buffer(&http->recv_buffer, buf, buf_size);140 216 } 141 217
Note:
See TracChangeset
for help on using the changeset viewer.