1 /*
2  * Copyright 2009-2017 Alibaba Cloud All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 #include <alibabacloud/oss/model/DownloadObjectRequest.h>
19 #include <alibabacloud/oss/Const.h>
20 #include <sstream>
21 #include <fstream>
22 #include "../model/ModelError.h"
23 #include "../utils/FileSystemUtils.h"
24 
25 using namespace AlibabaCloud::OSS;
26 
DownloadObjectRequest(const std::string & bucket,const std::string & key,const std::string & filePath,const std::string & checkpointDir,const uint64_t partSize,const uint32_t threadNum)27 DownloadObjectRequest::DownloadObjectRequest(const std::string &bucket, const std::string &key,
28     const std::string &filePath, const std::string &checkpointDir,
29     const uint64_t partSize, const uint32_t threadNum):
30     OssResumableBaseRequest(bucket, key, checkpointDir, partSize, threadNum),
31     rangeIsSet_(false),
32     filePath_(filePath)
33 {
34     tempFilePath_ = filePath + ".temp";
35 }
36 
DownloadObjectRequest(const std::string & bucket,const std::string & key,const std::string & filePath,const std::string & checkpointDir)37 DownloadObjectRequest::DownloadObjectRequest(const std::string &bucket, const std::string &key,
38     const std::string &filePath, const std::string &checkpointDir) :
39     DownloadObjectRequest(bucket, key, filePath, checkpointDir, DefaultPartSize, DefaultResumableThreadNum)
40 {}
41 
DownloadObjectRequest(const std::string & bucket,const std::string & key,const std::string & filePath)42 DownloadObjectRequest::DownloadObjectRequest(const std::string &bucket, const std::string &key,
43     const std::string &filePath) :
44     DownloadObjectRequest(bucket, key, filePath, "", DefaultPartSize, DefaultResumableThreadNum)
45 {}
46 
47 //wstring
DownloadObjectRequest(const std::string & bucket,const std::string & key,const std::wstring & filePath,const std::wstring & checkpointDir,const uint64_t partSize,const uint32_t threadNum)48 DownloadObjectRequest::DownloadObjectRequest(const std::string &bucket, const std::string &key,
49     const std::wstring &filePath, const std::wstring &checkpointDir,
50     const uint64_t partSize, const uint32_t threadNum) :
51     OssResumableBaseRequest(bucket, key, checkpointDir, partSize, threadNum),
52     rangeIsSet_(false),
53     filePathW_(filePath)
54 {
55     tempFilePathW_ = filePath + L".temp";
56 }
57 
DownloadObjectRequest(const std::string & bucket,const std::string & key,const std::wstring & filePath,const std::wstring & checkpointDir)58 DownloadObjectRequest::DownloadObjectRequest(const std::string &bucket, const std::string &key,
59     const std::wstring &filePath, const std::wstring &checkpointDir) :
60     DownloadObjectRequest(bucket, key, filePath, checkpointDir, DefaultPartSize, DefaultResumableThreadNum)
61 {}
62 
DownloadObjectRequest(const std::string & bucket,const std::string & key,const std::wstring & filePath)63 DownloadObjectRequest::DownloadObjectRequest(const std::string &bucket, const std::string &key,
64     const std::wstring &filePath) :
65     DownloadObjectRequest(bucket, key, filePath, L"", DefaultPartSize, DefaultResumableThreadNum)
66 {}
67 
68 
setRange(int64_t start,int64_t end)69 void DownloadObjectRequest::setRange(int64_t start, int64_t end)
70 {
71     range_[0] = start;
72     range_[1] = end;
73     rangeIsSet_ = true;
74 }
75 
setModifiedSinceConstraint(const std::string & value)76 void DownloadObjectRequest::setModifiedSinceConstraint(const std::string &value)
77 {
78     modifiedSince_ = value;
79 }
80 
setUnmodifiedSinceConstraint(const std::string & value)81 void DownloadObjectRequest::setUnmodifiedSinceConstraint(const std::string &value)
82 {
83     unmodifiedSince_ = value;
84 }
85 
setMatchingETagConstraints(const std::vector<std::string> & values)86 void DownloadObjectRequest::setMatchingETagConstraints(const std::vector<std::string> &values)
87 {
88     matchingETags_ = values;
89 }
90 
setNonmatchingETagConstraints(const std::vector<std::string> & values)91 void DownloadObjectRequest::setNonmatchingETagConstraints(const std::vector<std::string> &values)
92 {
93     nonmatchingETags_ = values;
94 }
95 
addResponseHeaders(RequestResponseHeader header,const std::string & value)96 void DownloadObjectRequest::addResponseHeaders(RequestResponseHeader header, const std::string &value)
97 {
98     static const char *ResponseHeader[] = {
99         "response-content-type", "response-content-language",
100         "response-expires", "response-cache-control",
101         "response-content-disposition", "response-content-encoding" };
102     responseHeaderParameters_[ResponseHeader[header - RequestResponseHeader::ContentType]] = value;
103 }
104 
validate() const105 int DownloadObjectRequest::validate() const
106 {
107     auto ret = OssResumableBaseRequest::validate();
108     if (ret != 0) {
109         return ret;
110     }
111 
112     if (rangeIsSet_ && (range_[0] < 0 || range_[1] < -1 || (range_[1] > -1 && range_[1] < range_[0]))) {
113         return ARG_ERROR_INVALID_RANGE;
114     }
115 
116 #if !defined(_WIN32)
117     if (!filePathW_.empty()) {
118         return ARG_ERROR_PATH_NOT_SUPPORT_WSTRING_TYPE;
119     }
120 #endif
121 
122     if (filePath_.empty() && filePathW_.empty()) {
123         return ARG_ERROR_DOWNLOAD_FILE_PATH_EMPTY;
124     }
125 
126     //path and checkpoint must be same type.
127     if ((!filePath_.empty() && !checkpointDirW_.empty()) ||
128         (!filePathW_.empty() && !checkpointDir_.empty())) {
129         return ARG_ERROR_PATH_NOT_SAME_TYPE;
130     }
131 
132     //check tmpfilePath is available
133     auto stream = GetFstreamByPath(tempFilePath_, tempFilePathW_, std::ios::out | std::ios::app);
134     if (!stream->is_open()) {
135         return ARG_ERROR_OPEN_DOWNLOAD_TEMP_FILE;
136     }
137     stream->close();
138 
139     return 0;
140 }
141