source: mainline/uspace/lib/http/src/response.c@ a53ed3a

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a53ed3a was b7fd2a0, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

Use errno_t in all uspace and kernel code.

Change type of every variable, parameter and return value that holds an
<errno.h> constant to either errno_t (the usual case), or sys_errno_t
(some places in kernel). This is for the purpose of self-documentation,
as well as for type-checking with a bit of type definition hackery.

Although this is a massive commit, it is a simple text replacement, and thus
is very easy to verify. Simply do the following:

`
git checkout <this commit's hash>
git reset HEAD
git add .
tools/srepl '\berrno_t\b' int
git add .
tools/srepl '\bsys_errno_t\b' sysarg_t
git reset
git diff
`

While this doesn't ensure that the replacements are correct, it does ensure
that the commit doesn't do anything except those replacements. Since errno_t
is typedef'd to int in the usual case (and sys_errno_t to sysarg_t), even if
incorrect, this commit cannot change behavior.

  • Property mode set to 100644
File size: 5.1 KB
RevLine 
[f9a2831]1/*
2 * Copyright (c) 2013 Martin Sucha
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup http
30 * @{
31 */
32/**
33 * @file
34 */
35
[10de842]36#include <errno.h>
[f9a2831]37#include <stdio.h>
38#include <stdlib.h>
39#include <str.h>
40#include <macros.h>
41
[b623b68]42#include <http/http.h>
[f9a2831]43
[408424e]44static bool is_digit(char c)
45{
46 return (c >= '0' && c <= '9');
47}
48
[b7fd2a0]49static errno_t receive_number(receive_buffer_t *rb, char **str)
[408424e]50{
51 receive_buffer_mark_t start;
52 receive_buffer_mark_t end;
53
54 recv_mark(rb, &start);
[b7fd2a0]55 errno_t rc = recv_while(rb, is_digit);
[d5c1051]56 if (rc != EOK) {
[408424e]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
[b7fd2a0]68static errno_t receive_uint8_t(receive_buffer_t *rb, uint8_t *out_value)
[408424e]69{
70 char *str = NULL;
[b7fd2a0]71 errno_t rc = receive_number(rb, &str);
[408424e]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
[b7fd2a0]82static errno_t receive_uint16_t(receive_buffer_t *rb, uint16_t *out_value)
[408424e]83{
84 char *str = NULL;
[b7fd2a0]85 errno_t rc = receive_number(rb, &str);
[408424e]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
[b7fd2a0]96static errno_t expect(receive_buffer_t *rb, const char *expect)
[408424e]97{
[9a09212]98 size_t ndisc;
[b7fd2a0]99 errno_t rc = recv_discard_str(rb, expect, &ndisc);
[9a09212]100 if (rc != EOK)
[408424e]101 return rc;
[9a09212]102 if (ndisc < str_length(expect))
[408424e]103 return HTTP_EPARSE;
104 return EOK;
105}
106
107static bool is_not_newline(char c)
108{
109 return (c != '\n' && c != '\r');
110}
111
[b7fd2a0]112errno_t http_receive_status(receive_buffer_t *rb, http_version_t *out_version,
[f9a2831]113 uint16_t *out_status, char **out_message)
114{
115 http_version_t version;
116 uint16_t status;
117 char *message = NULL;
118
[b7fd2a0]119 errno_t rc = expect(rb, "HTTP/");
[408424e]120 if (rc != EOK)
121 return rc;
[f9a2831]122
[408424e]123 rc = receive_uint8_t(rb, &version.major);
124 if (rc != EOK)
125 return rc;
[f9a2831]126
[408424e]127 rc = expect(rb, ".");
[f9a2831]128 if (rc != EOK)
129 return rc;
130
[408424e]131 rc = receive_uint8_t(rb, &version.minor);
[f9a2831]132 if (rc != EOK)
133 return rc;
134
[408424e]135 rc = expect(rb, " ");
[f9a2831]136 if (rc != EOK)
137 return rc;
[408424e]138
139 rc = receive_uint16_t(rb, &status);
140 if (rc != EOK)
141 return rc;
142
143 rc = expect(rb, " ");
144 if (rc != EOK)
145 return rc;
146
147 receive_buffer_mark_t msg_start;
148 recv_mark(rb, &msg_start);
149
150 rc = recv_while(rb, is_not_newline);
[d5c1051]151 if (rc != EOK) {
[408424e]152 recv_unmark(rb, &msg_start);
153 return rc;
154 }
155
156 receive_buffer_mark_t msg_end;
157 recv_mark(rb, &msg_end);
[f9a2831]158
159 if (out_message) {
[408424e]160 rc = recv_cut_str(rb, &msg_start, &msg_end, &message);
161 if (rc != EOK) {
162 recv_unmark(rb, &msg_start);
163 recv_unmark(rb, &msg_end);
164 return rc;
165 }
166 }
167
168 recv_unmark(rb, &msg_start);
169 recv_unmark(rb, &msg_end);
170
[9a09212]171 size_t nrecv;
172 rc = recv_eol(rb, &nrecv);
173 if (rc == EOK && nrecv == 0)
[408424e]174 rc = HTTP_EPARSE;
[9a09212]175 if (rc != EOK) {
[408424e]176 free(message);
177 return rc;
[f9a2831]178 }
179
180 if (out_version)
181 *out_version = version;
182 if (out_status)
183 *out_status = status;
184 if (out_message)
185 *out_message = message;
186 return EOK;
187}
188
[b7fd2a0]189errno_t http_receive_response(receive_buffer_t *rb, http_response_t **out_response,
[cbfc8b7]190 size_t max_headers_size, unsigned max_headers_count)
[f9a2831]191{
192 http_response_t *resp = malloc(sizeof(http_response_t));
193 if (resp == NULL)
194 return ENOMEM;
195 memset(resp, 0, sizeof(http_response_t));
[4d4f656]196 http_headers_init(&resp->headers);
[f9a2831]197
[b7fd2a0]198 errno_t rc = http_receive_status(rb, &resp->version, &resp->status,
[f9a2831]199 &resp->message);
200 if (rc != EOK)
201 goto error;
202
[cbfc8b7]203 rc = http_headers_receive(rb, &resp->headers, max_headers_size,
204 max_headers_count);
[4d4f656]205 if (rc != EOK)
206 goto error;
207
[9a09212]208 size_t nrecv;
209 rc = recv_eol(rb, &nrecv);
210 if (rc == EOK && nrecv == 0)
[4d4f656]211 rc = HTTP_EPARSE;
[9a09212]212 if (rc != EOK)
[4d4f656]213 goto error;
[f9a2831]214
215 *out_response = resp;
216
217 return EOK;
218error:
219 http_response_destroy(resp);
220 return rc;
221}
222
223void http_response_destroy(http_response_t *resp)
224{
225 free(resp->message);
[4d4f656]226 http_headers_clear(&resp->headers);
[f9a2831]227 free(resp);
228}
229
230/** @}
231 */
Note: See TracBrowser for help on using the repository browser.