4 #include <nsIServiceManager.h>
5 #include <nsIComponentManager.h>
6 #include <nsComponentManagerUtils.h>
7 #include <nsIIOService.h>
8 #include <nsStringAPI.h>
9 #include <nsIInputStream.h>
10 #include <nsIOutputStream.h>
11 #include <nsIStreamListener.h>
12 #include <nsEmbedString.h>
13 #include <nsIChannel.h>
14 #include <nsIRequest.h>
15 #include <nsIRequestObserver.h>
16 #include <nsIHttpChannel.h>
17 #include <nsIHttpHeaderVisitor.h>
18 #include <nsEmbedString.h>
19 #include <nsIUploadChannel.h>
22 #if WITH_LIBXUL_UNSTABLE
23 #include <nsNetError.h>
24 #include <nsIStorageStream.h>
26 #include <necko/nsNetError.h>
27 #include <xpcom/nsIStorageStream.h>
30 class GECKO_SYM(HeaderVisitor) : public nsIHttpHeaderVisitor {
33 NS_DECL_NSIHTTPHEADERVISITOR
35 GECKO_SYM(HeaderVisitor) (DownloaderResponseHeaderCallback cb, gpointer context)
38 this->context = context;
40 virtual ~GECKO_SYM(HeaderVisitor)()
45 DownloaderResponseHeaderCallback callback;
49 NS_IMPL_ISUPPORTS1(GECKO_SYM(HeaderVisitor), nsIHttpHeaderVisitor)
52 GECKO_SYM(HeaderVisitor)::VisitHeader(const nsACString &header, const nsACString &value)
54 const char *name, *val;
57 nl = NS_CStringGetData (header, &name);
58 vl = NS_CStringGetData (value, &val);
60 name = g_strndup (name, nl);
61 val = g_strndup (val, vl);
63 callback (context, name, val);
65 g_free ((gpointer) name);
66 g_free ((gpointer) val);
71 class GECKO_SYM(DownloaderResponse) : public DownloaderResponse, public nsIStreamListener {
73 nsCOMPtr<nsIChannel> channel;
77 NS_DECL_NSIREQUESTOBSERVER
78 NS_DECL_NSISTREAMLISTENER
83 GECKO_SYM(DownloaderResponse) (nsCOMPtr<nsIChannel> channel, DownloaderResponseStartedHandler started, DownloaderResponseDataAvailableHandler available, DownloaderResponseFinishedHandler finished, gpointer context)
84 : DownloaderResponse (started, available, finished, context)
86 this->channel = channel;
87 this->aborted = false;
90 virtual ~GECKO_SYM(DownloaderResponse) ()
105 virtual void SetHeaderVisitor (DownloaderResponseHeaderCallback visitor, gpointer context);
106 int GetResponseStatus ();
107 const char *GetResponseStatusText ();
110 class GECKO_SYM(DownloaderRequest) : public DownloaderRequest {
113 nsCOMPtr<nsIChannel> channel;
115 void CreateChannel ();
118 GECKO_SYM(DownloaderRequest) (const char *method, const char *uri, bool disable_cache)
119 : DownloaderRequest (method, uri)
121 this->disable_cache = disable_cache;
125 ~GECKO_SYM(DownloaderRequest) ()
129 DownloaderResponse *GetResponse ();
130 bool GetResponse (DownloaderResponseStartedHandler started, DownloaderResponseDataAvailableHandler available, DownloaderResponseFinishedHandler finished, gpointer context);
131 void SetHttpHeader (const char *name, const char *value);
132 void SetBody (void *body, int size);
137 // DownloaderResponse
139 NS_IMPL_ISUPPORTS1 (GECKO_SYM(DownloaderResponse), nsIStreamListener)
142 GECKO_SYM(DownloaderResponse)::SetHeaderVisitor (DownloaderResponseHeaderCallback visitor, gpointer context)
144 GECKO_SYM(HeaderVisitor) *hv = new GECKO_SYM(HeaderVisitor) (visitor, context);
145 nsCOMPtr<nsIHttpChannel> httpchannel = do_QueryInterface (channel);
147 httpchannel->VisitResponseHeaders (hv);
151 GECKO_SYM(DownloaderResponse)::GetResponseStatus ()
154 nsCOMPtr<nsIHttpChannel> httpchannel = do_QueryInterface (channel);
156 httpchannel->GetResponseStatus (&status);
162 GECKO_SYM(DownloaderResponse)::GetResponseStatusText ()
165 nsCOMPtr<nsIHttpChannel> httpchannel = do_QueryInterface (channel);
167 httpchannel->GetResponseStatusText (status);
173 GECKO_SYM(DownloaderResponse)::Abort ()
176 this->channel->Cancel (NS_BINDING_ABORTED);
182 GECKO_SYM(DownloaderResponse)::OnStartRequest (nsIRequest *request, nsISupports *context)
185 return started (this, this->context);
190 GECKO_SYM(DownloaderResponse)::OnStopRequest (nsIRequest *request, nsISupports *ctx, nsresult status)
193 return finished (this, this->context, (status == NS_OK), NULL, NULL);
198 GECKO_SYM(DownloaderResponse)::OnDataAvailable (nsIRequest *request, nsISupports *context, nsIInputStream *input, PRUint32 offset, PRUint32 count)
206 char *buffer = (char *) NS_Alloc (count);
207 input->Read (buffer, count, &length);
208 res = available (this, this->context, buffer, length);
217 GECKO_SYM(DownloaderRequest)::CreateChannel ()
220 nsCOMPtr<nsIServiceManager> mgr;
221 rv = NS_GetServiceManager (getter_AddRefs (mgr));
222 if (NS_FAILED (rv)) {
223 printf ("failed to ge a ServiceManager \n");
227 nsCOMPtr<nsIIOService> ioservice;
228 rv = mgr->GetServiceByContractID ("@mozilla.org/network/io-service;1",
229 NS_GET_IID (nsIIOService), getter_AddRefs (ioservice));
231 if (NS_FAILED (rv)) {
232 printf ("failed to get a IOService \n");
239 printf ("DownloaderRequest: %s\n", uri);
241 nsCOMPtr<nsIURI> uri;
242 rv = ioservice->NewURI (url, nsnull, nsnull, getter_AddRefs (uri));
244 ioservice->NewChannelFromURI (uri, getter_AddRefs (this->channel));
246 nsCOMPtr<nsIHttpChannel> httpchannel = do_QueryInterface (channel);
252 httpchannel->SetRequestMethod (meth);
256 GECKO_SYM(DownloaderRequest)::Abort ()
258 channel->Cancel (NS_BINDING_ABORTED);
260 if (response != NULL && !response->IsAborted ())
265 GECKO_SYM(DownloaderRequest)::GetResponse (DownloaderResponseStartedHandler started, DownloaderResponseDataAvailableHandler available, DownloaderResponseFinishedHandler finished, gpointer context)
268 GECKO_SYM(DownloaderResponse) *response;
269 nsCOMPtr<nsIHttpChannel> httpchannel = do_QueryInterface (channel);
271 response = new GECKO_SYM(DownloaderResponse) (channel, started, available, finished, context);
272 response->SetDownloaderRequest (this);
274 httpchannel->SetLoadFlags (nsIRequest::INHIBIT_CACHING);
276 rs = channel->AsyncOpen (response, (GECKO_SYM(DownloaderResponse)*)response);
278 this->response = response;
279 return !NS_FAILED (rs);
283 GECKO_SYM(DownloaderRequest)::SetHttpHeader (const char *name, const char *value)
285 nsCOMPtr<nsIHttpChannel> httpchannel = do_QueryInterface (channel);
289 nsEmbedCString nsname, nsvalue;
293 httpchannel->SetRequestHeader (nsname, nsvalue, true);
297 GECKO_SYM(DownloaderRequest)::SetBody (void *body, int size)
299 nsCOMPtr<nsIHttpChannel> httpchannel = do_QueryInterface (channel);
303 nsCOMPtr<nsIUploadChannel> upload = do_QueryInterface (channel);
310 nsCOMPtr<nsIStorageStream> storage = do_CreateInstance ("@mozilla.org/storagestream;1", &rv);
311 storage->Init (2048, PR_UINT32_MAX, nsnull);
313 nsCOMPtr<nsIOutputStream> output;
314 storage->GetOutputStream (0, getter_AddRefs (output));
317 output->Write ((const char *)body, size, &written);
320 nsCOMPtr<nsIInputStream> input;
321 rv = storage->NewInputStream (0, getter_AddRefs (input));
324 httpchannel->GetRequestMethod (method);
326 upload->SetUploadStream (input, type, -1);
328 httpchannel->SetRequestMethod (method);