Skip to content

Commit d259bce

Browse files
authored
Merge pull request #84 from ssethumavisa/FixForLargeFileDownload
Fix for large file download
2 parents bda3f0b + bfa74e8 commit d259bce

File tree

1 file changed

+169
-30
lines changed

1 file changed

+169
-30
lines changed

generator/cybersource-csharp-template/ApiClient.mustache

Lines changed: 169 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,12 @@ namespace {{packageName}}.Client
115115
/// <value>An instance of the RestClient</value>
116116
public RestClient RestClient { get; set; }
117117

118+
/// <summary>
119+
/// Gets or sets the file name, in which the response to be downloaded.
120+
/// </summary>
121+
/// <value>An instance of the Configuration.</value>
122+
public string DownloadReponseFileName { get; set; }
123+
118124
// Creates and sets up a RestRequest prior to a call.
119125
private RestRequest PrepareRequest(
120126
String path, {{^netStandard}}RestSharp.{{/netStandard}}Method method, Dictionary<String, String> queryParams, Object postBody,
@@ -237,6 +243,83 @@ namespace {{packageName}}.Client
237243
return request;
238244
}
239245

246+
// Creates and sets up a HttpWebRequest for calls which needs response in a file format.
247+
private HttpWebRequest PrepareHttpWebRequest(
248+
String path, {{^netStandard}}RestSharp.{{/netStandard}}Method method, Dictionary<String, String> queryParams, Object postBody,
249+
Dictionary<String, String> headerParams, Dictionary<String, String> formParams,
250+
Dictionary<String, FileParameter> fileParams, Dictionary<String, String> pathParams,
251+
String contentType)
252+
{
253+
// Change to path(Request Target) to be sent to Authentication SDK
254+
// Include Query Params in the Request target
255+
var firstQueryParam = true;
256+
foreach (var param in queryParams)
257+
{
258+
var key = param.Key;
259+
var val = param.Value;
260+
261+
if (!firstQueryParam)
262+
{
263+
path = path + "&" + key + "=" + val;
264+
}
265+
else
266+
{
267+
path = path + "?" + key + "=" + val;
268+
firstQueryParam = false;
269+
}
270+
}
271+
272+
//initiate a HttpWebRequest object
273+
HttpWebRequest requestT = (HttpWebRequest)WebRequest.Create(Uri.EscapeUriString("https://" + RestClient.BaseUrl.Host + path));
274+
requestT.UserAgent = Configuration.UserAgent;
275+
276+
if (Configuration.Proxy != null)
277+
{
278+
requestT.Proxy = Configuration.Proxy;
279+
}
280+
requestT.ContentType = contentType;
281+
282+
// add header parameter, if any
283+
// passed to this function
284+
foreach (var param in headerParams)
285+
{
286+
if (param.Key == "Accept")
287+
{
288+
requestT.Accept = param.Value;
289+
}
290+
else
291+
requestT.Headers.Add(param.Key, param.Value);
292+
}
293+
294+
//initiate the default authentication headers
295+
if (postBody == null)
296+
{
297+
CallAuthenticationHeaders(method.ToString(), path);
298+
}
299+
else
300+
{
301+
CallAuthenticationHeaders(method.ToString(), path, postBody.ToString());
302+
}
303+
304+
foreach (var param in Configuration.DefaultHeader)
305+
{
306+
if (param.Key == "Authorization")
307+
{
308+
requestT.Headers.Add("Authorization", string.Format("Bearer " + param.Value));
309+
}
310+
else if (param.Key == "Date")
311+
{
312+
requestT.Date = DateTime.Parse(param.Value);
313+
}
314+
else if (param.Key == "Host")
315+
{ }
316+
else
317+
requestT.Headers.Add(param.Key, param.Value);
318+
}
319+
320+
return requestT;
321+
}
322+
240323
/// <summary>
241324
/// Makes the HTTP request (Sync).
242325
/// </summary>
@@ -256,42 +339,98 @@ namespace {{packageName}}.Client
256339
Dictionary<String, FileParameter> fileParams, Dictionary<String, String> pathParams,
257340
String contentType)
258341
{
259-
var request = PrepareRequest(
260-
path, method, queryParams, postBody, headerParams, formParams, fileParams,
261-
pathParams, contentType);
342+
//declared separately to handle both regular call and download file calls
343+
int httpResponseStatusCode;
344+
IList<Parameter> httpResponseHeaders = null;
345+
string httpResponseData = string.Empty;
346+
347+
var response = new RestResponse();
262348
263-
// set timeout
264-
RestClient.Timeout = Configuration.Timeout;
265-
// set user agent
266-
RestClient.UserAgent = Configuration.UserAgent;
349+
//check if the Response is to be downloaded as a file, this value to be set by the calling API class
350+
if (string.IsNullOrEmpty(DownloadReponseFileName))
351+
{
352+
var request = PrepareRequest(
353+
path, method, queryParams, postBody, headerParams, formParams, fileParams,
354+
pathParams, contentType);
355+
356+
// set timeout
357+
RestClient.Timeout = Configuration.Timeout;
358+
// set user agent
359+
RestClient.UserAgent = Configuration.UserAgent;
267360
268-
RestClient.ClearHandlers();
361+
RestClient.ClearHandlers();
269362
270-
if (Configuration.Proxy != null)
363+
if (Configuration.Proxy != null)
364+
{
365+
RestClient.Proxy = Configuration.Proxy;
366+
}
367+
368+
InterceptRequest(request);
369+
{{#netStandard}}
370+
response = RestClient.Execute(request).Result;
371+
{{/netStandard}}
372+
{{^netStandard}}
373+
{{^supportsUWP}}
374+
response = RestClient.Execute(request);
375+
{{/supportsUWP}}
376+
{{#supportsUWP}}
377+
// Using async method to perform sync call (uwp-only)
378+
response = RestClient.ExecuteTaskAsync(request).Result;
379+
{{/supportsUWP}}
380+
{{/netStandard}}
381+
InterceptResponse(request, response);
382+
}
383+
else
271384
{
272-
RestClient.Proxy = Configuration.Proxy;
273-
}
385+
//prepare a HttpWebRequest request object
386+
var requestT = PrepareHttpWebRequest(path, method, queryParams, postBody, headerParams, formParams, fileParams, pathParams, contentType);
387+
388+
//getting the response stream using httpwebrequest
389+
HttpWebResponse responseT = (HttpWebResponse)requestT.GetResponse();
390+
using (Stream responseStream = responseT.GetResponseStream())
391+
{
392+
//setting high timeout to accomodate large files till 2GB, need to revisit for a dynamic approach
393+
responseStream.ReadTimeout = 8000000;
394+
responseStream.WriteTimeout = 9000000;
395+
using (Stream fileStream = File.OpenWrite(@DownloadReponseFileName))
396+
{
397+
byte[] buffer = new byte[4096];
398+
int bytesRead = responseStream.Read(buffer, 0, 4096);
399+
while (bytesRead > 0)
400+
{
401+
fileStream.Write(buffer, 0, bytesRead);
402+
bytesRead = responseStream.Read(buffer, 0, 4096);
403+
}
404+
}
405+
}
406+
407+
//setting the generic response with response headers
408+
foreach (var header in responseT.Headers)
409+
{
410+
response.Headers.Add(new Parameter(header.ToString(), String.Join(",", responseT.Headers.GetValues(header.ToString()).ToArray()), ParameterType.HttpHeader));
411+
}
412+
413+
//setting the generic RestResponse which is returned to the calling class
414+
response.StatusCode = responseT.StatusCode;
415+
if (responseT.StatusCode == HttpStatusCode.OK)
416+
{
417+
response.Content = "Custom Message: Response downloaded to file " + DownloadReponseFileName;
418+
}
419+
else if (responseT.StatusCode == HttpStatusCode.NotFound)
420+
{
421+
response.Content = "Custom Message: The requested resource is not found. Please try again later.";
422+
}
423+
else
424+
{
425+
response.Content = responseT.StatusDescription;
426+
}
427+
}
274428

275-
InterceptRequest(request);
276-
{{#netStandard}}
277-
var response = RestClient.Execute(request).Result;
278-
{{/netStandard}}
279-
{{^netStandard}}
280-
{{^supportsUWP}}
281-
var response = RestClient.Execute(request);
282-
{{/supportsUWP}}
283-
{{#supportsUWP}}
284-
// Using async method to perform sync call (uwp-only)
285-
var response = RestClient.ExecuteTaskAsync(request).Result;
286-
{{/supportsUWP}}
287-
{{/netStandard}}
288-
InterceptResponse(request, response);
289-
290429
Configuration.DefaultHeader.Clear();
291-
292-
var httpResponseStatusCode = (int)response.StatusCode;
293-
var httpResponseHeaders = response.Headers;
294-
var httpResponseData = response.Content;
430+
431+
httpResponseStatusCode = (int)response.StatusCode;
432+
httpResponseHeaders = response.Headers;
433+
httpResponseData = response.Content;
295434

296435
Console.WriteLine($"\n");
297436
Console.WriteLine($"RESPONSE STATUS CODE: {httpResponseStatusCode}");

0 commit comments

Comments
 (0)