Hi Daniel,
Please find attached for your reference (problematic_code.c), the sample code 
that repeats this problem 
(verified with the latest curl version - curl-7.23.1).

The observed output for this code was as below:

---------------------------------------------------------------------------------------------------
Initializing the curl handler...
Trying to connect to server
Setting the from...
Setting the to...
Sending message...
* About to connect() to proxy xx.xx.xx.xx port 8080 (#0)
*   Trying xx.xx.xx.xx... * connected
* Establish HTTP proxy tunnel to xx.xx.xx.xx:25
> CONNECT xx.xx.xx.xx:25 HTTP/1.1
Host: xx.xx.xx.xx:25
Proxy-Connection: Keep-Alive

< HTTP/1.1 200 Connection established
<
* Proxy replied OK to CONNECT request
> GET / HTTP/1.1
Host: xx.xx.xx.xx:25
Accept: */*

220 <SMTP_server> ESMTP Sendmail 8.9.3 (PHNE_28760+JAGae91741+JAGae92668)/8.9.3 
SMKit7.03; Fri, 9 Dec 2011 19:46:07 +0100 (MET)
500 Command unrecognized: "GET / HTTP/1.1"
500 Command unrecognized: "Host: xx.xx.xx.xx:25"
500 Command unrecognized: "Accept: */*"
500 Command unrecognized: "Cache-Control: max-stale=0"
500 Command unrecognized: "Connection: Keep-Alive"
500 Command unrecognized: "X-BlueCoat-Via: 6a059f033a1dbd0f"
500 Command unrecognized: ""
------------------------------------------------------------------------------------------------------

[Kindly note: I have edited out the proxy and SMTP server IPs used (in the code 
and its output seen here) for confidentiality purposes. 
              Request you to verify the same with appropriate IP addresses at 
your end]

Thanks in advance for your time.

Regards,
Naveen

-----Original Message-----
From: [email protected] 
[mailto:[email protected]] On Behalf Of Daniel Stenberg
Sent: Sunday, December 04, 2011 5:01 AM
To: libcurl hacking
Subject: RE: issue with SMTP through HTTP proxy (using curl v 7.20.0)

On Thu, 1 Dec 2011, Chandran, Naveen wrote:

(Reply taken over to curl-library from curl-users)

Please don't top-post and full-quote.

> Oh yes Daniel. I did specify the protocol to be smtp for the CURLOPT_URL 
> part. The SMTP server even presents itself with a "220 <server_name> ESMTP" 
> message. But afterwards, I get the erroneous behavior nevertheless.

Yes the server says "220..." because you connect to the correct remote port. 
But libcurl seems to think it should do HTTP and that is why it sends the HTTP 
request instead of speaking SMTP. That's why I wanted to be sure you really 
used SMTP:// first in the url string.

Single-stepping with your debugger through the smtp_connect() function should 
make a good start.

Can you provide a full example program that repeats this problem with a recent 
libcurl version?

-- 

  / daniel.haxx.se
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2011, Daniel Stenberg, <[email protected]>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
 *
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ***************************************************************************/
#include <stdio.h>
#include <string.h>
#include <curl/curl.h>

#define FROM    "<[email protected]>"
#define TO      "<[email protected]>"
#define CC      "<[email protected]>"

static const char *payload_text[]={
        "Date: Tue, 10 Dec 2011 11:38:29\n",
        "To: " TO "\n",
        "From: " FROM "(Example User)\n",
        "Cc: " CC "(Another example User)\n",
        //"Message-ID: 
<[email protected]>\n",
        "Subject: SMTP TLS example message\n",
        "\n", /* empty line to divide headers from body, see RFC5322 */
        "The body of the message starts here.\n",
        "\n",
        "It could be a lot of lines, could be MIME encoded, whatever.\n",
        "Check RFC5322.\n",
        NULL
};

struct upload_status {
        int lines_read;
};

static size_t payload_source(void *ptr, size_t size, size_t nmemb, void *userp)
{
        struct upload_status *upload_ctx = (struct upload_status *)userp;
        const char *data;

        if ((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
                return 0;
        }

        data = payload_text[upload_ctx->lines_read];

        if (data) {
                size_t len = strlen(data);
                memcpy(ptr, data, len);
                upload_ctx->lines_read ++;
                return len;
        }
        return 0;
}

int main(void)
{
        CURL *curl;
        CURLcode res;
        struct curl_slist *recipients = NULL;
        struct upload_status upload_ctx;

        upload_ctx.lines_read = 0;

        /* value for envelope reverse-path */
        static const char *from = "<[email protected]>";

        /* this becomes the envelope forward-path */
        static const char *to = "<[email protected]>";

        printf("Initializing the curl handler...\n");
        curl = curl_easy_init();
        if(curl) {
                /* this is the URL for your mailserver - you can also use an 
smtps:// URL
                 * here */
                curl_easy_setopt(curl, CURLOPT_VERBOSE, 1);
                printf("Trying to connect to server\n");
                curl_easy_setopt(curl, CURLOPT_URL, "smtp://xx.xx.xx.xx:25");

                /* Note that this option isn't strictly required, omitting it 
will result in
                 * libcurl will sent the MAIL FROM command with no sender data. 
All
                 * autoresponses should have an empty reverse-path, and should 
be directed
                 * to the address in the reverse-path which triggered them. 
Otherwise, they
                 * could cause an endless loop. See RFC 5321 Section 4.5.5 for 
more details.
                 */
                printf("Setting the from...\n");
                curl_easy_setopt(curl, CURLOPT_MAIL_FROM, from);

                /* Note that the CURLOPT_MAIL_RCPT takes a list, not a char 
array.  */
                printf("Setting the to...\n");
                recipients = curl_slist_append(recipients, to);
                curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);

                /* You provide the payload (headers and the body of the 
message) as the
                 * "data" element. There are two choices, either:
                 * - provide a callback function and specify the function name 
using the
                 * CURLOPT_READFUNCTION option; or
                 * - just provide a FILE pointer that can be used to read the 
data from.
                 * The easiest case is just to read from standard input, (which 
is available
                 * as a FILE pointer) as shown here.
                 */
                curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
                curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);

        /* Setting the proxy server IP, followed by the HTTP proxy tunneling 
option */
                curl_easy_setopt(curl, CURLOPT_PROXY, "xx.xx.xx.xx:8080");
                curl_easy_setopt(curl, CURLOPT_HTTPPROXYTUNNEL, 1L );

                /* send the message (including headers) */
                printf("Sending message...\n");
                res = curl_easy_perform(curl);
                printf("Error: %d = %s\n", res, curl_easy_strerror(res));

                /* free the list of recipients */
                printf("Freeing...\n");
                curl_slist_free_all(recipients);

                /* curl won't send the QUIT command until you call cleanup, so 
you should be
                 * able to re-use this connection for additional messages 
(setting
                 * CURLOPT_MAIL_FROM and CURLOPT_MAIL_RCPT as required, and 
calling
                 * curl_easy_perform() again. It may not be a good idea to keep 
the
                 * connection open for a very long time though (more than a few 
minutes may
                 * result in the server timing out the connection), and you do 
want to clean
                 * up in the end.
                 */
                printf("Cleaning up...\n");
                curl_easy_cleanup(curl);
        }
        return 0;
}
-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html

Reply via email to