public static bool SetOpt(PhpResource ch, CurlOption option, object value) { PhpCurlResource curlHandle = ch as PhpCurlResource; if (curlHandle == null) { return(false); } bool valid = false; value = option.ValidateAndConvert(value, out valid); if (valid) { curlHandle.Data.SetOption(option, value); return(true); } //exceptions: else if (option == CurlOption.CURLOPT_POSTFIELDS) { //ValidateAndConvert checks just for string // this option can be also array or object if (value != null && value.GetType() == typeof(PhpArray)) { PhpArray arr = (PhpArray)value; var form = CurlForm.Create(arr); curlHandle.Data.SetOption(CurlOption.CURLOPT_HTTPPOST, form); } } return(false); }
internal PhpCurlResource NextCompleted() { PhpCurlResource result = _results.Where(a => a.Value.IsCompleted && !_returned.Contains(a.Key)).Select(a => a.Key).FirstOrDefault(); if (result != null) { _returned.Add(result); } return(result); }
public static void Close(PhpResource ch) { PhpCurlResource curlHandle = ch as PhpCurlResource; if (curlHandle == null) { return; } curlHandle.Close(); }
public static object GetInfo(PhpResource ch, CurlInfo option) { PhpCurlResource curlHandle = ch as PhpCurlResource; if (curlHandle == null) { return(false); } return(curlHandle.GetInfo(option)); }
public static object Errno(PhpResource ch) { //PhpException.FunctionNotSupported(PhpError.Warning); PhpCurlResource curlHandle = ch as PhpCurlResource; if (curlHandle == null) { return(null); } return((int)curlHandle.ErrorCode); }
public static object Execute(PhpResource ch) { //PhpException.FunctionNotSupported(PhpError.Warning); PhpCurlResource curlHandle = ch as PhpCurlResource; if (curlHandle == null) { return(false); } return(curlHandle.Execute()); }
internal static void InvokeHeaderFunction(this HttpWebResponse response, PhpCurlResource curlResource, PhpCallback headerFunction) { StringBuilder builder = new StringBuilder(HTTP_HEADER_ROW_LENGTH); int startIndex = 0; IterateHtppHeaders(response, ref builder, delegate(ref StringBuilder sb) { headerFunction.Invoke(curlResource, sb.ToString(startIndex, sb.Length - startIndex)); startIndex = sb.Length; } ); }
internal void StartIfNeeded() { if (_started) { return; } _started = true; foreach (PhpCurlResource res in _resources) { PhpCurlResource res1 = res; Func <object> func = () => Curl.Execute(res1); var task = new Task <object>(func); task.Start(); _results.Add(res1, task); } }
public static string Error(PhpResource ch) { PhpCurlResource curlHandle = ch as PhpCurlResource; if (curlHandle == null) { return(null); } switch (curlHandle.ErrorCode) { case CURLcode.CURLE_OPERATION_TIMEOUTED: return("Connection time-out"); case CURLcode.CURLE_COULDNT_CONNECT: return("couldn't connect to host"); default: return(""); } }
internal void Remove(PhpCurlResource resource) { _resources.Remove(resource); }
internal object GetResult(PhpCurlResource handle) { return(_results[handle].Result); }
internal void Add(PhpCurlResource res) { _resources.Add(res); res.MultiParent = this; }
/// <summary> /// Execute is modified Curl_http() which in Curl gets called from the generic Curl_do() function when a HTTP /// request is to be performed. This creates and sends a properly constructed /// HTTP request. /// </summary> /// <param name="curl"></param> /// <param name="result"></param> /// <returns></returns> internal override object Execute(PhpCurlResource curl, ref CURLcode result) { UserDefined data = curl.Data; HttpBitsUploader uploader; bool terminatedCorrectly = false; int redirectAttempts = 0; bool keepVerb = false; result = CURLcode.CURLE_OK; if (data.Str[(int)DupString.SET_URL] == null) { result = CURLcode.CURLE_COULDNT_CONNECT; return(false); } Uri uri = Utils.CompleteUri(PhpVariable.AsString(data.Str[(int)DupString.SET_URL]), Scheme, data.UsePort); for (; ;) { request = (HttpWebRequest)HttpWebRequest.Create(uri); Curl_HttpReq httpreq = (redirectAttempts == 0) || keepVerb?setRequestMethod(data) : Curl_HttpReq.GET; setTimeOut(data); setHttpVersion(data); request.AllowAutoRedirect = data.FollowLocation; request.MaximumAutomaticRedirections = data.MaxRedirects; if (data.Str[(int)DupString.USERAGENT] != null) { request.UserAgent = PhpVariable.AsString(data.Str[(int)DupString.USERAGENT]); } if (data.Str[(int)DupString.SET_REFERER] != null) { request.Referer = PhpVariable.AsString(data.Str[(int)DupString.SET_REFERER]); } if (data.Headers != null) { request.SetHttpHeaders(data.Headers); } setProxy(data); setCredentials(data); setCookies(data); //ssl.VerifyPeer && ssl.VerifyHost == 2 is supported by default .NET // other values are currently unsupported if (data.Str[(int)DupString.CERT] != null) { X509Certificate cert; string certPath; try { certPath = Path.Combine(ScriptContext.CurrentContext.WorkingDirectory, PhpVariable.AsString(data.Str[(int)DupString.SSL_CAFILE])); if (data.Str[(int)DupString.KEY_PASSWD] == null) { cert = new X509Certificate(certPath); } else { cert = new X509Certificate(certPath, PhpVariable.AsString(data.Str[(int)DupString.KEY_PASSWD])); } request.ClientCertificates.Add(cert); } catch (CryptographicException) { //TODO: here are more caises to differentiate result = CURLcode.CURLE_SSL_CACERT_BADFILE; return(false); } } switch (httpreq) { case Curl_HttpReq.POST_FORM: //same as POST but we can send multiple items asform-data if (data.HttpPostForm != null) { try { HttpFormDataUploader formUploader = new HttpFormDataUploader(request); formUploader.UploadForm(data.HttpPostForm); } catch (WebException ex) { switch (ex.Status) { case WebExceptionStatus.Timeout: result = CURLcode.CURLE_OPERATION_TIMEOUTED; break; default: result = CURLcode.CURLE_COULDNT_CONNECT; // for now just this break; } return(false); } } break; case Curl_HttpReq.PUT: /* Let's PUT the data to the server! */ //INFILE & INFILESIZE has to be set NativeStream nativeStream = data.Infile as NativeStream; if (nativeStream == null) { return(false); } FileStream fs = nativeStream.RawStream as FileStream; if (fs == null) { return(false); } try { uploader = new HttpBitsUploader(request); uploader.UploadFile(fs); } catch (WebException ex) { switch (ex.Status) { case WebExceptionStatus.Timeout: result = CURLcode.CURLE_OPERATION_TIMEOUTED; break; default: result = CURLcode.CURLE_COULDNT_CONNECT; // for now just this break; } return(false); } break; case Curl_HttpReq.POST: /* this is the simple POST, using x-www-form-urlencoded style */ if (String.IsNullOrEmpty(request.ContentType)) // if Content-type isn't set set the default { request.ContentType = "application/x-www-form-urlencoded"; } if (data.Postfields != null) { try { uploader = new HttpBitsUploader(request); uploader.UploadData(data.Postfields); } catch (WebException ex) { switch (ex.Status) { case WebExceptionStatus.Timeout: result = CURLcode.CURLE_OPERATION_TIMEOUTED; break; default: result = CURLcode.CURLE_COULDNT_CONNECT; // for now just this break; } return(false); } } break; } try { // if we got this far, we will turn off AutoRedirect (assuming it was on), since // we are ready to handle manually following certain responses. this is needed // to harvest cookies that are set on any intermediate response (i.e. anything // other than the last one followed), since the .NET HTTP class will use, but // NOT return, cookies set on anything but the last request. request.AllowAutoRedirect = false; response = (HttpWebResponse)request.GetResponse(); } catch (WebException ex) { switch (ex.Status) { case WebExceptionStatus.Timeout: result = CURLcode.CURLE_OPERATION_TIMEOUTED; break; case WebExceptionStatus.ConnectFailure: result = CURLcode.CURLE_COULDNT_CONNECT; break; case WebExceptionStatus.TrustFailure: result = CURLcode.CURLE_SSL_CACERT; break; case WebExceptionStatus.ProtocolError: //Response from server was complete, but indicated protocol error as 404, 401 etc. break; default: result = CURLcode.CURLE_COULDNT_CONNECT; // for now just this break; } //TODO: other errorCodes response = (HttpWebResponse)ex.Response; //return false; //error = true; } if (response == null)// just to make sure I have the response object { return(false); } if (data.FollowLocation) { // see if we need to follow a redirect. switch (response.StatusCode) { case HttpStatusCode.MovedPermanently: case HttpStatusCode.Found: case HttpStatusCode.SeeOther: case HttpStatusCode.RedirectKeepVerb: if (redirectAttempts++ >= data.MaxRedirects) { result = CURLcode.CURLE_TOO_MANY_REDIRECTS; return(false); } string location = response.Headers["Location"]; if (!string.IsNullOrWhiteSpace(location)) { try { keepVerb = response.StatusCode == HttpStatusCode.RedirectKeepVerb; data.Cookies.Add(response.Cookies); response.Close(); uri = new Uri(uri, location); continue; } catch (Exception) { // closest error code though could be confusing as it's not the user- // submitted URL that's the problem result = CURLcode.CURLE_URL_MALFORMAT; return(false); } } break; } } //Save cookies data.Cookies.Add(response.Cookies); // break out of the for loop as we aren't following a redirect break; } byte[] headers = null; byte[] content = null; int headersLength = 0; if (data.IncludeHeader) { //It's necessary to put HTTP header into the result //first we need to create it since there isn't anywhere headers = Encoding.ASCII.GetBytes(response.GetHttpHeaderAsString()); headersLength = headers.Length; } if (data.FunctionWriteHeader != null)// TODO: probably invoke before { response.InvokeHeaderFunction(curl, data.FunctionWriteHeader); } Stream writeStream = null; if (data.WriteFunction != null) { writeStream = new WriteFunctionStream(curl, data.WriteFunction); } else if (data.OutFile != null) { var outStream = data.OutFile as PhpStream; if (outStream == null) { return(false); } Stream fs = outStream.RawStream as Stream; if (fs == null) { return(false); } writeStream = fs; } else if (data.ReturnTransfer == false) // Output to standart output { writeStream = ScriptContext.CurrentContext.OutputStream; } if (writeStream != null) { if (headers != null) //there is http header to copy to the result { writeStream.Write(headers, 0, headersLength); } HttpBitsDownloader reader = new HttpBitsDownloader(response); try { reader.ReadToStream(writeStream, out terminatedCorrectly); } catch (WebException ex) { switch (ex.Status) { case WebExceptionStatus.Timeout: result = CURLcode.CURLE_OPERATION_TIMEOUTED; break; default: result = CURLcode.CURLE_COULDNT_CONNECT; // for now just this break; } } if (!terminatedCorrectly) { result = CURLcode.CURLE_PARTIAL_FILE; } return(true); } else { // Read the response HttpBitsDownloader reader = new HttpBitsDownloader(response); try { content = reader.ReadToEnd(headersLength, out terminatedCorrectly); } catch (WebException ex) { switch (ex.Status) { case WebExceptionStatus.Timeout: result = CURLcode.CURLE_OPERATION_TIMEOUTED; break; default: result = CURLcode.CURLE_COULDNT_CONNECT; // for now just this break; } } if (!terminatedCorrectly) { result = CURLcode.CURLE_PARTIAL_FILE; } if (headers != null) //there is http header to copy to the result { if (content != null) { Buffer.BlockCopy(headers, 0, content, 0, headersLength); } else { content = headers; } } if (content == null) { return(PhpBytes.Empty); } else { return(new PhpBytes(content)); } } }
public WriteFunctionStream(PhpCurlResource curl,PhpCallback writeFunction) { this.curl = curl; this.writeFunction = writeFunction; }
/// <summary> /// Execute is modified Curl_http() which in Curl gets called from the generic Curl_do() function when a HTTP /// request is to be performed. This creates and sends a properly constructed /// HTTP request. /// </summary> /// <param name="curl"></param> /// <param name="result"></param> /// <returns></returns> internal override object Execute(PhpCurlResource curl, ref CURLcode result) { UserDefined data = curl.Data; HttpBitsUploader uploader; bool terminatedCorrectly = false; int redirectAttempts = 0; bool keepVerb = false; result = CURLcode.CURLE_OK; if (data.Str[(int)DupString.SET_URL] == null) { result = CURLcode.CURLE_COULDNT_CONNECT; return false; } Uri uri = Utils.CompleteUri(PhpVariable.AsString(data.Str[(int)DupString.SET_URL]), Scheme, data.UsePort); for (; ; ) { request = (HttpWebRequest)HttpWebRequest.Create(uri); Curl_HttpReq httpreq = (redirectAttempts == 0) || keepVerb ? setRequestMethod(data) : Curl_HttpReq.GET; setTimeOut(data); setHttpVersion(data); request.AllowAutoRedirect = data.FollowLocation; request.MaximumAutomaticRedirections = data.MaxRedirects; if (data.Str[(int)DupString.USERAGENT] != null) request.UserAgent = PhpVariable.AsString(data.Str[(int)DupString.USERAGENT]); if (data.Str[(int)DupString.SET_REFERER] != null) request.Referer = PhpVariable.AsString(data.Str[(int)DupString.SET_REFERER]); if (data.Headers != null) request.SetHttpHeaders(data.Headers); setProxy(data); setCredentials(data); setCookies(data); //ssl.VerifyPeer && ssl.VerifyHost == 2 is supported by default .NET // other values are currently unsupported if (data.Str[(int)DupString.CERT] != null) { X509Certificate cert; string certPath; try { certPath = Path.Combine(ScriptContext.CurrentContext.WorkingDirectory, PhpVariable.AsString(data.Str[(int)DupString.SSL_CAFILE])); if (data.Str[(int)DupString.KEY_PASSWD] == null) cert = new X509Certificate(certPath); else cert = new X509Certificate(certPath, PhpVariable.AsString(data.Str[(int)DupString.KEY_PASSWD])); request.ClientCertificates.Add(cert); } catch (CryptographicException) { //TODO: here are more caises to differentiate result = CURLcode.CURLE_SSL_CACERT_BADFILE; return false; } } switch (httpreq) { case Curl_HttpReq.POST_FORM: //same as POST but we can send multiple items asform-data if (data.HttpPostForm != null) { try { HttpFormDataUploader formUploader = new HttpFormDataUploader(request); formUploader.UploadForm(data.HttpPostForm); } catch (WebException ex) { switch (ex.Status) { case WebExceptionStatus.Timeout: result = CURLcode.CURLE_OPERATION_TIMEOUTED; break; default: result = CURLcode.CURLE_COULDNT_CONNECT;// for now just this break; } return false; } } break; case Curl_HttpReq.PUT: /* Let's PUT the data to the server! */ //INFILE & INFILESIZE has to be set NativeStream nativeStream = data.Infile as NativeStream; if (nativeStream == null) return false; FileStream fs = nativeStream.RawStream as FileStream; if (fs == null) return false; try { uploader = new HttpBitsUploader(request); uploader.UploadFile(fs); } catch (WebException ex) { switch (ex.Status) { case WebExceptionStatus.Timeout: result = CURLcode.CURLE_OPERATION_TIMEOUTED; break; default: result = CURLcode.CURLE_COULDNT_CONNECT;// for now just this break; } return false; } break; case Curl_HttpReq.POST: /* this is the simple POST, using x-www-form-urlencoded style */ if (String.IsNullOrEmpty(request.ContentType))// if Content-type isn't set set the default request.ContentType = "application/x-www-form-urlencoded"; if (data.Postfields != null) { try { uploader = new HttpBitsUploader(request); uploader.UploadData(data.Postfields); } catch (WebException ex) { switch (ex.Status) { case WebExceptionStatus.Timeout: result = CURLcode.CURLE_OPERATION_TIMEOUTED; break; default: result = CURLcode.CURLE_COULDNT_CONNECT;// for now just this break; } return false; } } break; } try { // if we got this far, we will turn off AutoRedirect (assuming it was on), since // we are ready to handle manually following certain responses. this is needed // to harvest cookies that are set on any intermediate response (i.e. anything // other than the last one followed), since the .NET HTTP class will use, but // NOT return, cookies set on anything but the last request. request.AllowAutoRedirect = false; response = (HttpWebResponse)request.GetResponse(); } catch (WebException ex) { switch (ex.Status) { case WebExceptionStatus.Timeout: result = CURLcode.CURLE_OPERATION_TIMEOUTED; break; case WebExceptionStatus.ConnectFailure: result = CURLcode.CURLE_COULDNT_CONNECT; break; case WebExceptionStatus.TrustFailure: result = CURLcode.CURLE_SSL_CACERT; break; case WebExceptionStatus.ProtocolError: //Response from server was complete, but indicated protocol error as 404, 401 etc. break; default: result = CURLcode.CURLE_COULDNT_CONNECT;// for now just this break; } //TODO: other errorCodes response = (HttpWebResponse)ex.Response; //return false; //error = true; } if (response == null)// just to make sure I have the response object return false; if (data.FollowLocation) { // see if we need to follow a redirect. switch (response.StatusCode) { case HttpStatusCode.MovedPermanently: case HttpStatusCode.Found: case HttpStatusCode.SeeOther: case HttpStatusCode.RedirectKeepVerb: if (redirectAttempts++ >= data.MaxRedirects) { result = CURLcode.CURLE_TOO_MANY_REDIRECTS; return false; } string location = response.Headers["Location"]; if (!string.IsNullOrWhiteSpace(location)) { try { keepVerb = response.StatusCode == HttpStatusCode.RedirectKeepVerb; data.Cookies.Add(response.Cookies); response.Close(); uri = new Uri(uri, location); continue; } catch (Exception) { // closest error code though could be confusing as it's not the user- // submitted URL that's the problem result = CURLcode.CURLE_URL_MALFORMAT; return false; } } break; } } //Save cookies data.Cookies.Add(response.Cookies); // break out of the for loop as we aren't following a redirect break; } byte[] headers = null; byte[] content = null; int headersLength = 0; if (data.IncludeHeader) { //It's necessary to put HTTP header into the result //first we need to create it since there isn't anywhere headers = Encoding.ASCII.GetBytes(response.GetHttpHeaderAsString()); headersLength = headers.Length; } if (data.FunctionWriteHeader != null)// TODO: probably invoke before { response.InvokeHeaderFunction(curl, data.FunctionWriteHeader); } Stream writeStream = null; if (data.WriteFunction != null) { writeStream = new WriteFunctionStream(curl, data.WriteFunction); } else if (data.OutFile != null) { var outStream = data.OutFile as PhpStream; if (outStream == null) return false; Stream fs = outStream.RawStream as Stream; if (fs == null) return false; writeStream = fs; } else if (data.ReturnTransfer == false) // Output to standart output { writeStream = ScriptContext.CurrentContext.OutputStream; } if (writeStream != null) { if (headers != null) //there is http header to copy to the result { writeStream.Write(headers, 0, headersLength); } HttpBitsDownloader reader = new HttpBitsDownloader(response); try { reader.ReadToStream(writeStream, out terminatedCorrectly); } catch (WebException ex) { switch (ex.Status) { case WebExceptionStatus.Timeout: result = CURLcode.CURLE_OPERATION_TIMEOUTED; break; default: result = CURLcode.CURLE_COULDNT_CONNECT;// for now just this break; } } if (!terminatedCorrectly) result = CURLcode.CURLE_PARTIAL_FILE; return true; } else { // Read the response HttpBitsDownloader reader = new HttpBitsDownloader(response); try { content = reader.ReadToEnd(headersLength, out terminatedCorrectly); } catch(WebException ex) { switch (ex.Status) { case WebExceptionStatus.Timeout: result = CURLcode.CURLE_OPERATION_TIMEOUTED; break; default: result = CURLcode.CURLE_COULDNT_CONNECT;// for now just this break; } } if (!terminatedCorrectly) result = CURLcode.CURLE_PARTIAL_FILE; if (headers != null) //there is http header to copy to the result { if (content != null) Buffer.BlockCopy(headers, 0, content, 0, headersLength); else content = headers; } if (content == null) return PhpBytes.Empty; else return new PhpBytes(content); } }
internal abstract object Execute(PhpCurlResource curl, ref CURLcode result);
internal object GetResult(PhpCurlResource handle) { return _results[handle].Result; }
public WriteFunctionStream(PhpCurlResource curl, PhpCallback writeFunction) { this.curl = curl; this.writeFunction = writeFunction; }