summaryrefslogtreecommitdiffstats
path: root/webkit/plugins/npapi/plugin_stream.h
blob: ec987be03db6d26fb035d0b14569717ae5f33300 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef WEBKIT_PLUGINS_NPAPI_PLUGIN_STREAM_H_
#define WEBKIT_PLUGINS_NPAPI_PLUGIN_STREAM_H_

#include <string>
#include <vector>

#include "base/files/file_path.h"
#include "base/memory/ref_counted.h"
#include "build/build_config.h"
#include "third_party/npapi/bindings/npapi.h"

namespace webkit {
namespace npapi {

class PluginInstance;
class WebPluginResourceClient;

// Base class for a NPAPI stream.  Tracks basic elements
// of a stream for NPAPI notifications and stream position.
class PluginStream : public base::RefCounted<PluginStream> {
 public:
  // Create a new PluginStream object.  If needNotify is true, then the
  // plugin will be notified when the stream has been fully sent.
  PluginStream(PluginInstance* instance,
               const char* url,
               bool need_notify,
               void* notify_data);

  // In case of a redirect, this can be called to update the url.  But it must
  // be called before Open().
  void UpdateUrl(const char* url);

  // Opens the stream to the Plugin.
  // If the mime-type is not specified, we'll try to find one based on the
  // mime-types table and the extension (if any) in the URL.
  // If the size of the stream is known, use length to set the size.  If
  // not known, set length to 0.
  // The request_is_seekable parameter indicates whether byte range requests
  // can be issued on the stream.
  bool Open(const std::string &mime_type,
            const std::string &headers,
            uint32 length,
            uint32 last_modified,
            bool request_is_seekable);

  // Writes to the stream.
  int Write(const char* buf, const int len, int data_offset);

  // Write the result as a file.
  void WriteAsFile();

  // Notify the plugin that a stream is complete.
  void Notify(NPReason reason);

  // Close the stream.
  virtual bool Close(NPReason reason);

  virtual WebPluginResourceClient* AsResourceClient();

  // Cancels any HTTP requests initiated by the stream.
  virtual void CancelRequest() {}

  const NPStream* stream() const { return &stream_; }

  // setter/getter for the seekable attribute on the stream.
  bool seekable() const { return seekable_stream_; }

  void set_seekable(bool seekable) { seekable_stream_ = seekable; }

  // getters for reading the notification related attributes on the stream.
  bool notify_needed() const { return notify_needed_; }

  void* notify_data() const { return notify_data_; }

  std::string pending_redirect_url() const { return pending_redirect_url_; }

 protected:
  friend class base::RefCounted<PluginStream>;

  virtual ~PluginStream();

  PluginInstance* instance() { return instance_.get(); }

  // Check if the stream is open.
  bool open() { return opened_; }

  // If the plugin participates in HTTP URL redirect handling then this member
  // holds the url being redirected to while we wait for the plugin to make a
  // decision on whether to allow or deny the redirect.
  std::string pending_redirect_url_;

 private:
  // Per platform method to reset the temporary file handle.
  void ResetTempFileHandle();

  // Per platform method to reset the temporary file name.
  void ResetTempFileName();

  // Open a temporary file for this stream.
  // If successful, will set temp_file_name_, temp_file_handle_, and
  // return true.
  bool OpenTempFile();

  // Closes the temporary file if it is open.
  void CloseTempFile();

  // Sends the data to the file. Called From WriteToFile.
  size_t WriteBytes(const char* buf, size_t length);

  // Sends the data to the file if it's open.
  bool WriteToFile(const char* buf, size_t length);

  // Sends the data to the plugin.  If it's not ready, handles buffering it
  // and retrying later.
  bool WriteToPlugin(const char* buf, const int length, const int data_offset);

  // Send the data to the plugin, returning how many bytes it accepted, or -1
  // if an error occurred.
  int TryWriteToPlugin(const char* buf, const int length,
                       const int data_offset);

  // The callback which calls TryWriteToPlugin.
  void OnDelayDelivery();

  // Returns true if the temp file is valid and open for writing.
  bool TempFileIsValid() const;

  // Returns true if |requested_plugin_mode_| is NP_ASFILE or NP_ASFILEONLY.
  bool RequestedPluginModeIsAsFile() const;

 private:
  NPStream                      stream_;
  std::string                   headers_;
  scoped_refptr<PluginInstance> instance_;
  bool                          notify_needed_;
  void*                         notify_data_;
  bool                          close_on_write_data_;
  uint16                        requested_plugin_mode_;
  bool                          opened_;
#if defined(OS_WIN)
  char                          temp_file_name_[MAX_PATH];
  HANDLE                        temp_file_handle_;
#elif defined(OS_POSIX)
  FILE*                         temp_file_;
  base::FilePath                temp_file_path_;
#endif
  std::vector<char>             delivery_data_;
  int                           data_offset_;
  bool                          seekable_stream_;
  std::string                   mime_type_;
  DISALLOW_COPY_AND_ASSIGN(PluginStream);
};

}  // namespace npapi
}  // namespace webkit

#endif  // WEBKIT_PLUGINS_NPAPI_PLUGIN_STREAM_H_