1 // Copyright 2015 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 "extensions/browser/api/mime_handler_private/mime_handler_private.h"
7 #include "base/strings/string_util.h"
8 #include "content/public/browser/stream_handle.h"
9 #include "content/public/browser/stream_info.h"
10 #include "content/public/common/content_constants.h"
11 #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
12 #include "extensions/common/constants.h"
13 #include "net/http/http_response_headers.h"
14 #include "third_party/mojo/src/mojo/public/cpp/bindings/map.h"
16 namespace extensions
{
19 mojo::Map
<mojo::String
, mojo::String
> CreateResponseHeadersMap(
20 const net::HttpResponseHeaders
* headers
) {
21 std::map
<std::string
, std::string
> result
;
23 return mojo::Map
<mojo::String
, mojo::String
>::From(result
);
26 std::string header_name
;
27 std::string header_value
;
28 while (headers
->EnumerateHeaderLines(&iter
, &header_name
, &header_value
)) {
29 // mojo strings must be UTF-8 and headers might not be, so drop any headers
30 // that aren't ASCII. The PDF plugin does not use any headers with non-ASCII
31 // names and non-ASCII values are never useful for the headers the plugin
34 // TODO(sammc): Send as bytes instead of a string and let the client decide
36 if (!base::IsStringASCII(header_name
) || !base::IsStringASCII(header_value
))
38 auto& current_value
= result
[header_name
];
39 if (!current_value
.empty())
40 current_value
+= ", ";
41 current_value
+= header_value
;
43 return mojo::Map
<mojo::String
, mojo::String
>::From(result
);
49 void MimeHandlerServiceImpl::Create(
50 base::WeakPtr
<StreamContainer
> stream_container
,
51 mojo::InterfaceRequest
<mime_handler::MimeHandlerService
> request
) {
52 new MimeHandlerServiceImpl(stream_container
, request
.Pass());
55 MimeHandlerServiceImpl::MimeHandlerServiceImpl(
56 base::WeakPtr
<StreamContainer
> stream_container
,
57 mojo::InterfaceRequest
<mime_handler::MimeHandlerService
> request
)
58 : stream_(stream_container
),
59 binding_(this, request
.Pass()),
63 MimeHandlerServiceImpl::~MimeHandlerServiceImpl() {
66 void MimeHandlerServiceImpl::GetStreamInfo(
67 const mojo::Callback
<void(mime_handler::StreamInfoPtr
)>& callback
) {
69 callback
.Run(mime_handler::StreamInfoPtr());
72 callback
.Run(mojo::ConvertTo
<mime_handler::StreamInfoPtr
>(*stream_
));
75 void MimeHandlerServiceImpl::AbortStream(
76 const mojo::Callback
<void()>& callback
) {
81 stream_
->Abort(base::Bind(&MimeHandlerServiceImpl::OnStreamClosed
,
82 weak_factory_
.GetWeakPtr(), callback
));
85 void MimeHandlerServiceImpl::OnStreamClosed(
86 const mojo::Callback
<void()>& callback
) {
90 } // namespace extensions
94 extensions::mime_handler::StreamInfoPtr TypeConverter
<
95 extensions::mime_handler::StreamInfoPtr
,
96 extensions::StreamContainer
>::Convert(const extensions::StreamContainer
&
98 if (!stream
.stream_info()->handle
)
99 return extensions::mime_handler::StreamInfoPtr();
101 auto result
= extensions::mime_handler::StreamInfo::New();
102 result
->embedded
= stream
.embedded();
103 result
->tab_id
= stream
.tab_id();
104 const content::StreamInfo
* info
= stream
.stream_info();
105 result
->mime_type
= info
->mime_type
;
107 // If the URL is too long, mojo will give up on sending the URL. In these
108 // cases truncate it. Only data: URLs should ever really suffer this problem
109 // so only worry about those for now.
110 // TODO(raymes): This appears to be a bug in mojo somewhere. crbug.com/480099.
111 if (info
->original_url
.SchemeIs(url::kDataScheme
) &&
112 info
->original_url
.spec().size() > content::kMaxURLDisplayChars
) {
113 result
->original_url
= info
->original_url
.scheme() + ":";
115 result
->original_url
= info
->original_url
.spec();
118 result
->stream_url
= info
->handle
->GetURL().spec();
119 result
->response_headers
=
120 extensions::CreateResponseHeadersMap(info
->response_headers
.get());
121 return result
.Pass();