@@ -12,9 +12,9 @@ import urllib2
12
12
import httplib
13
13
import json
14
14
import datetime
15
- import mimetools
16
15
import mimetypes
17
- import itertools
16
+ import random
17
+ import string
18
18
19
19
from models import *
20
20
@@ -29,7 +29,7 @@ class ApiClient:
29
29
self .apiKey = apiKey
30
30
self .apiServer = apiServer
31
31
self .cookie = None
32
- self .boundary = mimetools . choose_boundary ( )
32
+ self .boundary = '' . join ( random . choice ( string . ascii_letters + string . digits ) for _ in range ( 30 ) )
33
33
34
34
def callAPI (self , resourcePath , method , queryParams , postData ,
35
35
headerParams = None , files = None ):
@@ -40,7 +40,6 @@ class ApiClient:
40
40
for param , value in headerParams .iteritems ():
41
41
headers [param ] = value
42
42
43
- #headers['Content-type'] = 'application/json'
44
43
headers ['api_key' ] = self .apiKey
45
44
46
45
if self .cookie :
@@ -68,9 +67,10 @@ class ApiClient:
68
67
if 'Content-type' not in headers :
69
68
headers ['Content-type' ] = 'application/json'
70
69
data = json .dumps (postData )
71
- elif headers ['Content-type' ] == 'multipart/form' :
72
- headers ['Content-type' ] = 'multipart/form; boundry=%s' % self .boundary
70
+ elif headers ['Content-type' ] == 'multipart/form-data' :
73
71
data = self .buildMultipartFormData (postData , files )
72
+ headers ['Content-type' ] = 'multipart/form-data; boundary={0}' .format (self .boundary )
73
+ headers ['Content-length' ] = str (len (data ))
74
74
else :
75
75
data = urllib .urlencode (postData )
76
76
@@ -135,29 +135,36 @@ class ApiClient:
135
135
data = json .dumps (postData .__dict__ )
136
136
137
137
def buildMultipartFormData (self , postData , files ):
138
- parts = []
139
- part_boundary = '--' + self .boundary
140
- parts .extend (
141
- [part_boundary , 'Content-Disposition: form-data; name="%s"' % name , '' , value ]
142
- for name , value in postData .items ()
143
- )
144
-
145
- file_tuples = []
146
- for fieldname , file_path in files :
147
- filename = file_path .split ('/' )[- 1 ]
148
- f = open (file_path , 'r' )
138
+ def escape_quotes (s ):
139
+ return s .replace ('"' , '\\ "' )
140
+
141
+ lines = []
142
+
143
+ for name , value in postData .items ():
144
+ lines .extend ((
145
+ '--{0}' .format (self .boundary ),
146
+ 'Content-Disposition: form-data; name="{0}"' .format (escape_quotes (name )),
147
+ '' ,
148
+ str (value ),
149
+ ))
150
+
151
+ for name , filepath in files .items ():
152
+ f = open (filepath , 'r' )
153
+ filename = filepath .split ('/' )[- 1 ]
149
154
mimetype = mimetypes .guess_type (filename )[0 ] or 'application/octet-stream'
150
- body = f .read ()
151
- file_tuples .append ((fieldname , filename , mimetype , body ))
152
- parts .extend (
153
- [part_boundary , 'Content-Disposition file; name="%s"; filename="%s"' % (fieldname , filename ), 'Content-Type: %s' % content_type , '' , body ]
154
- for fieldname , filename , content_type , body in file_tuples
155
- )
156
-
157
- flattened = list (itertools .chain (* parts ))
158
- flattened .append ('--' + self .boundary + '--' )
159
- flattened .append ('' )
160
- return '\r \n ' .join (flattened )
155
+ lines .extend ((
156
+ '--{0}' .format (self .boundary ),
157
+ 'Content-Disposition: form-data; name="{0}"; filename="{1}"' .format (escape_quotes (name ), escape_quotes (filename )),
158
+ 'Content-Type: {0}' .format (mimetype ),
159
+ '' ,
160
+ f .read ()
161
+ ))
162
+
163
+ lines .extend ((
164
+ '--{0}--' .format (self .boundary ),
165
+ ''
166
+ ))
167
+ return '\r \n ' .join (lines )
161
168
162
169
def deserialize (self , obj , objClass ):
163
170
"""Derialize a JSON string into an object.
0 commit comments