Reviewed by Maciej (a while back).
[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     BOOL hideReferrer;
42     if (![bridge canLoadURL:[theRequest URL] fromReferrer:[bridge referrer] hideReferrer:&hideReferrer])
43         return nil;
44
45     if ([self initWithRequestURL:[theRequest URL]
46                     pluginPointer:thePluginPointer
47                        notifyData:theNotifyData
48                  sendNotification:flag] == nil) {
49         return nil;
50     }
51     
52     // Temporarily set isTerminated to YES to avoid assertion failure in dealloc in case we are released in this method.
53     isTerminated = YES;
54     
55     if (![WebView _canHandleRequest:theRequest]) {
56         [self release];
57         return nil;
58     }
59         
60     request = [theRequest mutableCopy];
61     if (hideReferrer) {
62         [(NSMutableURLRequest *)request setHTTPReferrer:nil];
63     }
64
65     _loader = [[WebNetscapePluginConnectionDelegate alloc] initWithStream:self view:view]; 
66     [_loader setDataSource:[view dataSource]];
67     
68     isTerminated = NO;
69
70     return self;
71 }
72
73 - (void)dealloc
74 {
75     [_loader release];
76     [request release];
77     [super dealloc];
78 }
79
80 - (void)start
81 {
82     ASSERT(request);
83
84     [[_loader dataSource] _addPlugInStreamClient:_loader];
85
86     BOOL succeeded = [_loader loadWithRequest:request];
87     if (!succeeded) {
88         [[_loader dataSource] _removePlugInStreamClient:_loader];
89     }
90 }
91
92 - (void)cancelLoadWithError:(NSError *)error
93 {
94     if (![_loader isDone]) {
95         [_loader cancelWithError:error];
96     }
97 }
98
99 - (void)stop
100 {
101     [self cancelLoadAndDestroyStreamWithError:[_loader cancelledError]];
102 }
103
104 @end
105
106 @implementation WebNetscapePluginConnectionDelegate
107
108 - initWithStream:(WebNetscapePluginStream *)theStream view:(WebBaseNetscapePluginView *)theView
109 {
110     [super init];
111     stream = [theStream retain];
112     view = [theView retain];
113     return self;
114 }
115
116 - (BOOL)isDone
117 {
118     return stream == nil;
119 }
120
121 - (void)releaseResources
122 {
123     [stream release];
124     stream = nil;
125     [view release];
126     view = nil;
127     [super releaseResources];
128 }
129
130 - (void)didReceiveResponse:(NSURLResponse *)theResponse
131 {
132     // retain/release self in this delegate method since the additional processing can do
133     // anything including possibly releasing self; one example of this is 3266216
134     [self retain];
135     [stream startStreamWithResponse:theResponse];
136     
137     // Don't continue if the stream is cancelled in startStreamWithResponse or didReceiveResponse.
138     if (stream) {
139         [super didReceiveResponse:theResponse];
140         if (stream) {
141             if ([theResponse isKindOfClass:[NSHTTPURLResponse class]] &&
142                 [NSHTTPURLResponse isErrorStatusCode:[(NSHTTPURLResponse *)theResponse statusCode]]) {
143                 NSError *error = [NSError _webKitErrorWithDomain:NSURLErrorDomain
144                                                             code:NSURLErrorFileDoesNotExist
145                                                             URL:[theResponse URL]];
146                 [stream cancelLoadAndDestroyStreamWithError:error];
147             }
148         }
149     }
150     [self release];
151 }
152
153 - (void)didReceiveData:(NSData *)data lengthReceived:(long long)lengthReceived
154 {
155     // retain/release self in this delegate method since the additional processing can do
156     // anything including possibly releasing self; one example of this is 3266216
157     [self retain];
158     [stream receivedData:data];
159     [super didReceiveData:data lengthReceived:lengthReceived];
160     [self release];
161 }
162
163 - (void)didFinishLoading
164 {
165     // Calling _removePlugInStreamClient will likely result in a call to release, so we must retain.
166     [self retain];
167
168     [[self dataSource] _removePlugInStreamClient:self];
169     [[view webView] _finishedLoadingResourceFromDataSource:[self dataSource]];
170     [stream finishedLoadingWithData:[self resourceData]];
171     [super didFinishLoading];
172
173     [self release];
174 }
175
176 - (void)didFailWithError:(NSError *)error
177 {
178     // Calling _removePlugInStreamClient will likely result in a call to release, so we must retain.
179     // The other additional processing can do anything including possibly releasing self;
180     // one example of this is 3266216
181     [self retain];
182
183     [[self dataSource] _removePlugInStreamClient:self];
184     [[view webView] _receivedError:error fromDataSource:[self dataSource]];
185     [stream destroyStreamWithError:error];
186     [super didFailWithError:error];
187
188     [self release];
189 }
190
191 - (void)cancelWithError:(NSError *)error
192 {
193     // Calling _removePlugInStreamClient will likely result in a call to release, so we must retain.
194     [self retain];
195
196     [[self dataSource] _removePlugInStreamClient:self];
197     [super cancelWithError:error];
198
199     [self release];
200 }
201
202 @end