CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 7 of 7
  1. #1
    Join Date
    Aug 2002
    Posts
    757

    [SOLVED]VB + ASP -> C++ + libCURL

    Hi, ALL,
    I am trying to convert VB code to the C++ and libCURL.

    Here is the server part in asp:

    Default.aspx
    Code:
    <%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
    
        <div>
        <form id="Form2" Method="Post" EncType="Multipart/Form-Data" RunAt="Server">
    
       <%-- The File upload Html control --%>
       Choose Your File  To Upload <BR>
       <Input Name="MyFile" id="MyFile" Type="File" RunAt="Server">
       <BR>
    
       <%-- A button - when clicked the form is submitted and the
                Upload_Click event handler is fired... --%>
       <Input id="Submit1" Type="Submit" Value="Upload" 
                 RunAt="Server">
       
        </form> </div>
    </body>
    </html>
    Default.aspx.vb
    Code:
    Imports System.IO
    
    Partial Class _Default
    
        Inherits System.Web.UI.Page
        Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            'If Page.IsPostBack Then
            'Grab the file name from its fully qualified path at client 
            Dim strFileName As String = MyFile.PostedFile.FileName
            'Response.Write(strFileName)
            ' only the attched file name not its path
            Dim c As String = System.IO.Path.GetFileName(strFileName)
    
            'Save uploaded file to server at C:\ServerFolder\
            Try
                MyFile.PostedFile.SaveAs("C:\inetpub\wwwroot\<my_path>\files\" + c)
    
            Catch Exp As Exception
    
            End Try
    And here is the relevant part of the client code:

    Code:
            HttpUploadFile("http://xxx.xxx.xxx.xxx/<my_path>/Default.aspx", "C:\temp\12345 .bmp", "MyFile", "image/bitmap")
    
    Private Sub HttpUploadFile( _
        ByVal uri As String, _
        ByVal filePath As String, _
        ByVal fileParameterName As String, _
        ByVal contentType As String)
            'ByVal otherParameters As Specialized.NameValueCollection)
    
            ' This routine takes the locally generated image and uploads it using HTTP Post data
            Dim boundary As String = "---------------------------" & DateTime.Now.Ticks.ToString("x")
            Dim newLine As String = System.Environment.NewLine
            Dim boundaryBytes As Byte() = System.Text.Encoding.ASCII.GetBytes(newLine & "--" & boundary & newLine)
            Dim request As Net.HttpWebRequest = Net.WebRequest.Create(uri)
    
            request.ContentType = "multipart/form-data; boundary=" & boundary
            request.Method = "POST"
            request.KeepAlive = True
            request.Credentials = Net.CredentialCache.DefaultCredentials
    
            Using requestStream As IO.Stream = request.GetRequestStream()
                Dim headerTemplate As String = "Content-Disposition: form-data; name=""{0}""; filename=""{1}""{2}Content-Type: {3}{2}{2}"
                Dim header As String = String.Format(headerTemplate, fileParameterName, filePath, newLine, contentType)
                Dim headerBytes As Byte() = System.Text.Encoding.UTF8.GetBytes(header)
                requestStream.Write(headerBytes, 0, headerBytes.Length)
    However using libCURL I'm getting the "Object reference is not set to an instance of the object", because the server code does not have "MyFile = new InputText" line. I was told from the author that "MyFile" object has been created on the client side by the "headerTemplate" variable.

    Is libCURL capable of doing something like this?

    Here is my code in C++/wxWidgets/libCURL:

    Code:
    	CURLcode error;
    	char errorMsg[1024];
    	struct curl_httppost *first = NULL, *last = NULL;
    	struct curl_slist *post = NULL;
                  wxString header = wxString::Format( "Content-Disposition: form-data; name=\"MyFile\"; filename=\"%s\"", filename;
                  post = curl_slist_append( post, (const char *) header.c_str() );
    	post = curl_slist_append( post, "Content-Type: image/bitmap" );
    	curl_formadd( &first, &last, CURLFORM_COPYNAME, "name", CURLFORM_FILE, (const char *) fileName.c_str(), CURLFORM_END );
    	curl_formadd( &first, &last, CURLFORM_COPYNAME, "filename", CURLFORM_COPYCONTENTS, (const char *) fileName.c_str(), CURLFORM_END );
    	curl_formadd(&first,  &last, CURLFORM_COPYNAME, "submit", CURLFORM_COPYCONTENTS, "send", CURLFORM_END );
    	CURL *handle = wxGetApp().GetCurlHandle();
    	FILE *fp = fopen( "session.log", "w+" );
    	curl_easy_setopt( handle, CURLOPT_VERBOSE, 1L );
    	curl_easy_setopt( handle, CURLOPT_HEADER, 1L );
    	curl_easy_setopt( handle, CURLOPT_STDERR, fp );
    	curl_easy_setopt( handle, CURLOPT_ERRORBUFFER, errorMsg );
    	curl_easy_setopt( handle, CURLOPT_URL, "http://xxx.xxx.xxx.xxx/<my_path>/Default.aspx" );
                  curl_easy_setopt( handle, CURLOPT_HTTPPOST, first );
    	curl_easy_setopt( handle, CURLOPT_HTTPHEADER, post );
    	error = curl_easy_perform( handle );
    	curl_slist_free_all( post );
    	curl_formfree( first );
                  curl_easy_setopt( handle, CURLOPT_HTTPPOST, NULL );
    	curl_easy_setopt( handle, CURLOPT_HTTPHEADER, NULL );
    	curl_easy_setopt( handle, CURLOPT_HTTPGET, 1L );
    	curl_easy_setopt( handle, CURLOPT_WRITEFUNCTION, CWindowPanel::get_data );
    	curl_easy_setopt( handle, CURLOPT_WRITEDATA, &m_stringToRead );
    	error = curl_easy_perform( handle );
    	curl_easy_setopt( handle, CURLOPT_WRITEFUNCTION, NULL );
    	curl_easy_setopt( handle, CURLOPT_WRITEDATA, NULL );
    What am I doing wrong?

    Thank you.
    Last edited by OneEyeMan; July 28th, 2012 at 01:17 PM. Reason: Mark as solved

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: VB + ASP -> C++ + libCURL

    Quote Originally Posted by OneEyeMan View Post
    What am I doing wrong?
    You don't check any of those functions to see if they returned successful or not. If a function is documented to return a value to determine its success or failure, then you need to test the return value. You are potentially missing the answer to your questions when you fail to check return values.

    You don't even check if the fopen() is successful:
    Code:
    	FILE *fp = fopen( "session.log", "w+" );
            //..
    	curl_easy_setopt( handle, CURLOPT_STDERR, fp );
    What hapeens if that file couldn't be opened? Where is the check if fp is NULL?

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; July 24th, 2012 at 08:39 PM.

  3. #3
    Join Date
    Aug 2002
    Posts
    757

    Re: VB + ASP -> C++ + libCURL

    Paul,
    I added necessary checks. Everything is fine. File is opened and parameters are added.
    The problem seems to be that the furst curl_easy_perform() return "Error 23: Failed writing a body".

    My guess is that this is because the server throws an exception I was talking about and it is not possible to finish the transfer.

    Is it possible that CURL don't know when and how to make an ASP object on demand?

    Here is the modified version for reference.

    Code:
    	wxString header = wxString::Format( "Content-Disposition: form-data; name=\"MyFile\"; filename=\"%s\"", fileName );
    	Speech *speech = wxGetApp().GetSpeechObject();
    	post = curl_slist_append( post, (const char *) header.c_str() );
    	if( !post )
    	{
    		speech->Speak( "Can't generate an appropriate header. Exiting!" );
    		return;
    	}
    	post = curl_slist_append( post, "Content-Type: image/bitmap" );
    	if( !post )
    	{
    		speech->Speak( "Can't set content type" );
    		curl_slist_free_all( post );
    		return;
    	}
    	result = curl_formadd( &first, &last, CURLFORM_COPYNAME, "name", CURLFORM_FILE, (const char *) fileName.c_str(), CURLFORM_END );
    	result = curl_formadd( &first, &last, CURLFORM_COPYNAME, "filename", CURLFORM_COPYCONTENTS, (const char *) fileName.c_str(), CURLFORM_CONTENTHEADER, post, CURLFORM_END );
    	result = curl_formadd(&first,  &last, CURLFORM_COPYNAME, "submit", CURLFORM_COPYCONTENTS, "send", CURLFORM_END );
    	if( result )
    	{
    		speech->Speak( "Can't form the query to tesseract service" );
    		curl_slist_free_all( post );
    		curl_formfree( first );
    		return;
    	}
    	CURL *handle = wxGetApp().GetCurlHandle();
    	FILE *fp = fopen( "session.log", "w+" );
    	if( !fp )
    	{
    		speech->Speak( "Can't create log file" );
    		curl_slist_free_all( post );
    		curl_formfree( first );
    		return;
    	}
    	curl_easy_setopt( handle, CURLOPT_VERBOSE, 1L );
    	curl_easy_setopt( handle, CURLOPT_HEADER, 1L );
    	curl_easy_setopt( handle, CURLOPT_STDERR, fp );
    	curl_easy_setopt( handle, CURLOPT_ERRORBUFFER, errorMsg );
    	curl_easy_setopt( handle, CURLOPT_URL, "http://174.122.236.154/TouchAndRead/Default.aspx" );
                  curl_easy_setopt( handle, CURLOPT_HTTPPOST, first );
    	error = curl_easy_perform( handle );
    	if( !error )
    	{
    		speech->Speak( errorMsg );
    		curl_slist_free_all( post );
    		curl_formfree( first );
    		return;
    	}

  4. #4
    Join Date
    Aug 2002
    Posts
    757

    Re: VB + ASP -> C++ + libCURL

    Paul,
    I added necessary checks. Everything is fine. File is opened and parameters are added.
    The problem seems to be that the furst curl_easy_perform() return "Error 23: Failed writing a body".

    My guess is that this is because the server throws an exception I was talking about and it is not possible to finish the transfer.

    Is it possible that CURL don't know when and how to make an ASP object on demand?

    Here is the modified version for reference.

    Code:
    	wxString header = wxString::Format( "Content-Disposition: form-data; name=\"MyFile\"; filename=\"%s\"", fileName );
    	Speech *speech = wxGetApp().GetSpeechObject();
    	post = curl_slist_append( post, (const char *) header.c_str() );
    	if( !post )
    	{
    		speech->Speak( "Can't generate an appropriate header. Exiting!" );
    		return;
    	}
    	post = curl_slist_append( post, "Content-Type: image/bitmap" );
    	if( !post )
    	{
    		speech->Speak( "Can't set content type" );
    		curl_slist_free_all( post );
    		return;
    	}
    	result = curl_formadd( &first, &last, CURLFORM_COPYNAME, "name", CURLFORM_FILE, (const char *) fileName.c_str(), CURLFORM_END );
    	result = curl_formadd( &first, &last, CURLFORM_COPYNAME, "filename", CURLFORM_COPYCONTENTS, (const char *) fileName.c_str(), CURLFORM_CONTENTHEADER, post, CURLFORM_END );
    	result = curl_formadd(&first,  &last, CURLFORM_COPYNAME, "submit", CURLFORM_COPYCONTENTS, "send", CURLFORM_END );
    	if( result )
    	{
    		speech->Speak( "Can't form the query to tesseract service" );
    		curl_slist_free_all( post );
    		curl_formfree( first );
    		return;
    	}
    	CURL *handle = wxGetApp().GetCurlHandle();
    	FILE *fp = fopen( "session.log", "w+" );
    	if( !fp )
    	{
    		speech->Speak( "Can't create log file" );
    		curl_slist_free_all( post );
    		curl_formfree( first );
    		return;
    	}
    	curl_easy_setopt( handle, CURLOPT_VERBOSE, 1L );
    	curl_easy_setopt( handle, CURLOPT_HEADER, 1L );
    	curl_easy_setopt( handle, CURLOPT_STDERR, fp );
    	curl_easy_setopt( handle, CURLOPT_ERRORBUFFER, errorMsg );
    	curl_easy_setopt( handle, CURLOPT_URL, "http://174.122.236.154/TouchAndRead/Default.aspx" );
                  curl_easy_setopt( handle, CURLOPT_HTTPPOST, first );
    	error = curl_easy_perform( handle );
    	if( !error )
    	{
    		speech->Speak( errorMsg );
    		curl_slist_free_all( post );
    		curl_formfree( first );
    		return;
    	}
    Thank you.

  5. #5
    Join Date
    Apr 1999
    Posts
    27,449

    Re: VB + ASP -> C++ + libCURL

    Quote Originally Posted by OneEyeMan View Post
    Paul,
    I added necessary checks. Everything is fine. File is opened and parameters are added.
    The problem seems to be that the furst curl_easy_perform() return "Error 23: Failed writing a body".
    I have never used libcurl. I'm just noting the red flags in your code, the first being the lack of error checking.

    The second one is this:
    Code:
    post = curl_slist_append( post, (const char *) header.c_str() );
    First, header is a wxString. I have never used wxString, but according to the curl_slist_append documentation, the second parameter must be a const char *. The question is this -- why did you need to cast the return value of wxString::c_str() to a const char*? What would happen if you removed the cast?

    The reason why this is important is because I see this too often, and that is believing that a string can be converted to another string type by merely casting. I see this error when someone tries to take a Unicode string and forces it to compile for char-based strings by applying a C-style cast (or vice-versa, forcing a char based string to a wide string by merely casting).

    So what does the compiler tell you is the issue if you remove that cast?

    Regards,

    Paul McKenzie

  6. #6
    Join Date
    Aug 2002
    Posts
    757

    Re: VB + ASP -> C++ + libCURL

    Hi, Paul,
    Sorry for the late reply.
    No issues at all. In fact both Mac gcc and MSVC 2010 are happy with it.

    I also installed WireShark on my Windows box and this is resolved, but I have another problem which hopefully be solved soon.

    Thank you for the help.

  7. #7
    Join Date
    Jan 2009
    Posts
    1,689

    Re: VB + ASP -> C++ + libCURL

    If you are on Windows, an invaluable tool is called Fiddler 2. It's much much easier to use that Wireshark for this type of request, and you simply have to proxy your traffic through port 8080 to see and inspect it. Curl has an easy way to set the proxy settings, I don't know it off the top of y header, but i'm sure you will have no trouble finding it.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured