@@ -119,69 +119,75 @@ internal unsafe IISHttpContext(
119
119
120
120
protected void InitializeContext ( )
121
121
{
122
- _thisHandle = GCHandle . Alloc ( this ) ;
122
+ // create a memory barrier between initialize and disconnect to prevent a possible
123
+ // NullRef with disconnect being called before these fields have been written
124
+ // disconnect aquires this lock as well
125
+ lock ( _abortLock )
126
+ {
127
+ _thisHandle = GCHandle . Alloc ( this ) ;
123
128
124
- Method = GetVerb ( ) ;
129
+ Method = GetVerb ( ) ;
125
130
126
- RawTarget = GetRawUrl ( ) ;
127
- // TODO version is slow.
128
- HttpVersion = GetVersion ( ) ;
129
- Scheme = SslStatus != SslStatus . Insecure ? Constants . HttpsScheme : Constants . HttpScheme ;
130
- KnownMethod = VerbId ;
131
- StatusCode = 200 ;
131
+ RawTarget = GetRawUrl ( ) ;
132
+ // TODO version is slow.
133
+ HttpVersion = GetVersion ( ) ;
134
+ Scheme = SslStatus != SslStatus . Insecure ? Constants . HttpsScheme : Constants . HttpScheme ;
135
+ KnownMethod = VerbId ;
136
+ StatusCode = 200 ;
132
137
133
- var originalPath = GetOriginalPath ( ) ;
138
+ var originalPath = GetOriginalPath ( ) ;
134
139
135
- if ( KnownMethod == HttpApiTypes . HTTP_VERB . HttpVerbOPTIONS && string . Equals ( RawTarget , "*" , StringComparison . Ordinal ) )
136
- {
137
- PathBase = string . Empty ;
138
- Path = string . Empty ;
139
- }
140
- else
141
- {
142
- // Path and pathbase are unescaped by RequestUriBuilder
143
- // The UsePathBase middleware will modify the pathbase and path correctly
144
- PathBase = string . Empty ;
145
- Path = originalPath ;
146
- }
140
+ if ( KnownMethod == HttpApiTypes . HTTP_VERB . HttpVerbOPTIONS && string . Equals ( RawTarget , "*" , StringComparison . Ordinal ) )
141
+ {
142
+ PathBase = string . Empty ;
143
+ Path = string . Empty ;
144
+ }
145
+ else
146
+ {
147
+ // Path and pathbase are unescaped by RequestUriBuilder
148
+ // The UsePathBase middleware will modify the pathbase and path correctly
149
+ PathBase = string . Empty ;
150
+ Path = originalPath ;
151
+ }
147
152
148
- var cookedUrl = GetCookedUrl ( ) ;
149
- QueryString = cookedUrl . GetQueryString ( ) ?? string . Empty ;
153
+ var cookedUrl = GetCookedUrl ( ) ;
154
+ QueryString = cookedUrl . GetQueryString ( ) ?? string . Empty ;
150
155
151
- RequestHeaders = new RequestHeaders ( this ) ;
152
- HttpResponseHeaders = new HeaderCollection ( ) ;
153
- ResponseHeaders = HttpResponseHeaders ;
156
+ RequestHeaders = new RequestHeaders ( this ) ;
157
+ HttpResponseHeaders = new HeaderCollection ( ) ;
158
+ ResponseHeaders = HttpResponseHeaders ;
154
159
155
- if ( _options . ForwardWindowsAuthentication )
156
- {
157
- WindowsUser = GetWindowsPrincipal ( ) ;
158
- if ( _options . AutomaticAuthentication )
160
+ if ( _options . ForwardWindowsAuthentication )
159
161
{
160
- User = WindowsUser ;
162
+ WindowsUser = GetWindowsPrincipal ( ) ;
163
+ if ( _options . AutomaticAuthentication )
164
+ {
165
+ User = WindowsUser ;
166
+ }
161
167
}
162
- }
163
168
164
- MaxRequestBodySize = _options . MaxRequestBodySize ;
169
+ MaxRequestBodySize = _options . MaxRequestBodySize ;
165
170
166
- ResetFeatureCollection ( ) ;
171
+ ResetFeatureCollection ( ) ;
167
172
168
- if ( ! _server . IsWebSocketAvailable ( _pInProcessHandler ) )
169
- {
170
- _currentIHttpUpgradeFeature = null ;
171
- }
173
+ if ( ! _server . IsWebSocketAvailable ( _pInProcessHandler ) )
174
+ {
175
+ _currentIHttpUpgradeFeature = null ;
176
+ }
172
177
173
- _streams = new Streams ( this ) ;
178
+ _streams = new Streams ( this ) ;
174
179
175
- ( RequestBody , ResponseBody ) = _streams . Start ( ) ;
180
+ ( RequestBody , ResponseBody ) = _streams . Start ( ) ;
176
181
177
- var pipe = new Pipe (
178
- new PipeOptions (
179
- _memoryPool ,
180
- readerScheduler : PipeScheduler . ThreadPool ,
181
- pauseWriterThreshold : PauseWriterThreshold ,
182
- resumeWriterThreshold : ResumeWriterTheshold ,
183
- minimumSegmentSize : MinAllocBufferSize ) ) ;
184
- _bodyOutput = new OutputProducer ( pipe ) ;
182
+ var pipe = new Pipe (
183
+ new PipeOptions (
184
+ _memoryPool ,
185
+ readerScheduler : PipeScheduler . ThreadPool ,
186
+ pauseWriterThreshold : PauseWriterThreshold ,
187
+ resumeWriterThreshold : ResumeWriterTheshold ,
188
+ minimumSegmentSize : MinAllocBufferSize ) ) ;
189
+ _bodyOutput = new OutputProducer ( pipe ) ;
190
+ }
185
191
186
192
NativeMethods . HttpSetManagedContext ( _pInProcessHandler , ( IntPtr ) _thisHandle ) ;
187
193
}
0 commit comments