11using System ;
22using System . Collections ;
3+ using System . Collections . Generic ;
34using System . Net ;
5+ using PatchKit . Logging ;
46using UnityEngine ;
57using PatchKit . Network ;
68using PatchKit . Unity . Patcher . Debug ;
9+ using PatchKit . Unity . Utilities ;
10+ using ILogger = PatchKit . Logging . ILogger ;
711
812namespace PatchKit . Unity . Patcher . AppData . Remote
913{
1014 public class UnityHttpClient : IHttpClient
1115 {
12- private class RequestResult
16+ private class WWWResult
1317 {
14- public bool IsDone ;
18+ public bool IsDone { get ; set ; }
1519
16- public string Data ;
17- public int StatusCode ;
20+ public string Text { get ; set ; }
1821
19- public bool WasError ;
20- public bool WasTimeout ;
21- public string ErrorText ;
22+ public Dictionary < string , string > ResponseHeaders { get ; set ; }
2223 }
23-
24- private static readonly DebugLogger DebugLogger = new DebugLogger ( typeof ( UnityHttpClient ) ) ;
24+
25+ private readonly ILogger _logger ;
2526
2627 private const string ResponseEncoding = "iso-8859-2" ;
2728
28- private IEnumerator JobCoroutine ( HttpGetRequest getRequest , RequestResult result )
29+ public UnityHttpClient ( )
30+ {
31+ _logger = PatcherLogManager . DefaultLogger ;
32+ }
33+
34+ private IEnumerator GetWWW ( HttpGetRequest getRequest , WWWResult result )
2935 {
3036 var www = new WWW ( getRequest . Address . ToString ( ) ) ;
3137
3238 yield return www ;
3339
34- if ( ! www . isDone )
40+ lock ( result )
3541 {
36- lock ( result )
42+ result . IsDone = www . isDone ;
43+
44+ if ( www . isDone )
3745 {
38- result . WasTimeout = true ;
39- result . IsDone = true ;
46+ result . ResponseHeaders = www . responseHeaders ;
47+ result . Text = www . text ;
4048 }
41- yield break ;
4249 }
50+ }
4351
44- if ( ! string . IsNullOrEmpty ( www . error ) )
52+ public IHttpResponse Get ( HttpGetRequest getRequest )
53+ {
54+ try
4555 {
46- lock ( result )
56+ _logger . LogDebug ( "Sending GET request to " + getRequest . Address ) ;
57+
58+ if ( getRequest . Range != null )
4759 {
48- result . ErrorText = www . error ;
49- result . WasError = true ;
50- result . IsDone = true ;
60+ throw new NotImplementedException ( ) ;
5161 }
52- yield break ;
53- }
5462
55- var wwwText = www . text ;
63+ _logger . LogTrace ( "timeout = " + getRequest . Timeout ) ;
64+
65+ var result = new WWWResult ( ) ;
5666
57- if ( string . IsNullOrEmpty ( wwwText ) )
58- {
59- lock ( result )
60- {
61- result . ErrorText = "Empty response data" ;
62- result . WasError = true ;
63- result . IsDone = true ;
64- }
65- yield break ;
66- }
67+ var waitHandle = UnityDispatcher . InvokeCoroutine ( GetWWW ( getRequest , result ) ) ;
68+
69+ waitHandle . WaitOne ( TimeSpan . FromMilliseconds ( getRequest . Timeout ) ) ;
6770
68- lock ( result )
69- {
70- try
71+ lock ( result )
7172 {
72- result . Data = wwwText ;
73-
74- if ( ! www . responseHeaders . ContainsKey ( "STATUS" ) )
75- {
76- // Based on tests, if response doesn't contain status it has probably timed out.
77- DebugLogger . Log ( "Response is missing STATUS header. Marking it as timed out." ) ;
78- result . WasTimeout = true ;
79- }
80- else
73+ if ( ! result . IsDone )
8174 {
82- var status = www . responseHeaders [ "STATUS" ] ;
83- DebugLogger . Log ( string . Format ( "Response status: {0}" , status ) ) ;
84- var s = status . Split ( ' ' ) ;
85-
86- if ( s . Length >= 3 && int . TryParse ( s [ 1 ] , out result . StatusCode ) )
87- {
88- DebugLogger . Log ( string . Format ( "Successfully parsed status code: {0}" , result . StatusCode ) ) ;
89- }
90- else
91- {
92- // Based on tests, if response contains invalid status it has probably timed out.
93- DebugLogger . Log ( string . Format ( "Response has invalid status - {0}. Marking it as timed out." ,
94- status ) ) ;
95- result . WasTimeout = true ;
96- }
75+ throw new WebException ( "Timeout." , WebExceptionStatus . Timeout ) ;
9776 }
98- }
99- catch ( Exception e )
100- {
101- result . WasError = true ;
102- result . ErrorText = e . ToString ( ) ;
103- }
104- finally
105- {
106- result . IsDone = true ;
77+
78+ var statusCode = ReadStatusCode ( result ) ;
79+
80+ _logger . LogDebug ( "Successfuly received response." ) ;
81+ return new UnityHttpResponse ( result . Text , statusCode , ResponseEncoding ) ;
10782 }
10883 }
109-
110- yield return null ;
84+ catch ( Exception e )
85+ {
86+ _logger . LogError ( "Failed to get response." , e ) ;
87+ throw ;
88+ }
11189 }
11290
113- public IHttpResponse Get ( HttpGetRequest getRequest )
91+ private HttpStatusCode ReadStatusCode ( WWWResult result )
11492 {
115- if ( getRequest . Range != null )
93+ _logger . LogDebug ( "Reading status code..." ) ;
94+
95+ if ( ! result . ResponseHeaders . ContainsKey ( "STATUS" ) )
11696 {
117- throw new NotImplementedException ( ) ;
97+ // Based on tests, if response doesn't contain status it has probably timed out.
98+ _logger . LogWarning ( "Response is missing STATUS header. Marking it as timed out." ) ;
99+ throw new WebException ( "Timeout." , WebExceptionStatus . Timeout ) ;
118100 }
119-
120- var result = new RequestResult ( ) ;
121101
122- var waitHandle = Utilities . UnityDispatcher . InvokeCoroutine ( JobCoroutine ( getRequest , result ) ) ;
123-
124- waitHandle . WaitOne ( TimeSpan . FromMilliseconds ( getRequest . Timeout ) ) ;
102+ var status = result . ResponseHeaders [ "STATUS" ] ;
103+ _logger . LogTrace ( "status = " + status ) ;
104+
105+ var s = status . Split ( ' ' ) ;
106+
107+ int statusCode ;
125108
126- if ( result . WasTimeout || ! result . IsDone )
109+ if ( s . Length < 3 || ! int . TryParse ( s [ 1 ] , out statusCode ) )
127110 {
111+ _logger . LogWarning ( "Response has invalid status. Marking it as timed out." ) ;
128112 throw new WebException ( "Timeout." , WebExceptionStatus . Timeout ) ;
129113 }
130114
131- if ( result . WasError )
132- {
133- throw new WebException ( result . ErrorText ) ;
134- }
115+ _logger . LogTrace ( "statusCode = " + statusCode ) ;
116+ _logger . LogTrace ( "statusCode (as enum) = " + ( HttpStatusCode ) statusCode ) ;
135117
136- return new UnityHttpResponse ( result . Data , result . StatusCode , ResponseEncoding ) ;
118+ return ( HttpStatusCode ) statusCode ;
137119 }
138120 }
139121}
0 commit comments