xref: /haiku/src/kits/network/libnetservices/HttpResult.cpp (revision 52c4471a3024d2eb81fe88e2c3982b9f8daa5e56)
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 using namespace BPrivate::Network;
16 
17 
18 BHttpResult::BHttpResult(const BUrl& url)
19 	:
20 	fUrl(url),
21 	fHeaders(),
22 	fStatusCode(0)
23 {
24 }
25 
26 
27 BHttpResult::BHttpResult(const BHttpResult& other)
28 	:
29 	fUrl(other.fUrl),
30 	fHeaders(other.fHeaders),
31 	fStatusCode(other.fStatusCode),
32 	fStatusString(other.fStatusString)
33 {
34 }
35 
36 
37 BHttpResult::~BHttpResult()
38 {
39 }
40 
41 
42 // #pragma mark Result parameters modifications
43 
44 
45 void
46 BHttpResult::SetUrl(const BUrl& url)
47 {
48 	fUrl = url;
49 }
50 
51 
52 // #pragma mark Result parameters access
53 
54 
55 const BUrl&
56 BHttpResult::Url() const
57 {
58 	return fUrl;
59 }
60 
61 
62 BString
63 BHttpResult::ContentType() const
64 {
65 	return Headers()["Content-Type"];
66 }
67 
68 
69 off_t
70 BHttpResult::Length() const
71 {
72 	const char* length = Headers()["Content-Length"];
73 	if (length == NULL)
74 		return 0;
75 
76 	/* NOTE: Not RFC7230 compliant:
77 	 * - If Content-Length is a list, all values must be checked and verified
78 	 *   to be duplicates of each other, but this is currently not supported.
79 	 */
80 	off_t result = 0;
81 	/* strtoull() will ignore a prefixed sign, so we verify that there aren't
82 	 * any before continuing (RFC7230 only permits digits).
83 	 *
84 	 * We can check length[0] directly because header values are trimmed by
85 	 * HttpHeader beforehand. */
86 	if (length[0] != '-' && length[0] != '+') {
87 		errno = 0;
88 		char *endptr = NULL;
89 		result = strtoull(length, &endptr, 10);
90 		/* ERANGE will be signalled if the result is too large (which can
91 		 * happen), in that case, return 0. */
92 		if (errno != 0 || *endptr != '\0')
93 			result = 0;
94 	}
95 	return result;
96 }
97 
98 
99 const BHttpHeaders&
100 BHttpResult::Headers() const
101 {
102 	return fHeaders;
103 }
104 
105 
106 int32
107 BHttpResult::StatusCode() const
108 {
109 	return fStatusCode;
110 }
111 
112 
113 const BString&
114 BHttpResult::StatusText() const
115 {
116 	return fStatusString;
117 }
118 
119 
120 // #pragma mark Result tests
121 
122 
123 bool
124 BHttpResult::HasHeaders() const
125 {
126 	return fHeaders.CountHeaders() > 0;
127 }
128 
129 
130 // #pragma mark Overloaded members
131 
132 
133 BHttpResult&
134 BHttpResult::operator=(const BHttpResult& other)
135 {
136 	if (this == &other)
137 		return *this;
138 
139 	fUrl = other.fUrl;
140 	fHeaders = other.fHeaders;
141 	fStatusCode = other.fStatusCode;
142 	fStatusString = other.fStatusString;
143 
144 	return *this;
145 }
146