90123f0682338a500ac23c9378e7e54a2433f0fe
[WebKit-https.git] / WebKit / Plugins.subproj / WebNetscapePluginStream.m
1 /*
2         WebNetscapePluginStream.h
3         Copyright 2002, Apple, Inc. All rights reserved.
4 */
5
6 #import <WebKit/WebNetscapePluginStream.h>
7
8 #import <WebKit/WebBaseResourceHandleDelegate.h>
9 #import <WebKit/WebBridge.h>
10 #import <WebKit/WebDataSourcePrivate.h>
11 #import <WebKit/WebKitErrorsPrivate.h>
12 #import <WebKit/WebKitLogging.h>
13 #import <WebKit/WebNetscapePluginEmbeddedView.h>
14 #import <WebKit/WebNetscapePluginPackage.h>
15 #import <WebKit/WebViewPrivate.h>
16
17 #import <Foundation/NSError_NSURLExtras.h>
18 #import <Foundation/NSURLConnection.h>
19 #import <Foundation/NSURLResponsePrivate.h>
20 #import <Foundation/NSURLRequestPrivate.h>
21
22 @interface WebNetscapePluginConnectionDelegate : WebBaseResourceHandleDelegate
23 {
24     WebNetscapePluginStream *stream;
25     WebBaseNetscapePluginView *view;
26 }
27 - initWithStream:(WebNetscapePluginStream *)theStream view:(WebBaseNetscapePluginView *)theView;
28 - (BOOL)isDone;
29 @end
30
31 @implementation WebNetscapePluginStream
32
33 - initWithRequest:(NSURLRequest *)theRequest
34     pluginPointer:(NPP)thePluginPointer
35        notifyData:(void *)theNotifyData 
36  sendNotification:(BOOL)flag
37 {   
38     WebBaseNetscapePluginView *view = (WebBaseNetscapePluginView *)thePluginPointer->ndata;
39
40     WebBridge *bridge = [[view webFrame] _bridge];
41
42     // Since this is a subresource, we can load any URL (we ignore the return value).
43     // But we still want to know whether we should hide the referrer or not, so we call the canLoadURL method.
44     BOOL hideReferrer;
45     [bridge canLoadURL:[theRequest URL] fromReferrer:[bridge referrer] hideReferrer:&hideReferrer];
46
47     if ([self initWithRequestURL:[theRequest URL]
48                     pluginPointer:thePluginPointer
49                        notifyData:theNotifyData
50                  sendNotification:flag] == nil) {
51         return nil;
52     }
53     
54     // Temporarily set isTerminated to YES to avoid assertion failure in dealloc in case we are released in this method.
55     isTerminated = YES;
56     
57     if (![WebView _canHandleRequest:theRequest]) {
58         [self release];
59         return nil;
60     }
61         
62     request = [theRequest mutableCopy];
63     if (hideReferrer) {
64         [(NSMutableURLRequest *)request setHTTPReferrer:nil];
65     }
66
67     _loader = [[WebNetscapePluginConnectionDelegate alloc] initWithStream:self view:view]; 
68     [_loader setDataSource:[view dataSource]];
69     
70     isTerminated = NO;
71
72     return self;
73 }
74
75 - (void)dealloc
76 {
77     [_loader release];
78     [request release];
79     [super dealloc];
80 }
81
82 - (void)start
83 {
84     ASSERT(request);
85
86     [[_loader dataSource] _addPlugInStreamClient:_loader];
87
88     BOOL succeeded = [_loader loadWithRequest:request];
89     if (!succeeded) {
90         [[_loader dataSource] _removePlugInStreamClient:_loader];
91     }
92 }
93
94 - (void)cancelLoadWithError:(NSError *)error
95 {
96     if (![_loader isDone]) {
97         [_loader cancelWithError:error];
98     }
99 }
100
101 - (void)stop
102 {
103     [self cancelLoadAndDestroyStreamWithError:[_loader cancelledError]];
104 }
105
106 @end
107
108 @implementation WebNetscapePluginConnectionDelegate
109
110 - initWithStream:(WebNetscapePluginStream *)theStream view:(WebBaseNetscapePluginView *)theView
111 {
112     [super init];
113     stream = [theStream retain];
114     view = [theView retain];
115     return self;
116 }
117
118 - (BOOL)isDone
119 {
120     return stream == nil;
121 }
122
123 - (void)releaseResources
124 {
125     [stream release];
126     stream = nil;
127     [view release];
128     view = nil;
129     [super releaseResources];
130 }
131
132 - (void)didReceiveResponse:(NSURLResponse *)theResponse
133 {
134     // retain/release self in this delegate method since the additional processing can do
135     // anything including possibly releasing self; one example of this is 3266216
136     [self retain];
137     [stream startStreamWithResponse:theResponse];
138     
139     // Don't continue if the stream is cancelled in startStreamWithResponse or didReceiveResponse.
140     if (stream) {
141         [super didReceiveResponse:theResponse];
142         if (stream) {
143             if ([theResponse isKindOfClass:[NSHTTPURLResponse class]] &&
144                 [NSHTTPURLResponse isErrorStatusCode:[(NSHTTPURLResponse *)theResponse statusCode]]) {
145                 NSError *error = [NSError _webKitErrorWithDomain:NSURLErrorDomain
146                                                             code:NSURLErrorFileDoesNotExist
147                                                             URL:[theResponse URL]];
148                 [stream cancelLoadAndDestroyStreamWithError:error];
149             }
150         }
151     }
152     [self release];
153 }
154
155 - (void)didReceiveData:(NSData *)data lengthReceived:(long long)lengthReceived
156 {
157     // retain/release self in this delegate method since the additional processing can do
158     // anything including possibly releasing self; one example of this is 3266216
159     [self retain];
160     [stream receivedData:data];
161     [super didReceiveData:data lengthReceived:lengthReceived];
162     [self release];
163 }
164
165 - (void)didFinishLoading
166 {
167     // Calling _removePlugInStreamClient will likely result in a call to release, so we must retain.
168     [self retain];
169
170     [[self dataSource] _removePlugInStreamClient:self];
171     [[view webView] _finishedLoadingResourceFromDataSource:[self dataSource]];
172     [stream finishedLoadingWithData:[self resourceData]];
173     [super didFinishLoading];
174
175     [self release];
176 }
177
178 - (void)didFailWithError:(NSError *)error
179 {
180     // Calling _removePlugInStreamClient will likely result in a call to release, so we must retain.
181     // The other additional processing can do anything including possibly releasing self;
182     // one example of this is 3266216
183     [self retain];
184
185     [[self dataSource] _removePlugInStreamClient:self];
186     [[view webView] _receivedError:error fromDataSource:[self dataSource]];
187     [stream destroyStreamWithError:error];
188     [super didFailWithError:error];
189
190     [self release];
191 }
192
193 - (void)cancelWithError:(NSError *)error
194 {
195     // Calling _removePlugInStreamClient will likely result in a call to release, so we must retain.
196     [self retain];
197
198     [[self dataSource] _removePlugInStreamClient:self];
199     [super cancelWithError:error];
200
201     [self release];
202 }
203
204 @end