|
| 1 | +/************************************************************************** |
| 2 | +* ADOBE SYSTEMS INCORPORATED |
| 3 | +* Copyright 2008 Adobe Systems Incorporated |
| 4 | +* All Rights Reserved |
| 5 | +* |
| 6 | +* NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the |
| 7 | +* terms of the Adobe license agreement accompanying it. If you have received this file from a |
| 8 | +* source other than Adobe, then your use, modification, or distribution of it requires the prior |
| 9 | +* written permission of Adobe. |
| 10 | +**************************************************************************/ |
| 11 | + |
| 12 | +#define WINDOWS_IGNORE_PACKING_MISMATCH |
| 13 | + |
| 14 | +#include "BasicExternalObject.h" |
| 15 | +#include "SoSharedLibDefs.h" |
| 16 | +#include <string> |
| 17 | + |
| 18 | +#include <curl/curl.h> |
| 19 | + |
| 20 | + |
| 21 | +/** |
| 22 | +* \brief To allow string manipulation |
| 23 | +*/ |
| 24 | +using namespace std; |
| 25 | + |
| 26 | +/** This is the version number, and can be modified by setVersion(). */ |
| 27 | +static long libraryVersionNumber = 1; |
| 28 | + |
| 29 | +/** |
| 30 | + String string that contains the signatures of every ESFunction defined here, |
| 31 | + used to support the JavaScript reflection interface. |
| 32 | + Note that this is a single comma-separated values string, concatenated |
| 33 | + by the compiler. |
| 34 | +*/ |
| 35 | +static char* signatures = "httpPost_sss"; // ? |
| 36 | + |
| 37 | +#if MAC |
| 38 | +#define unused(a) (void*) a ; |
| 39 | +#else |
| 40 | +void* unused(void* x) { return x; }; |
| 41 | +#endif |
| 42 | + |
| 43 | +/** |
| 44 | +* \brief Returns the version number of the library |
| 45 | +* |
| 46 | +* ExtendScript publishes this number as the version property of the object |
| 47 | +* created by new ExternalObject. Used by the direct interface. |
| 48 | +*/ |
| 49 | +extern "C" ESCURLLIB long ESGetVersion() |
| 50 | +{ |
| 51 | + return libraryVersionNumber; |
| 52 | +} |
| 53 | + |
| 54 | +/** |
| 55 | +* \brief Initialize the library and return function signatures. |
| 56 | +* |
| 57 | +* These signatures have no effect on the arguments that can be passed to the functions. |
| 58 | +* They are used by JavaScript to cast the arguments, and to populate the |
| 59 | +* reflection interface. |
| 60 | +*/ |
| 61 | +extern "C" ESCURLLIB char* ESInitialize(TaggedData * argv, long argc) |
| 62 | +{ |
| 63 | + unused(&argv); |
| 64 | + unused(&argc); |
| 65 | + |
| 66 | + curl_global_init(CURL_GLOBAL_ALL); |
| 67 | + |
| 68 | + return signatures; |
| 69 | +} |
| 70 | + |
| 71 | +/** |
| 72 | +* \brief Terminate the library. |
| 73 | +* |
| 74 | +* Does any necessary clean up that is needed. |
| 75 | +*/ |
| 76 | +extern "C" ESCURLLIB void ESTerminate() |
| 77 | +{ |
| 78 | + /* we are done with libcurl, so clean it up */ |
| 79 | + curl_global_cleanup(); |
| 80 | +} |
| 81 | + |
| 82 | +/** |
| 83 | +* \brief Free any string memory which has been returned as function result. |
| 84 | +* JavaScipt calls this function to release the memory associated with the string. |
| 85 | +* Used for the direct interface. |
| 86 | +* |
| 87 | +* \param *p Pointer to the string |
| 88 | +*/ |
| 89 | +extern "C" ESCURLLIB void ESFreeMem(void* p) |
| 90 | +{ |
| 91 | + if (p) |
| 92 | + free(p); |
| 93 | +} |
| 94 | + |
| 95 | + |
| 96 | +/** |
| 97 | +
|
| 98 | +
|
| 99 | +
|
| 100 | +
|
| 101 | +
|
| 102 | +
|
| 103 | +
|
| 104 | +*/ |
| 105 | +struct MemoryStruct { |
| 106 | + char* memory; |
| 107 | + size_t size; |
| 108 | +}; |
| 109 | +static size_t WriteMemoryCallback(void* contents, size_t size, size_t nmemb, void* userp) |
| 110 | +{ |
| 111 | + size_t realsize = size * nmemb; |
| 112 | + struct MemoryStruct* mem = (struct MemoryStruct*)userp; |
| 113 | + |
| 114 | + mem->memory = (char*)realloc(mem->memory, mem->size + realsize + 1); |
| 115 | + if (mem->memory == NULL) { |
| 116 | + /* out of memory */ |
| 117 | + printf("not enough memory (realloc returned NULL)\n"); |
| 118 | + return 0; |
| 119 | + } |
| 120 | + |
| 121 | + memcpy(&(mem->memory[mem->size]), contents, realsize); |
| 122 | + mem->size += realsize; |
| 123 | + mem->memory[mem->size] = 0; |
| 124 | + |
| 125 | + return realsize; |
| 126 | +} |
| 127 | +/** |
| 128 | +
|
| 129 | +
|
| 130 | +
|
| 131 | +
|
| 132 | +
|
| 133 | +
|
| 134 | +
|
| 135 | +*/ |
| 136 | +extern "C" ESCURLLIB long httpPost(TaggedData * argv, long argc, TaggedData * retval) { |
| 137 | + // Accept 2 arguments |
| 138 | + if (argc != 3) |
| 139 | + { |
| 140 | + return kESErrBadArgumentList; |
| 141 | + } |
| 142 | + |
| 143 | + // The arguments must be a string |
| 144 | + if (argv[0].type != kTypeString) // url |
| 145 | + { |
| 146 | + return kESErrBadArgumentList; |
| 147 | + } |
| 148 | + if (argv[1].type != kTypeString) // json request data |
| 149 | + { |
| 150 | + return kESErrBadArgumentList; |
| 151 | + } |
| 152 | + if (argv[2].type != kTypeString) // auth header |
| 153 | + { |
| 154 | + return kESErrBadArgumentList; |
| 155 | + } |
| 156 | + |
| 157 | + CURLcode ret; |
| 158 | + CURL* hnd; |
| 159 | + struct curl_slist* slist1; |
| 160 | + |
| 161 | + slist1 = NULL; |
| 162 | + slist1 = curl_slist_append(slist1, argv[2].data.string); |
| 163 | + slist1 = curl_slist_append(slist1, "Content-Type: application/json"); |
| 164 | + |
| 165 | + struct MemoryStruct chunk; |
| 166 | + |
| 167 | + chunk.memory = (char*)malloc(1); /* will be grown as needed by the realloc above */ |
| 168 | + chunk.size = 0; /* no data at this point */ |
| 169 | + |
| 170 | + |
| 171 | + |
| 172 | + /* init the curl session */ |
| 173 | + hnd = curl_easy_init(); |
| 174 | + |
| 175 | + |
| 176 | + // argv[0].data.string = the string passed in from the script |
| 177 | + curl_easy_setopt(hnd, CURLOPT_BUFFERSIZE, 102400L); |
| 178 | + curl_easy_setopt(hnd, CURLOPT_URL, argv[0].data.string); |
| 179 | + curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L); |
| 180 | + // post data |
| 181 | + curl_easy_setopt(hnd, CURLOPT_POSTFIELDS, argv[1].data.string); |
| 182 | + // content length |
| 183 | + curl_easy_setopt(hnd, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)strlen(argv[1].data.string)); |
| 184 | + curl_easy_setopt(hnd, CURLOPT_HTTPHEADER, slist1); |
| 185 | + curl_easy_setopt(hnd, CURLOPT_USERAGENT, "curl/7.81.0"); |
| 186 | + curl_easy_setopt(hnd, CURLOPT_FOLLOWLOCATION, 1L); |
| 187 | + curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L); |
| 188 | + curl_easy_setopt(hnd, CURLOPT_HTTP_VERSION, (long)CURL_HTTP_VERSION_2TLS); |
| 189 | + curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYPEER, 0L); |
| 190 | + curl_easy_setopt(hnd, CURLOPT_SSL_VERIFYHOST, 0L); |
| 191 | + curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "POST"); |
| 192 | + curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L); |
| 193 | + curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L); |
| 194 | + |
| 195 | + /* send all data to this function */ |
| 196 | + curl_easy_setopt(hnd, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); |
| 197 | + |
| 198 | + /* we pass our 'chunk' struct to the callback function */ |
| 199 | + curl_easy_setopt(hnd, CURLOPT_WRITEDATA, (void*)&chunk); |
| 200 | + |
| 201 | + |
| 202 | + ret = curl_easy_perform(hnd); |
| 203 | + |
| 204 | + /* check for errors */ |
| 205 | + if (ret != CURLE_OK) { |
| 206 | + fprintf(stderr, "curl_easy_perform() failed: %s\n", |
| 207 | + curl_easy_strerror(ret)); |
| 208 | + } |
| 209 | + else { |
| 210 | + /* |
| 211 | + * Now, our chunk.memory points to a memory block that is chunk.size |
| 212 | + * bytes big and contains the remote file. |
| 213 | + * |
| 214 | + * Do something nice with it! |
| 215 | + */ |
| 216 | + |
| 217 | + printf("%lu bytes retrieved\n", (long)chunk.size); |
| 218 | + } |
| 219 | + |
| 220 | + |
| 221 | + |
| 222 | + /* cleanup curl stuff */ |
| 223 | + curl_easy_cleanup(hnd); |
| 224 | + hnd = NULL; |
| 225 | + curl_slist_free_all(slist1); |
| 226 | + slist1 = NULL; |
| 227 | + |
| 228 | + |
| 229 | + // The returned value type |
| 230 | + retval->type = kTypeString; |
| 231 | + |
| 232 | + retval->data.string = chunk.memory; |
| 233 | + |
| 234 | + |
| 235 | + return kESErrOK; |
| 236 | +} |
0 commit comments