Multipart form post to google app engine not working
Question: I am trying to post a multi-part form using httplib, url is hosted on google
app engine, on post it says Method not allowed, though the post using urllib2
works. Full working example is attached.

My question is what is the difference between two, why one works but not the
other

  1. is there a problem in my mulipart form post code?

  2. or the problem is with google app engine?

  3. or something else ?

* * *
    
    
    import httplib
    import urllib2, urllib
    
    # multipart form post using httplib fails, saying
    # 405, 'Method Not Allowed'
    url = "http://mockpublish.appspot.com/publish/api/revision_screen_create"
    _, host, selector, _, _ = urllib2.urlparse.urlsplit(url)
    print host, selector
    h = httplib.HTTP(host)
    
    h.putrequest('POST', selector)
    
    BOUNDARY = '----------THE_FORM_BOUNDARY'
    content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
    h.putheader('content-type', content_type)
    h.putheader('User-Agent', 'Python-urllib/2.5,gzip(gfe)')
    content = ""
    L = []
    L.append('--' + BOUNDARY)
    L.append('Content-Disposition: form-data; name="test"')
    L.append('')
    L.append("xxx")
    L.append('--' + BOUNDARY + '--')
    L.append('')
    content = '\r\n'.join(L)
    h.putheader('content-length', str(len(content)))
    h.endheaders()
    h.send(content)
    
    print h.getreply()
    
    # post using urllib2 works
    data = urllib.urlencode({'test':'xxx'})
    request = urllib2.Request(url)
    f = urllib2.urlopen(request, data)
    output = f.read()
    print output
    

Edit: After changing putrequest to request (on Nick Johnson's suggestion), it
works

    
    
    url = "http://mockpublish.appspot.com/publish/api/revision_screen_create"
    _, host, selector, _, _ = urllib2.urlparse.urlsplit(url)
    
    h = httplib.HTTPConnection(host)
    
    BOUNDARY = '----------THE_FORM_BOUNDARY'
    content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
    
    content = ""
    L = []
    L.append('--' + BOUNDARY)
    L.append('Content-Disposition: form-data; name="test"')
    L.append('')
    L.append("xxx")
    L.append('--' + BOUNDARY + '--')
    L.append('')
    content = '\r\n'.join(L)
    h.request('POST', selector, content,{'content-type':content_type})
    res = h.getresponse()
    print res.status, res.reason, res.read()
    

so now the question remains what is the difference between two approaches and
can first first be made to work?


Answer: [Nick Johnson's](http://stackoverflow.com/users/12030/nick-johnson) answer

Have you tried sending the request with httplib using .request() instead of
.putrequest() etc, supplying the headers as a dict?

it works!

