Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem with python curl while submitting file

#!/usr/bin/python
import pycurl
import re
import StringIO


#CONSTANTS
URL = "http://www.imagehost.org"
FILE = "/datos/poop1.jpg"
POST_DATA = [("a", "upload"), ("file[]", (pycurl.FORM_FILE, FILE))]



buffer = StringIO.StringIO()


c = pycurl.Curl()
c.setopt( c.URL, URL )
c.setopt( c.POST, 1 )
c.setopt( c.POSTFIELDS, POST_DATA )
##c.setopt( c.HTTPPOST, POST_DATA )
c.setopt( c.USERAGENT,'Curl')
c.setopt( c.WRITEFUNCTION, buffer.write)
c.setopt(pycurl.VERBOSE, 1)

c.perform()
c.close()

#c.setopt(c.PROXY, proxyHostAndPort)
#c.setopt(c.PROXYUSERPWD, proxyAuthentication)

parse = buffer.getvalue()


pattern = re.compile('/<td nowrap="nowrap">(.+)<\/td>\s*<td class="link"><input.+value="([^"]+)" \/><\/td>/i')

result = re.search(pattern, parse)
print result

The problem is in the way on how to do the post.

c.setopt( c.POSTFIELDS, POST_DATA ) does not accept lists, so what should I do instead of adding a list?

And c.setopt( c.HTTPPOST, POST_DATA ) drops :

Traceback (most recent call last): 
  File "pymage", line 26, in <module>
c.perform() pycurl.error: (26, 'failed creating formpost data')

Update:

-----------------------------15758382912173403811539561297\r\nContent-Disposition: form-data; name="a"\r\n\r\nupload\r\n-----------------------------15758382912173403811539561297\r\nContent-Disposition: form-data; name="file[]"; filename="Datos_Pegados_0a17.jpg"\r\nContent-Type: image/jpeg\r\n\r\nÿØÿà

That's what I get using tamper data.

Interesting part of the postfield:

form-data; name="a"\r\n\r\nupload\r\n

form-data; name="file[]"

So... you say the POST_DATA should be 'a=upload&file[]=FILE'?

Update2:

<form method="post" action="/" enctype="multipart/form-data" onsubmit="javascript:Upload(); return true;">

<input type="hidden" name="a" value="upload" />

<td class="left">File:</td>
td class="right"><input name="file[]" type="file" size="20" /></td>

That's the code...

Now it's working the form-data configuration, but it's not uploading the file I believe

c.setopt( c.POSTFIELDS, 'a=upload&file[]=/datos/poop1.jpg' )

I'm getting this:

* About to connect() to www.imagehost.org port 80 (#0)
*   Trying 74.63.87.74... * connected
* Connected to www.imagehost.org (74.63.87.74) port 80 (#0)
> POST / HTTP/1.1
User-Agent: Curl
Host: www.imagehost.org
Accept: */*
Content-Length: 32
Content-Type: application/x-www-form-urlencoded

< HTTP/1.1 200 OK
< Transfer-Encoding: chunked
< Date: Wed, 25 Mar 2009 06:53:49 GMT
< Content-Type: text/html
< Server: nginx/0.7.11
< Set-Cookie: userhash=7c09b97cc70c8c133c850a3e744b416e; expires=Thu, 25-Mar-2010 06:53:49 GMT; path=/; domain=.imagehost.org; httponly
< 
* Connection #0 to host www.imagehost.org left intact
* Closing connection #0
like image 287
matta Avatar asked Dec 05 '25 05:12

matta


2 Answers

The pycurl documentation is not so clear on this, but the HTTPPOST option can take a list of tuples, each exactly two elements long. Each tuple's first argument is the form field name, the second is the value.

However, the value may be a tuple as well. This tuple must contains pairs of data relating to that field: ( form_option, option_value, form_option, option_value, etc., etc.)

For example, a multi-part form with three fields, the last being a file upload - we can set the filename and the mime type:

c = pycurl.Curl()
c.setopt(c.URL, base_url + 'upload.cgi')
c.setopt(c.HTTPPOST,[ ("fieldname1", "value1"), 
                      ("fieldname2", "value2"), 
                      ("uploadfieldname", 
                                 (c.FORM_FILE, local_filename, 
                                  c.FORM_CONTENTTYPE, "application/x-gzip"))
                    ])

You can find the options in the documentation for the C API for curl_formadd(): http://curl.haxx.se/libcurl/c/curl_formadd.html however, from the pycurl source, it looks like only FORM_FILE, FORM_FILENAME, FORM_CONTENTTYPE and FORM_COPYCONTENTS are supported.

like image 70
GrahamW Avatar answered Dec 07 '25 18:12

GrahamW


Error 26 (in "pycurl.error: (26, 'failed creating formpost data')") means that the filename you specified to upload does not exist. I was running into this same error, and that was definitely the problem. See the curl source code for the location that it generates error 26.

like image 24
Sean Reifschneider Avatar answered Dec 07 '25 17:12

Sean Reifschneider



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!