@@ -22,8 +22,10 @@ internal class AppiumCommandExecutor : ICommandExecutor
22
22
{
23
23
private readonly AppiumLocalService Service ;
24
24
private readonly Uri URL ;
25
- private readonly ICommandExecutor RealExecutor ;
25
+ private ICommandExecutor RealExecutor ;
26
26
private bool isDisposed ;
27
+ private const string IdempotencyHeader = "X-Idempotency-Key" ;
28
+
27
29
28
30
private static ICommandExecutor CreateRealExecutor ( Uri remoteAddress , TimeSpan commandTimeout )
29
31
{
@@ -37,6 +39,7 @@ private static ICommandExecutor CreateRealExecutor(Uri remoteAddress, TimeSpan c
37
39
Activator . CreateInstance ( commandType , new object [ ] { remoteAddress , commandTimeout } ) as
38
40
ICommandExecutor ;
39
41
}
42
+
40
43
41
44
return commandExecutor ;
42
45
}
@@ -64,23 +67,29 @@ internal AppiumCommandExecutor(AppiumLocalService service, TimeSpan timeForTheSe
64
67
public Response Execute ( Command commandToExecute )
65
68
{
66
69
Response result = null ;
67
- if ( commandToExecute . Name == DriverCommand . NewSession && this . Service != null )
68
- {
69
- Service . Start ( ) ;
70
- }
70
+
71
71
72
72
try
73
73
{
74
+ if ( commandToExecute . Name == DriverCommand . NewSession && Service != null )
75
+ {
76
+ Service . Start ( ) ;
77
+ }
78
+ else
79
+ {
80
+ RealExecutor = ModifyHttpRequestHeader ( RealExecutor ) ;
81
+ }
82
+
74
83
result = RealExecutor . Execute ( commandToExecute ) ;
75
84
return result ;
76
85
}
77
86
catch ( Exception e )
78
87
{
79
- if ( ( commandToExecute . Name == DriverCommand . NewSession ) && ( Service != null ) )
88
+ if ( ( commandToExecute . Name == DriverCommand . NewSession ) )
80
89
{
81
- Service . Dispose ( ) ;
90
+ Service ? . Dispose ( ) ;
82
91
}
83
- throw e ;
92
+ throw ;
84
93
}
85
94
finally
86
95
{
@@ -97,21 +106,29 @@ public Response Execute(Command commandToExecute)
97
106
}
98
107
}
99
108
100
- public void Dispose ( )
109
+ private ICommandExecutor ModifyHttpRequestHeader ( ICommandExecutor commandExecutor )
110
+ {
111
+ var modifiedCommandExecutor = commandExecutor as HttpCommandExecutor ;
112
+ if ( modifiedCommandExecutor != null )
113
+ modifiedCommandExecutor . SendingRemoteHttpRequest += SendingRemoteHttpRequestHandler ;
114
+ return modifiedCommandExecutor ;
115
+ }
116
+
117
+ private void SendingRemoteHttpRequestHandler (
118
+ object sender , SendingRemoteHttpRequestEventArgs e )
101
119
{
102
- this . Dispose ( true ) ;
120
+ e . Request . Headers . Add ( IdempotencyHeader , Guid . NewGuid ( ) . ToString ( ) ) ;
103
121
}
104
122
123
+ public void Dispose ( ) => Dispose ( true ) ;
124
+
105
125
protected void Dispose ( bool disposing )
106
126
{
107
127
if ( ! isDisposed )
108
128
{
109
129
if ( disposing )
110
130
{
111
- if ( Service != null )
112
- {
113
- Service . Dispose ( ) ;
114
- }
131
+ Service ? . Dispose ( ) ;
115
132
}
116
133
117
134
isDisposed = true ;
0 commit comments