using System.Text;
using System.Threading;
+#if NET_2_0
+using System.Net.Cache;
+#endif
+
namespace System.Net
{
[Serializable]
bool getResponseCalled;
Exception saved_exc;
object locker = new object ();
+ bool is_ntlm_auth;
#if NET_1_1
int maxResponseHeadersLength;
static int defaultMaxResponseHeadersLength;
}
}
#endif
-
- internal HttpWebRequest (Uri uri)
+
+#if NET_2_1
+ public
+#else
+ internal
+#endif
+ HttpWebRequest (Uri uri)
{
this.requestUri = uri;
this.actualUri = uri;
this.proxy = GlobalProxySelection.Select;
}
+#if NET_2_0
+ [Obsolete ("Serialization is obsoleted for this type", false)]
+#endif
protected HttpWebRequest (SerializationInfo serializationInfo, StreamingContext streamingContext)
{
SerializationInfo info = serializationInfo;
}
// Properties
-
+
+ internal bool UsesNtlmAuthentication {
+ get { return is_ntlm_auth; }
+ }
+
public string Accept {
get { return webHeaders ["Accept"]; }
set {
get { return allowBuffering; }
set { allowBuffering = value; }
}
+
+#if NET_2_0
+ static Exception GetMustImplement ()
+ {
+ return new NotImplementedException ();
+ }
+
+ [MonoTODO]
+ public DecompressionMethods AutomaticDecompression
+ {
+ get {
+ throw GetMustImplement ();
+ }
+ set {
+ throw GetMustImplement ();
+ }
+ }
+#endif
internal bool InternalAllowBuffering {
get {
- return (allowBuffering && (method == "PUT" || method == "POST"));
+ return (allowBuffering && (method != "HEAD" && method != "GET" &&
+ method != "MKCOL" && method != "CONNECT" &&
+ method != "DELETE" && method != "TRACE"));
}
}
return certificates;
}
+#if NET_2_0
+ [MonoTODO]
+ set {
+ throw GetMustImplement ();
+ }
+#endif
}
public string Connection {
get { return credentials; }
set { credentials = value; }
}
+
+#if NET_2_0
+ [MonoTODO]
+ public static new RequestCachePolicy DefaultCachePolicy
+ {
+ get {
+ throw GetMustImplement ();
+ }
+ set {
+ throw GetMustImplement ();
+ }
+ }
+
+ [MonoTODO]
+ public static int DefaultMaximumErrorResponseLength
+ {
+ get {
+ throw GetMustImplement ();
+ }
+ set {
+ throw GetMustImplement ();
+ }
+ }
+#endif
public string Expect {
get { return webHeaders ["Expect"]; }
get { return proxy; }
set {
CheckRequestStarted ();
+#if ONLY_1_1
if (value == null)
throw new ArgumentNullException ("value");
+#endif
proxy = value;
servicePoint = null; // we may need a new one
webHeaders.RemoveAndAdd ("Transfer-Encoding", value);
}
}
+
+#if NET_2_0
+ [MonoTODO]
+ public override bool UseDefaultCredentials
+ {
+ get {
+ throw GetMustImplement ();
+ }
+ set {
+ throw GetMustImplement ();
+ }
+ }
+#endif
public string UserAgent {
get { return webHeaders ["User-Agent"]; }
}
#if NET_1_1
- [MonoTODO]
+ bool unsafe_auth_blah;
public bool UnsafeAuthenticatedConnectionSharing
{
- get { throw new NotImplementedException (); }
- set { throw new NotImplementedException (); }
+ get { return unsafe_auth_blah; }
+ set { unsafe_auth_blah = value; }
}
#endif
if (aborted)
throw new WebException ("The request was previosly aborted.");
- bool send = !(method == "GET" || method == "CONNECT" || method == "HEAD");
+ bool send = !(method == "GET" || method == "CONNECT" || method == "HEAD" ||
+ method == "TRACE" || method == "DELETE");
if (method == null || !send)
throw new ProtocolViolationException ("Cannot send data when method is: " + method);
public override Stream GetRequestStream()
{
- IAsyncResult asyncResult = BeginGetRequestStream (null, null);
- asyncWrite = (WebAsyncResult) asyncResult;
+ IAsyncResult asyncResult = asyncWrite;
+ if (asyncResult == null) {
+ asyncResult = BeginGetRequestStream (null, null);
+ asyncWrite = (WebAsyncResult) asyncResult;
+ }
+
if (!asyncResult.AsyncWaitHandle.WaitOne (timeout, false)) {
Abort ();
throw new WebException ("The request timed out", WebExceptionStatus.Timeout);
return EndGetRequestStream (asyncResult);
}
-
+
+ void CheckIfForceWrite ()
+ {
+ if (writeStream == null || contentLength < 0 || !InternalAllowBuffering)
+ return;
+
+ // This will write the POST/PUT if the write stream already has the expected
+ // amount of bytes in it (ContentLength) (bug #77753).
+ if (writeStream.WriteBufferLength == contentLength)
+ writeStream.WriteRequest ();
+ }
+
public override IAsyncResult BeginGetResponse (AsyncCallback callback, object state)
{
bool send = (method == "PUT" || method == "POST");
"method while a previous call is still in progress.");
}
+ CheckIfForceWrite ();
asyncRead = new WebAsyncResult (this, callback, state);
+ WebAsyncResult aread = asyncRead;
initialMethod = method;
if (haveResponse) {
if (webResponse != null) {
Exception saved = saved_exc;
Monitor.Exit (this);
if (saved == null) {
- asyncRead.SetCompleted (true, webResponse);
+ aread.SetCompleted (true, webResponse);
} else {
- asyncRead.SetCompleted (true, saved);
+ aread.SetCompleted (true, saved);
}
- asyncRead.DoCallback ();
- return asyncRead;
+ aread.DoCallback ();
+ return aread;
}
}
}
Monitor.Exit (this);
- return asyncRead;
+ return aread;
}
public override WebResponse EndGetResponse (IAsyncResult asyncResult)
void ISerializable.GetObjectData (SerializationInfo serializationInfo,
StreamingContext streamingContext)
+ {
+ GetObjectData (serializationInfo, streamingContext);
+ }
+
+#if NET_2_0
+ protected override
+#endif
+ void GetObjectData (SerializationInfo serializationInfo,
+ StreamingContext streamingContext)
{
SerializationInfo info = serializationInfo;
return false;
*/
+ contentLength = 0;
+ bodyBufferLength = 0;
+ bodyBuffer = null;
+ method = "GET";
uriString = webResponse.Headers ["Location"];
break;
case HttpStatusCode.SeeOther: //303
{
bool continue100 = false;
if (contentLength != -1) {
- continue100 = true;
+ if (contentLength > 0)
+ continue100 = true;
webHeaders.SetInternal ("Content-Length", contentLength.ToString ());
webHeaders.RemoveInternal ("Transfer-Encoding");
} else if (sendChunked) {
expectContinue = false;
}
- string connectionHeader = (ProxyQuery) ? "Proxy-Connection" : "Connection";
- webHeaders.RemoveInternal ((!ProxyQuery) ? "Proxy-Connection" : "Connection");
- bool spoint10 = (servicePoint.ProtocolVersion == null ||
- servicePoint.ProtocolVersion == HttpVersion.Version10);
+ bool proxy_query = ProxyQuery;
+ string connectionHeader = (proxy_query) ? "Proxy-Connection" : "Connection";
+ webHeaders.RemoveInternal ((!proxy_query) ? "Proxy-Connection" : "Connection");
+ Version proto_version = servicePoint.ProtocolVersion;
+ bool spoint10 = (proto_version == null || proto_version == HttpVersion.Version10);
if (keepAlive && (version == HttpVersion.Version10 || spoint10)) {
webHeaders.RemoveAndAdd (connectionHeader, "keep-alive");
webHeaders.SetInternal ("Host", actualUri.Authority);
if (cookieContainer != null) {
- string cookieHeader = cookieContainer.GetCookieHeader (requestUri);
+ string cookieHeader = cookieContainer.GetCookieHeader (actualUri);
if (cookieHeader != "")
webHeaders.SetInternal ("Cookie", cookieHeader);
}
req.Append (GetHeaders ());
string reqstr = req.ToString ();
byte [] bytes = Encoding.UTF8.GetBytes (reqstr);
- writeStream.SetHeaders (bytes, 0, bytes.Length);
+ try {
+ writeStream.SetHeaders (bytes, 0, bytes.Length);
+ } catch (WebException wexc) {
+ SetWriteStreamError (wexc.Status);
+ } catch (Exception) {
+ SetWriteStreamError (WebExceptionStatus.SendFailure);
+ }
}
internal void SetWriteStream (WebConnectionStream stream)
contentLength = bodyBufferLength;
writeStream.SendChunked = false;
}
-
+
SendRequestHeaders ();
haveRequest = true;
writeStream.Write (bodyBuffer, 0, bodyBufferLength);
bodyBuffer = null;
writeStream.Close ();
- } else if (method == "PUT" || method == "POST") {
+ } else if (method == "PUT" || method == "POST" || method == "OPTIONS") {
if (getResponseCalled && !writeStream.RequestWritten)
writeStream.WriteRequest ();
}
void CheckSendError (WebConnectionData data)
{
// Got here, but no one called GetResponse
- if (data.StatusCode < 400)
+ int status = data.StatusCode;
+ if (status < 400 || status == 401 || status == 407)
return;
if (writeStream != null && asyncRead == null && !writeStream.CompleteRequestWritten) {
}
}
+ void HandleNtlmAuth (WebAsyncResult r)
+ {
+ WebConnectionStream wce = webResponse.GetResponseStream () as WebConnectionStream;
+ if (wce != null) {
+ WebConnection cnc = wce.Connection;
+ cnc.PriorityRequest = this;
+ bool isProxy = (proxy != null && !proxy.IsBypassed (actualUri));
+ ICredentials creds = (!isProxy) ? credentials : proxy.Credentials;
+ if (creds != null) {
+ cnc.NtlmCredential = creds.GetCredential (requestUri, "NTLM");
+#if NET_1_1
+ cnc.UnsafeAuthenticatedConnectionSharing = unsafe_auth_blah;
+#endif
+ }
+ }
+ r.Reset ();
+ haveResponse = false;
+ webResponse.ReadAll ();
+ webResponse = null;
+ }
+
internal void SetResponseData (WebConnectionData data)
{
if (aborted) {
try {
redirected = CheckFinalStatus (r);
if (!redirected) {
+ if (is_ntlm_auth && authCompleted && webResponse != null
+ && (int)webResponse.StatusCode < 400) {
+ WebConnectionStream wce = webResponse.GetResponseStream () as WebConnectionStream;
+ if (wce != null) {
+ WebConnection cnc = wce.Connection;
+ cnc.NtlmAuthenticated = true;
+ }
+ }
+
+ // clear internal buffer so that it does not
+ // hold possible big buffer (bug #397627)
+ if (writeStream != null)
+ writeStream.KillBuffer ();
+
r.SetCompleted (false, webResponse);
r.DoCallback ();
} else {
if (webResponse != null) {
+ if (is_ntlm_auth) {
+ HandleNtlmAuth (r);
+ return;
+ }
webResponse.Close ();
- webResponse = null;
}
haveResponse = false;
webResponse = null;
webHeaders [(isProxy) ? "Proxy-Authorization" : "Authorization"] = auth.Message;
authCompleted = auth.Complete;
+ is_ntlm_auth = (auth.Module.AuthenticationType == "NTLM");
return true;
}
WebExceptionStatus protoError = WebExceptionStatus.ProtocolError;
HttpStatusCode code = 0;
if (throwMe == null && webResponse != null) {
- code = webResponse.StatusCode;
+ code = webResponse.StatusCode;
if (!authCompleted && ((code == HttpStatusCode.Unauthorized && credentials != null) ||
- code == HttpStatusCode.ProxyAuthenticationRequired)) {
+ (ProxyQuery && code == HttpStatusCode.ProxyAuthenticationRequired))) {
if (!usedPreAuth && CheckAuthorization (webResponse, code)) {
// Keep the written body, so it can be rewritten in the retry
if (InternalAllowBuffering) {
bodyBuffer = writeStream.WriteBuffer;
bodyBufferLength = writeStream.WriteBufferLength;
- webResponse.Close ();
return true;
} else if (method != "PUT" && method != "POST") {
- webResponse.Close ();
return true;
}
string err = String.Format ("The remote server returned an error: ({0}) {1}.",
(int) code, webResponse.StatusDescription);
throwMe = new WebException (err, null, protoError, webResponse);
- } else if ((int) code >= 300 && allowAutoRedirect && redirects > maxAutoRedirect) {
+ } else if ((int) code >= 300 && allowAutoRedirect && redirects >= maxAutoRedirect) {
throwMe = new WebException ("Max. redirections exceeded.", null,
protoError, webResponse);
webResponse.ReadAll ();
if (throwMe == null) {
bool b = false;
int c = (int) code;
- if (allowAutoRedirect && c >= 300)
+ if (allowAutoRedirect && c >= 300) {
+ if (InternalAllowBuffering && writeStream.WriteBufferLength > 0) {
+ bodyBuffer = writeStream.WriteBuffer;
+ bodyBufferLength = writeStream.WriteBufferLength;
+ }
b = Redirect (result, code);
+ }
if (resp != null && c >= 300 && c != 304)
resp.ReadAll ();