masroore / CurlSharp

CurlSharp - .Net binding and object-oriented wrapper for libcurl.
BSD 3-Clause "New" or "Revised" License
182 stars 71 forks source link

The POST method not working CurlSharp #1

Closed http200it closed 9 years ago

http200it commented 10 years ago

The POST method not working CurlSharp. The same does not operate easy.PostFields> FileUpload.cs not working easy.HttpPost> BookPost.cs not working 64 Bit

masroore commented 10 years ago

Are you running Windows or Mono Linux/OSX? All the examples you've mentioned are working fine on my end. (Windows 8.1 x64). Make sure to copy the appropriate DLL for the environment (32/64 bit). To avoid further confusion, re-target the projects from "Any CPU" to the specific architecture of your choice.

http200it commented 10 years ago

Run on a Windows 2008 Standard R2 - 64 bit and Mono 3.8 GET method, a proxy for these systems work. The POST method does not send data to the program itself starts, but does not send. Built in this way Download> https://github.com/masroore/CurlSharp> Open project> CurlSharp> Debug> MixedPlatforms> Bulid Solutions

1> ------ Build started: Project: CurlSharp, Configuration: Debug Any CPU ------ 1> CurlSharp -> C:\Users\Administrator\Downloads\CurlSharp-master(1)\CurlSharp-master\CurlSharp\bin\Debug\CurlSharp.dll

I run the test program, and download the code works. POST does not work send in the 32 Bit and 64 Bit If possible, ask me about posting your CurlSharp.dll 64 bit that works well for you. Sorry for English writing by the translator

mangusta commented 10 years ago

Hi. I have similar problem with POST method. I wasn't able to send any data using CURLSHARP. My environment is Win 7 64 bit - compile via "Any CPU" and "x64".

This is my complete C# cod (I've change domain only):

using CurlSharp; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks;

namespace ConsoleApplication1 {

class Program
{

    static void Main(string[] args)
    {
        int bits = IntPtr.Size * 8;
        Console.WriteLine("Test curl {0} bit", bits);
        Curl.GlobalInit(CurlInitFlag.All);
        Console.WriteLine("Curl Version: {0}\n", Curl.Version);

        try
        {

            Console.WriteLine("\n========== TEST 1 CurlEasy Post ============");

            using (var easy = new CurlEasy())
            {

                easy.WriteFunction = OnWriteData;
                easy.WriteData = null;
                easy.PostFields = "parm1=value1&parm2=value2";
                easy.UserAgent = "MyUserAgent CurlEasy Post";
                easy.FollowLocation = true;
                easy.Url = "http://xxxxx.com/testpost.php";
                easy.Post = true;
                var code = easy.Perform();
            }

            Console.WriteLine("\n========== TEST 2 CurlEasy HttpPost ============");

            var mf = new CurlHttpMultiPartForm();
            mf.AddSection(CurlFormOption.CopyName, "parm1", CurlFormOption.CopyContents, "value1", CurlFormOption.End);
            mf.AddSection(CurlFormOption.CopyName, "parm2", CurlFormOption.CopyContents, "value2", CurlFormOption.End);
            using (var easy = new CurlEasy())
            {

                easy.WriteFunction = OnWriteData;
                easy.WriteData = null;
                easy.UserAgent = "MyUserAgent CurlEasy HttpPost";
                easy.FollowLocation = true;
                easy.Url = "http://xxxxx.com/testpost.php";
                easy.HttpPost = mf;
                var code = easy.Perform();
            }  

            Curl.GlobalCleanup();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex);
        }

        Console.WriteLine("\n========== TEST 3 HttpWebRequest ============");

        var request = (HttpWebRequest)WebRequest.Create("http://xxxxx.com/testpost.php");
        var data = Encoding.ASCII.GetBytes("parm1=value1&parm2=value2");
        request.UserAgent = "MyUserAgent HttpWebRequest";
        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.ContentLength = data.Length;

        using (var stream = request.GetRequestStream())
        {
            stream.Write(data, 0, data.Length);
        }

        var response = (HttpWebResponse)request.GetResponse();
        var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();

        Console.WriteLine(responseString);    
        Console.ReadLine();
    }

    public static Int32 OnWriteData(Byte[] buf, Int32 size, Int32 nmemb, Object extraData)
    {
        Console.Write(Encoding.UTF8.GetString(buf));
        return size * nmemb;
    }

    public static Int32 OnHeaderData(Byte[] buf, Int32 size, Int32 nmemb, Object extraData)
    {
        var userData = (string)extraData;
        Console.Write("->"+Encoding.UTF8.GetString(buf));
        return size * nmemb;
    }

    public static void OnDebug(CurlInfoType infoType, String msg, Object extraData)
    {
        // print out received data only
        if (infoType == CurlInfoType.DataIn)
            Console.WriteLine(msg);
    }

    public static void Testowuec()
    {

    }
}

}

And here are the results:

Test curl 64 bit Curl Version: libcurl/7.23.1 OpenSSL/1.0.1e zlib/1.2.8

========== TEST 1 CurlEasy Post ============ Array ( ) User-Agent: MyUserAgent CurlEasy Post Host: xxxxx.com Accept: / Content-Length: 1 Content-Type: application/x-www-form-urlencoded

========== TEST 2 CurlEasy HttpPost ============ Array ( ) User-Agent: MyUserAgent CurlEasy HttpPost Host: xxxxx.com Accept: / Content-Length: 0

========== TEST 3 HttpWebRequest ============ Array ( [parm1] => value1 [parm2] => value2 ) User-Agent: MyUserAgent HttpWebRequest Content-Type: application/x-www-form-urlencoded Host: xxxxx.com Content-Length: 25 Expect: 100-continue Connection: Keep-Alive

The POST receiver:

<?php print_r($_POST);

$headers = apache_request_headers(); foreach ($headers as $header => $value) { echo "$header: $value\n"; } ?>

As you can see only HttpWebRequest (TEST 3) sent POST data. I'm not sure is some problem with CurlSharp, my code or sth else...

masroore commented 10 years ago

@mangusta @http200it The POST bug has been fixed for WIN64. Please see the newly added EasyPost sample application.

Expected outputs:

64-bit build:

Test curl 64 bit
Curl Version: libcurl/7.38.0 OpenSSL/1.0.1g zlib/1.2.8 WinIDN libssh2/1.4.3

========== TEST 1 HttpWebRequest ============
User-Agent: HttpWebRequest
Content-Type: application/x-www-form-urlencoded
Host: localhost
Content-Length: 38
Expect: 100-continue
Connection: Keep-Alive

Array
(
    [parm1] => 12345
    [parm2] => "Hello world!"
)

========== TEST 2 CurlEasy PostFields ============
User-Agent: CurlEasy PostFields
Host: localhost
Accept: */*
Content-Length: 38
Content-Type: application/x-www-form-urlencoded

Array
(
    [parm1] => 12345
    [parm2] => "Hello world!"
)
Press <ENTER> to exit...

32-bit build utilizing libcurlshim.dll:

Test curl 32 bit
Curl Version: libcurl/7.38.0 OpenSSL/1.0.1g zlib/1.2.8 WinIDN libssh2/1.4.3

========== TEST 1 HttpWebRequest ============
User-Agent: HttpWebRequest
Content-Type: application/x-www-form-urlencoded
Host: localhost
Content-Length: 38
Expect: 100-continue
Connection: Keep-Alive

Array
(
    [parm1] => 12345
    [parm2] => "Hello world!"
)

========== TEST 2 CurlEasy PostFields ============
User-Agent: CurlEasy PostFields
Host: localhost
Accept: */*
Content-Length: 38
Content-Type: application/x-www-form-urlencoded

Array
(
    [parm1] => 12345
    [parm2] => "Hello world!"
)

========== TEST 3 CurlEasy HttpPost ============
User-Agent: CurlEasy HttpPost
Host: localhost
Accept: */*
Content-Length: 246
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------226a2f4ded940c61

Array
(
    [parm1] => value1
    [parm2] => value2
)
Press <ENTER> to exit...
http200it commented 10 years ago

Thank you very much for improving CurlSharp 64 bit for POST - PostFields. :-)

masroore commented 10 years ago

@http200it 32-bit build of CurlSharp uses the libcurlshim.dll helper library which was originally authored by Jeff Phillips. Unfortunately, this library was not ported to WIN64. I'm of little help in this regard as my C and assembly language skills are rusty. The CurlHttpMultiPartForm class is dependent on libcurlshim.dll and does not yet work in non-WIN32 builds.

http200it commented 10 years ago

@ masroore - It is important that it works the ability to send POST data under Linux 64 Bit Net MONO. The primary concern ;)

masroore commented 10 years ago

@http200it @mangusta Now the 64-bit HttpPost (multipart form-data) feature works without libcurlshim helper library.

Output from the EasyPost sample:

Test curl 64 bit
Curl Version: libcurl/7.38.0 OpenSSL/1.0.1g zlib/1.2.8 WinIDN libssh2/1.4.3

========== TEST 1 HttpWebRequest ============
User-Agent: HttpWebRequest
Content-Type: application/x-www-form-urlencoded
Host: localhost
Content-Length: 32
Expect: 100-continue
Connection: Keep-Alive

Array
(
    [parm1] => 12345
    [parm2] => Hello world!
)

========== TEST 2 CurlEasy PostFields ============
User-Agent: CurlEasy PostFields
Host: localhost
Accept: */*
Content-Length: 32
Content-Type: application/x-www-form-urlencoded

Array
(
    [parm1] => 12345
    [parm2] => Hello world!
)

========== TEST 3 CurlEasy HttpPost ============
User-Agent: CurlEasy HttpPost
Host: localhost
Accept: */*
Content-Length: 251
Expect: 100-continue
Content-Type: multipart/form-data; boundary=------------------------a61b6eaa416a1e00

Array
(
    [parm1] => 12345
    [parm2] => Hello world!
)

Press <ENTER> to exit...
http200it commented 10 years ago

It works by sending a POST easy.PostFields and easy.HttpPost on Windows 64 Bit and Linux Debian 7 64 Bit - Mono 3.8. Once again, thank you very much for improving the code.

@masroore - you are great ! -> Thank you :)

masroore commented 10 years ago

@http200it Thanks for confirming the fix on 64-bit Linux. I confirm the PostFields and HttpPost features work on OS X Xamarin as well.

http200it commented 10 years ago

Even setting the parameters works and does not work. I think it should work interchangeably so and so.

//easy.UserAgent = "Do UserAgent"; // Works easy.SetOpt(CurlOption.UserAgent, "Do UserAgent SetOpt"); // Does not work

//easy.Proxy = "xxx.xxx.xxx.xxx:21320"; // Works easy.SetOpt(CurlOption.Proxy, "xxx.xxx.xxx.xxx:21320"); // Does not work

//easy.PostFields = postData; // Works :) easy.SetOpt(CurlOption.PostFields, postData); // Does not work

//easy.Encoding = "gzip, deflate"; // Works easy.SetOpt(CurlOption.Encoding, "gzip, deflate"); // Does not work

easy.FollowLocation = true; // Works or easy.SetOpt(CurlOption.FollowLocation, true); // Works

At the time, please check yourself/

masroore commented 10 years ago

@http200it Thanks for reporting the bug. String options were not set properly in the setObjectOptions() method. Issue #2 is now fixed.

http200it commented 10 years ago

@masroore - Now the function easy.SetOpt (CurlOption. **, ***); works as it should. Tested on Windows 64bit and Linix 64bit mono. Thanks again for the quick improvement and help :-)

mangusta commented 10 years ago

@masroore thank you very much for your intervention and for whole great job! It's working now. All the best!

hieple commented 9 years ago

Love curl and this .NET port.

However, I try to set option easy.SetOpt(CurlOption.HttpHeader, "application/soap+xml; charset=utf-8");

but it always shows content-type: application/x-www-form-urlencoded

masroore commented 9 years ago

@hieple Are you trying to set the content-type header? You can use the ContentType property:

easy.ContentType = "application/soap+xml; charset=utf-8";

FYI, CurlOption.HttpHeader takes a linked list of strings.

hieple commented 9 years ago

But easy.ContentType is read-only

masroore commented 9 years ago

@hieple I stand corrected, ContentType is applicable only to the response from web server. I could not find any easy way to set the content-type header on the request. You'll need to construct the HTTP header manually:

var headers = new CurlSlist();
headers.Append("Content-Type: application/soap+xml; charset=utf-8");
easy.HttpHeader = headers;
http200it commented 9 years ago

Hello again. It does not work to send a file or send wrong? My test code: string avatar = Application.StartupPath + @"\avatary\myface.jpg"; var mf = new CurlHttpMultiPartForm(); mf.AddSection(CurlFormOption.CopyName, "parm1", CurlFormOption.CopyContents, "value1", CurlFormOption.End); mf.AddSection(CurlFormOption.CopyName, "parm2", CurlFormOption.CopyContents, "value2", CurlFormOption.End); if (File.Exists(avatar)) { mf.AddSection(CurlFormOption.CopyName, "uploadedfile", CurlFormOption.File, avatar, CurlFormOption.ContentType, "application/octet-stream", CurlFormOption.End); Console.WriteLine(avatar); } easy.HttpPost = mf;

<?php // dotetspostfile.php print_r($_POST); print_r($_FILES);

$headers = apache_request_headers();

foreach ($headers as $header => $value) { echo "$header: $value \r\n"; } ?>

My OUT: Array ( [parm1] => value1 [parm2] => value2 ) Array ( ) Host: www.testsite.com Connection: close Content-Length: 246 User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:22.0) Gecko/20100101 Firefox/22.0 Accept-Encoding: gzip,deflate Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8 Accept-Language: pl,en-us;q=0.7,en;q=0.3 Cache-Control: max-age=0 Pragma: no-cache Content-Type: multipart/form-data; boundary=------------------------e489e380b38b4322