1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "net/http/http_content_disposition.h"
7 #include "base/logging.h"
8 #include "base/string_util.h"
9 #include "net/base/net_util.h"
10 #include "net/http/http_util.h"
14 HttpContentDisposition::HttpContentDisposition(
15 const std::string
& header
, const std::string
& referrer_charset
)
17 Parse(header
, referrer_charset
);
20 HttpContentDisposition::~HttpContentDisposition() {
23 std::string::const_iterator
HttpContentDisposition::ConsumeDispositionType(
24 std::string::const_iterator begin
, std::string::const_iterator end
) {
25 DCHECK(type_
== INLINE
);
26 std::string::const_iterator delimiter
= std::find(begin
, end
, ';');
28 std::string::const_iterator type_begin
= begin
;
29 std::string::const_iterator type_end
= delimiter
;
30 HttpUtil::TrimLWS(&type_begin
, &type_end
);
32 // If the disposition-type isn't a valid token the then the
33 // Content-Disposition header is malformed, and we treat the first bytes as
34 // a parameter rather than a disposition-type.
35 if (!HttpUtil::IsToken(type_begin
, type_end
))
38 DCHECK(std::find(type_begin
, type_end
, '=') == type_end
);
40 if (!LowerCaseEqualsASCII(type_begin
, type_end
, "inline"))
45 // http://tools.ietf.org/html/rfc6266
47 // content-disposition = "Content-Disposition" ":"
48 // disposition-type *( ";" disposition-parm )
50 // disposition-type = "inline" | "attachment" | disp-ext-type
52 // disp-ext-type = token
54 // disposition-parm = filename-parm | disp-ext-parm
56 // filename-parm = "filename" "=" value
57 // | "filename*" "=" ext-value
59 // disp-ext-parm = token "=" value
60 // | ext-token "=" ext-value
61 // ext-token = <the characters in token, followed by "*">
63 void HttpContentDisposition::Parse(const std::string
& header
,
64 const std::string
& referrer_charset
) {
65 DCHECK(type_
== INLINE
);
66 DCHECK(filename_
.empty());
68 std::string::const_iterator pos
= header
.begin();
69 std::string::const_iterator end
= header
.end();
70 pos
= ConsumeDispositionType(pos
, end
);
74 std::string ext_filename
;
76 HttpUtil::NameValuePairsIterator
iter(pos
, end
, ';');
77 while (iter
.GetNext()) {
78 if (filename
.empty() && LowerCaseEqualsASCII(iter
.name_begin(),
81 DecodeFilenameValue(iter
.value(), referrer_charset
, &filename
);
82 } else if (name
.empty() && LowerCaseEqualsASCII(iter
.name_begin(),
85 DecodeFilenameValue(iter
.value(), referrer_charset
, &name
);
86 } else if (ext_filename
.empty() && LowerCaseEqualsASCII(iter
.name_begin(),
89 DecodeExtValue(iter
.raw_value(), &ext_filename
);
93 if (!ext_filename
.empty())
94 filename_
= ext_filename
;
95 else if (!filename
.empty())