xref: /haiku/src/kits/network/libnetservices/HttpResult.cpp (revision ce64ffdb9003171981534bc5d3e49147561ed096)
1 /*
2  * Copyright 2010-2017 Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Christophe Huriaux, c.huriaux@gmail.com
7  *		Adrien Destugues, pulkomandy@pulkomandy.tk
8  */
9 
10 #include <HttpResult.h>
11 
12 #include <errno.h>
13 #include <Debug.h>
14 
15 
16 using std::ostream;
17 
18 #ifndef LIBNETAPI_DEPRECATED
19 using namespace BPrivate::Network;
20 #endif
21 
22 
23 BHttpResult::BHttpResult(const BUrl& url)
24 	:
25 	fUrl(url),
26 	fHeaders(),
27 	fStatusCode(0)
28 {
29 }
30 
31 
32 BHttpResult::BHttpResult(BMessage* archive)
33 	:
34 	BUrlResult(archive),
35 	fUrl(archive->FindString("http:url")),
36 	fHeaders(),
37 	fStatusCode(archive->FindInt32("http:statusCode"))
38 {
39 	fStatusString = archive->FindString("http:statusString");
40 
41 	BMessage headers;
42 	archive->FindMessage("http:headers", &headers);
43 	fHeaders.PopulateFromArchive(&headers);
44 }
45 
46 
47 BHttpResult::BHttpResult(const BHttpResult& other)
48 	:
49 	fUrl(other.fUrl),
50 	fHeaders(other.fHeaders),
51 	fStatusCode(other.fStatusCode),
52 	fStatusString(other.fStatusString)
53 {
54 }
55 
56 
57 BHttpResult::~BHttpResult()
58 {
59 }
60 
61 
62 // #pragma mark Result parameters modifications
63 
64 
65 void
66 BHttpResult::SetUrl(const BUrl& url)
67 {
68 	fUrl = url;
69 }
70 
71 
72 // #pragma mark Result parameters access
73 
74 
75 const BUrl&
76 BHttpResult::Url() const
77 {
78 	return fUrl;
79 }
80 
81 
82 BString
83 BHttpResult::ContentType() const
84 {
85 	return Headers()["Content-Type"];
86 }
87 
88 
89 size_t
90 BHttpResult::Length() const
91 {
92 	const char* length = Headers()["Content-Length"];
93 	if (length == NULL)
94 		return 0;
95 
96 	/* NOTE: Not RFC7230 compliant:
97 	 * - If Content-Length is a list, all values must be checked and verified
98 	 *   to be duplicates of each other, but this is currently not supported.
99 	 */
100 	size_t result = 0;
101 	/* strtoul() will ignore a prefixed sign, so we verify that there aren't
102 	 * any before continuing (RFC7230 only permits digits).
103 	 *
104 	 * We can check length[0] directly because header values are trimmed by
105 	 * HttpHeader beforehand. */
106 	if (length[0] != '-' && length[0] != '+') {
107 		errno = 0;
108 		char *endptr = NULL;
109 		result = strtoul(length, &endptr, 10);
110 		/* ERANGE will be signalled if the result is too large (which can
111 		 * happen), in that case, return 0. */
112 		if (errno != 0 || *endptr != '\0')
113 			result = 0;
114 	}
115 	return result;
116 }
117 
118 
119 const BHttpHeaders&
120 BHttpResult::Headers() const
121 {
122 	return fHeaders;
123 }
124 
125 
126 int32
127 BHttpResult::StatusCode() const
128 {
129 	return fStatusCode;
130 }
131 
132 
133 const BString&
134 BHttpResult::StatusText() const
135 {
136 	return fStatusString;
137 }
138 
139 
140 // #pragma mark Result tests
141 
142 
143 bool
144 BHttpResult::HasHeaders() const
145 {
146 	return fHeaders.CountHeaders() > 0;
147 }
148 
149 
150 // #pragma mark Overloaded members
151 
152 
153 BHttpResult&
154 BHttpResult::operator=(const BHttpResult& other)
155 {
156 	if (this == &other)
157 		return *this;
158 
159 	fUrl = other.fUrl;
160 	fHeaders = other.fHeaders;
161 	fStatusCode = other.fStatusCode;
162 	fStatusString = other.fStatusString;
163 
164 	return *this;
165 }
166 
167 
168 status_t
169 BHttpResult::Archive(BMessage* target, bool deep) const
170 {
171 	status_t result = BUrlResult::Archive(target, deep);
172 	if (result != B_OK)
173 		return result;
174 
175 	target->AddString("http:url", fUrl);
176 	target->AddInt32("http:statusCode", fStatusCode);
177 	target->AddString("http:statusString", fStatusString);
178 
179 	BMessage headers;
180 	fHeaders.Archive(&headers);
181 	target->AddMessage("http:headers", &headers);
182 
183 	return B_OK;
184 }
185 
186 
187 /*static*/ BArchivable*
188 BHttpResult::Instantiate(BMessage* archive)
189 {
190 	if (!validate_instantiation(archive, "BHttpResult"))
191 		return NULL;
192 
193 	return new BHttpResult(archive);
194 }
195