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