Changeset 408424e in mainline for uspace/lib/http/src/response.c
- Timestamp:
- 2013-09-26T23:31:50Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c42f50d
- Parents:
- 4d4f656
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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.