Skip to content

Commit 0e037c5

Browse files
committed
Refactored the custom scheme handling to support asynchronous handlers + make it possible to override the HTTP response headers.
1 parent b33eb55 commit 0e037c5

File tree

10 files changed

+129
-29
lines changed

10 files changed

+129
-29
lines changed

CefSharp/CefSharp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include "include/cef_task.h"
1010
#include "CookieVisitor.h"
1111
#include "Settings.h"
12-
#include "SchemeHandler.h"
12+
#include "SchemeHandlerWrapper.h"
1313
#include "StringUtil.h"
1414

1515
using namespace System;

CefSharp/CefSharp.vcxproj

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@
132132
<ClCompile Include="Request.cpp" />
133133
<ClCompile Include="RequestResponse.cpp" />
134134
<ClCompile Include="RtzCountdownEvent.cpp" />
135-
<ClCompile Include="SchemeHandler.cpp" />
135+
<ClCompile Include="SchemeHandlerResponse.cpp" />
136+
<ClCompile Include="SchemeHandlerWrapper.cpp" />
136137
<ClCompile Include="ScriptCore.cpp" />
137138
<ClCompile Include="Stdafx.cpp">
138139
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
@@ -169,7 +170,8 @@
169170
<ClInclude Include="Request.h" />
170171
<ClInclude Include="RequestResponse.h" />
171172
<ClInclude Include="RtzCountdownEvent.h" />
172-
<ClInclude Include="SchemeHandler.h" />
173+
<ClInclude Include="SchemeHandlerWrapper.h" />
174+
<ClInclude Include="SchemeHandlerResponse.h" />
173175
<ClInclude Include="ScriptCore.h" />
174176
<ClInclude Include="ScriptException.h" />
175177
<ClInclude Include="Settings.h" />

CefSharp/CefSharp.vcxproj.filters

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,6 @@
5353
<ClCompile Include="RtzCountdownEvent.cpp">
5454
<Filter>Source Files</Filter>
5555
</ClCompile>
56-
<ClCompile Include="SchemeHandler.cpp">
57-
<Filter>Source Files</Filter>
58-
</ClCompile>
5956
<ClCompile Include="ScriptCore.cpp">
6057
<Filter>Source Files</Filter>
6158
</ClCompile>
@@ -74,6 +71,12 @@
7471
<ClCompile Include="Internals\JavascriptBinding\BindingHandler.cpp">
7572
<Filter>Source Files\Internals\JavascriptBinding</Filter>
7673
</ClCompile>
74+
<ClCompile Include="SchemeHandlerWrapper.cpp">
75+
<Filter>Source Files</Filter>
76+
</ClCompile>
77+
<ClCompile Include="SchemeHandlerResponse.cpp">
78+
<Filter>Source Files</Filter>
79+
</ClCompile>
7780
</ItemGroup>
7881
<ItemGroup>
7982
<ClInclude Include="BrowserCore.h">
@@ -139,9 +142,6 @@
139142
<ClInclude Include="RtzCountdownEvent.h">
140143
<Filter>Header Files</Filter>
141144
</ClInclude>
142-
<ClInclude Include="SchemeHandler.h">
143-
<Filter>Header Files</Filter>
144-
</ClInclude>
145145
<ClInclude Include="ScriptCore.h">
146146
<Filter>Header Files</Filter>
147147
</ClInclude>
@@ -181,5 +181,11 @@
181181
<ClInclude Include="IJsDialogHandler.h">
182182
<Filter>Header Files</Filter>
183183
</ClInclude>
184+
<ClInclude Include="SchemeHandlerWrapper.h">
185+
<Filter>Header Files</Filter>
186+
</ClInclude>
187+
<ClInclude Include="SchemeHandlerResponse.h">
188+
<Filter>Header Files</Filter>
189+
</ClInclude>
184190
</ItemGroup>
185191
</Project>

CefSharp/Request.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ namespace CefSharp
6969
{
7070
String^ name = toClr(it->first);
7171
String^ value = toClr(it->second);
72-
headers->Add(name, value);
72+
headers[name] = value;
7373
}
7474

7575
return headers;

CefSharp/Request.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,30 @@
1+
#pragma once
2+
13
#include "Stdafx.h"
24
#include "IRequest.h"
3-
#pragma once
5+
#include "SchemeHandlerResponse.h"
46

57
using namespace System;
68
using namespace System::Collections::Generic;
79

810
namespace CefSharp
911
{
12+
class SchemeHandlerWrapper;
13+
1014
ref class CefRequestWrapper : public IRequest
1115
{
1216
MCefRefPtr<CefRequest> _wrappedRequest;
1317
internal:
1418
CefRequestWrapper(CefRefPtr<CefRequest> cefRequest) : _wrappedRequest(cefRequest) {}
19+
//void (SchemeHandlerWrapper::* RequestCompletedCallback)(SchemeResponse^);
20+
21+
//void OnRequestCompleted(SchemeResponse^ response);
1522

1623
public:
1724
virtual property String^ Url { String^ get(); void set(String^ url); }
1825
virtual property String^ Method { String^ get(); }
1926
virtual property String^ Body { String^ get(); }
2027
virtual IDictionary<String^, String^>^ GetHeaders();
2128
virtual void SetHeaders(IDictionary<String^, String^>^ headers);
22-
2329
};
2430
}

CefSharp/RequestResponse.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,17 @@ namespace CefSharp
1212
{
1313
/// cancel the request, return nothing
1414
void Cancel();
15+
1516
/// the current request
1617
property IRequest^ Request { IRequest^ get(); };
18+
1719
/// respond with redirection to the provided URL
1820
void Redirect(String^ url);
21+
1922
/// respond with data from Stream
2023
void RespondWith(Stream^ stream, String^ mimeType);
24+
25+
void RespondWith(Stream^ stream, String^ mimeType, String^ statusText, int statusCode, IDictionary<String^, String^>^ responseHeaders);
2126
};
2227

2328
enum class ResponseAction
@@ -59,5 +64,4 @@ namespace CefSharp
5964
virtual void RespondWith(Stream^ stream, String^ mimeType);
6065
virtual void RespondWith(Stream^ stream, String^ mimeType, String^ statusText, int statusCode, IDictionary<String^, String^>^ responseHeaders);
6166
};
62-
6367
}

CefSharp/SchemeHandlerResponse.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#include "Stdafx.h"
2+
#include "SchemeHandlerWrapper.h"
3+
4+
namespace CefSharp
5+
{
6+
void SchemeHandlerResponse::OnRequestCompleted()
7+
{
8+
_schemeHandlerWrapper->ProcessRequestCallback(this);
9+
}
10+
}

CefSharp/SchemeHandlerResponse.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#pragma once
2+
3+
#include "Stdafx.h"
4+
#include "SchemeHandlerWrapper.h"
5+
6+
using namespace System;
7+
using namespace System::Collections::Generic;
8+
using namespace System::IO;
9+
10+
namespace CefSharp
11+
{
12+
class SchemeHandlerWrapper;
13+
14+
public ref class SchemeHandlerResponse
15+
{
16+
internal:
17+
SchemeHandlerWrapper* _schemeHandlerWrapper;
18+
void OnRequestCompleted();
19+
20+
public:
21+
/// <summary>
22+
/// A Stream with the response data. If the request didn't return any response, leave this property as null.
23+
/// </summary>
24+
property Stream^ ResponseStream;
25+
26+
property String^ MimeType;
27+
property IDictionary<String^, String^>^ ResponseHeaders;
28+
29+
SchemeHandlerResponse(SchemeHandlerWrapper* schemeHandlerWrapper)
30+
{
31+
_schemeHandlerWrapper = schemeHandlerWrapper;
32+
}
33+
};
34+
};

CefSharp/SchemeHandler.cpp renamed to CefSharp/SchemeHandlerWrapper.cpp

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,66 @@
11
#include "Stdafx.h"
22

3-
#include "SchemeHandler.h"
3+
#include "SchemeHandlerWrapper.h"
4+
5+
using namespace System::Runtime::InteropServices;
46

57
namespace CefSharp
68
{
7-
void SchemeHandlerWrapper::GetResponseHeaders(CefRefPtr<CefResponse> response, int64& response_length, CefString& redirectUrl)
9+
namespace
810
{
9-
response->SetMimeType(_mime_type);
10-
response->SetStatus(200);
11-
response_length = SizeFromStream();
12-
}
11+
CefResponse::HeaderMap ToHeaderMap(IDictionary<String^, String^>^ headers)
12+
{
13+
CefResponse::HeaderMap result;
14+
15+
for each (KeyValuePair<String^, String^> header in headers)
16+
{
17+
result.insert(std::pair<CefString,CefString>(toNative(header.Key), toNative(header.Value)));
18+
}
19+
20+
return result;
21+
}
22+
};
1323

1424
bool SchemeHandlerWrapper::ProcessRequest(CefRefPtr<CefRequest> request, CefRefPtr<CefSchemeHandlerCallback> callback)
1525
{
26+
_callback = callback;
27+
1628
bool handled = false;
1729
Stream^ stream;
1830
String^ mimeType;
1931

2032
AutoLock lock_scope(this);
2133

22-
IRequest^ requestWrapper = gcnew CefRequestWrapper(request);
23-
if (_handler->ProcessRequest(requestWrapper, mimeType, stream))
24-
{
25-
_mime_type = toNative(mimeType);
26-
_stream = stream;
27-
callback->HeadersAvailable();
34+
auto schemeResponse = gcnew SchemeHandlerResponse(this);
35+
auto onRequestCompleted = gcnew OnRequestCompletedHandler(schemeResponse, &SchemeHandlerResponse::OnRequestCompleted);
2836

37+
auto requestWrapper = gcnew CefRequestWrapper(request);
38+
if (_handler->ProcessRequestAsync(requestWrapper, schemeResponse, onRequestCompleted))
39+
{
2940
handled = true;
3041
}
3142

3243
return handled;
3344
}
3445

46+
void SchemeHandlerWrapper::ProcessRequestCallback(SchemeHandlerResponse^ response)
47+
{
48+
_mime_type = toNative(response->MimeType);
49+
_stream = response->ResponseStream;
50+
51+
_headers = ToHeaderMap(response->ResponseHeaders);
52+
53+
_callback->HeadersAvailable();
54+
}
55+
56+
void SchemeHandlerWrapper::GetResponseHeaders(CefRefPtr<CefResponse> response, int64& response_length, CefString& redirectUrl)
57+
{
58+
response->SetMimeType(_mime_type);
59+
response->SetStatus(200);
60+
response->SetHeaderMap(_headers);
61+
response_length = SizeFromStream();
62+
}
63+
3564
bool SchemeHandlerWrapper::ReadResponse(void* data_out, int bytes_to_read, int& bytes_read, CefRefPtr<CefSchemeHandlerCallback> callback)
3665
{
3766
bool has_data = false;

CefSharp/SchemeHandler.h renamed to CefSharp/SchemeHandlerWrapper.h

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,37 @@ using namespace System::IO;
99

1010
namespace CefSharp
1111
{
12+
ref class SchemeHandlerResponse;
13+
14+
public delegate void OnRequestCompletedHandler();
15+
1216
public interface class ISchemeHandler
1317
{
1418
/// <summary>
15-
/// if request is handled return true and set mimeType and stream accordingly.
16-
/// if no data the leave stream null
19+
/// Processes a custom scheme-based request asynchronously. The implementing method should call the callback whenever the
20+
/// request is completed.
1721
/// </summary>
18-
bool ProcessRequest(IRequest^ request, String^% mimeType, Stream^% stream);
22+
/// <returns>true if the request is handled, false otherwise.</returns>
23+
bool ProcessRequestAsync(IRequest^ request, SchemeHandlerResponse^ response, OnRequestCompletedHandler^ callback);
1924
};
2025

2126
public interface class ISchemeHandlerFactory
2227
{
2328
ISchemeHandler^ Create();
2429
};
2530

26-
class SchemeHandlerWrapper : public CefSchemeHandler
31+
public class SchemeHandlerWrapper : public CefSchemeHandler
2732
{
2833
gcroot<ISchemeHandler^> _handler;
2934
gcroot<Stream^> _stream;
3035
CefString _mime_type;
36+
CefResponse::HeaderMap _headers;
37+
CefRefPtr<CefSchemeHandlerCallback> _callback;
3138

3239
int SizeFromStream();
3340

3441
public:
42+
3543
SchemeHandlerWrapper(ISchemeHandler^ handler) : _handler(handler)
3644
{
3745
if(!_handler)
@@ -41,6 +49,7 @@ namespace CefSharp
4149
}
4250

4351
virtual bool ProcessRequest(CefRefPtr<CefRequest> request, CefRefPtr<CefSchemeHandlerCallback> callback);
52+
virtual void ProcessRequestCallback(SchemeHandlerResponse^ handlerResponse);
4453
virtual void GetResponseHeaders(CefRefPtr<CefResponse> response, int64& response_length, CefString& redirectUrl);
4554
virtual bool ReadResponse(void* data_out, int bytes_to_read, int& bytes_read, CefRefPtr<CefSchemeHandlerCallback> callback);
4655
virtual void Cancel();

0 commit comments

Comments
 (0)