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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 4d4f656 was 4d4f656, checked in by Martin Sucha <sucha14@…>, 12 years ago

libhttp: Add higher-level API for working with headers

  • Property mode set to 100644
File size: 3.7 KB
Line 
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
36#include <stdio.h>
37#include <stdlib.h>
38#include <str.h>
39#include <macros.h>
40
41#include <http/http.h>
42#include <http/errno.h>
43
44int http_parse_status(const char *line, http_version_t *out_version,
45 uint16_t *out_status, char **out_message)
46{
47 http_version_t version;
48 uint16_t status;
49 char *message = NULL;
50
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++;
79
80 if (out_message) {
81 message = str_dup(pos);
82 if (message == NULL)
83 return ENOMEM;
84 }
85
86 if (out_version)
87 *out_version = version;
88 if (out_status)
89 *out_status = status;
90 if (out_message)
91 *out_message = message;
92 return EOK;
93}
94
95int http_receive_response(http_t *http, http_response_t **out_response)
96{
97 http_response_t *resp = malloc(sizeof(http_response_t));
98 if (resp == NULL)
99 return ENOMEM;
100 memset(resp, 0, sizeof(http_response_t));
101 http_headers_init(&resp->headers);
102
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)
111 goto error;
112
113 rc = http_parse_status(line, &resp->version, &resp->status,
114 &resp->message);
115 if (rc != EOK)
116 goto error;
117
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);
123 if (rc == 0)
124 rc = HTTP_EPARSE;
125 if (rc < 0)
126 goto error;
127
128 *out_response = resp;
129
130 return EOK;
131error:
132 free(line);
133 http_response_destroy(resp);
134 return rc;
135}
136
137int http_receive_body(http_t *http, void *buf, size_t buf_size)
138{
139 return recv_buffer(&http->recv_buffer, buf, buf_size);
140}
141
142void http_response_destroy(http_response_t *resp)
143{
144 free(resp->message);
145 http_headers_clear(&resp->headers);
146 free(resp);
147}
148
149/** @}
150 */
Note: See TracBrowser for help on using the repository browser.