In reference to this: http://docs.rackspace.com/files/api/v1/cf-devguide/content/Uploading_the_Manifest-d1e2227.html
so I uploaded the following JSON via PUT command on Rackspace:
Body:
[
{
"path": "/archive5/8b98fb0bc6f8694d07a1bc851b58f72a",
"etag": "8b98fb0bc6f8694d07a1bc851b58f72a",
"size_bytes": 20971520
},
{
"path": "/archive5/c234d0f0204f67340fb4741bdf9f5e92",
"etag": "c234d0f0204f67340fb4741bdf9f5e92",
"size_bytes": 8382711
}
]
URL: https://storage101.ord1.clouddrive.com/v1/MossoCloudFS_hashhash/archive5/606f95dbf0a17bd7d5de202f3aab98c7?multipart-manifest=put
Method: PUT
Headers
ETag: 606f95dbf0a17bd7d5de202f3aab98c7
Content-Type: application/octet-stream
Content-Length: 266
X-Auth-Token: theAuthToken
X-Auth-Project-Id: theProjectId
but then Cloudfiles would then return
Problem saving/updating object
[https://storage101.ord1.clouddrive.com/v1/MossoCloudFS_hashhash/archive5/606f95dbf0a17bd7d5de202f3aab98c7]
HTTP status [422] response [Unprocessable
EntityUnable to process the contained instructions]
What did I do wrong? I've verified that the files in the JSON body indeed exist and that they have the correct path/etag(md5) and filesize...
Have you tried using php-opencloud to do this? There's an upload-large-object.php that takes care of all of the details for you.
Related
I'm using currently the Firebase messaging with PHP. I was able to make it work with a single notification with PHP and cURL. I've read the documentation about making batch request and I've constructed the request string as follow:
--subrequest_boundary
Content-Type: application/http
Content-Transfer-Encoding: binary
Authorization: Bearer ya29.xxxxxnY
POST /v1/projects/xxxxxxxx/messages:send
Content-Type: application/json
accept: application/json
{
"message":{
"token":"cxxxxx3",
"data":{
"typeNoti":"paiement",
"idcompte":"admin",
"typecompte":"paiement"
},
"notification":{
"title":"Test1",
"body":"Notification de test 1"
}
}
}
--subrequest_boundary
Content-Type: application/http
Content-Transfer-Encoding: binary
Authorization: Bearer yaxxxxxxY
POST /v1/projects/xxxxxx/messages:send
Content-Type: application/json
accept: application/json
{
"message":{
"token":"eoxxxxxU1",
"data":{
"typeNoti":"paiement",
"idcompte":"compte2",
"typecompte":"paiement"
},
"notification":{
"title":"Test1",
"body":"Notification de test 1"
}
}
}
--subrequest_boundary--
This string is generated in a file called batch_request.txt as the documentation said. When trying to send the request with cURL I receive this error:
{
"error": {
"code": 400,
"message": "Failed to parse batch request, error: 0 items. Received batch body: (0) bytes redacted",
"status": "INVALID_ARGUMENT"
}
}
I've experienced a strange behavior also, which is when I construct that string manually (in PHP I use HEREDOC), the batch request does occurs with 200ok response. I've tried to find some hidden character but couldn't.
I know there is a library called firebase-php. The problem with it is that I cannot find a straight foreward example like this:
//authenticate with json file
//create new token if it doesn't exist or skip
//create notification array
//create data array
//send multi notifications to multiple devices
I actually use a for loop and mono notification (one device token, one message at a time). The problem with this is that not all notifications are sent.
I appreciate your help thanks!
I gathered the code from firebase-php docs. After installing the library with composer I get a lot of errors and a lot of missing files in Firebase directory inside vendor like Factory.php etc
My solution was to NOT USE firebase-php library due to the numerous bugs I've faced (or maybe misuses) neither to construct the REST request text file for batch request. I used instead the NodeJS SDK which worked like a charm. I'm running a javascript file from my php code using exec.
I have some data that compressed with gzip in an application from here:
app.myaddress.com/data/api/1.
The data contains several parameters in JSON format like follows:
{
"id": 1,
"data": "abcabcabcabcabc" //this is the compressed data
}
I need to check the compressed data with another 3rd party service, we can just say the address like follows: app2.myaddress.com/check_data/abcabc by API request, but it's needed a header authentication:
{
"content-type": "application/json",
"api-key": 123456
}
app2.myaddress.com will return data JSON format like follows:
{
"name": "hello",
"address": "australia"
}
What I need to do is just checking a data by accessing URL like:
app.myaddress.com/data/api/checked/1
then the controller will process the data include checking through app2.myaddress.com and return the value into app.myaddress.com
Solved by #rafitio:
You can use cURL or Guzzle to access both URL inside your function. Here is the documentation of Guzzle: http://docs.guzzlephp.org/en/stable/request-options.html
While trying to add webhook status to a nicely working Docusign integration API, it started to give me a the error INVALID_REQUEST_BODY.
As I'm using the PHP API, I'm not writing the JSON payload myself, Docusign PHP package is responsible for serializing the thing, but, it says INVALID_REQUEST_BODY, pointing to here:
"eventNotification":[{"url":"https:\/\/xxx.yyyy.zzz.com\/docusign\/webhook",
^
I also tried to remove everything else, sending only the url parameter. Tried to change the URL, sending only a domain. Nothing worked. If I send the event notification I get the error, if I don't send it, everything works fine.
And the Docusign PHP package raises exceptions if you send wrongly named items to it, so, I'm also sure the EventNotification model is pretty much correct.
Here's the full error message, without sensitive data:
[DEBUG] HTTP Request body ~BEGIN~
{"documents":[{"documentId":1,"name":"XXXXXXXXXX.pdf","documentBase64":"XXXXXXXX="}],"recipients":{"signers":[{"tabs":{"signHereTabs":[{"documentId":1,"recipientId":1,"pageNumber":1,"anchorString":"recipient_signature"}]},"name":"xxxxxxxxx","email":"xx#xxxxxxxx.com","recipientId":1,"clientUserId":XXXX}]},"eventNotification":[{"url":"https:\/\/xxx.yyyy.zzz.com\/docusign\/webhook","loggingEnabled":"true"}],"status":"sent","emailSubject":"XXXXXX - XXXXXX Certification","brandId":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}
~END~
* Hostname demo.docusign.net was found in DNS cache
* Trying 162.248.186.25...
* TCP_NODELAY set
* Connected to demo.docusign.net (162.248.186.25) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
* Server certificate: demo.docusign.net
* Server certificate: Symantec Class 3 EV SSL CA - G3
* Server certificate: VeriSign Class 3 Public Primary Certification Authority - G5
> POST /restApi/v2/accounts/XXXXXX/envelopes HTTP/1.1
Host: demo.docusign.net
User-Agent: PHP-Swagger/2.0.0
X-DocuSign-Authentication: {"Username":"dev#xxxx.com","Password":"xxxxxxx","IntegratorKey":"XXX-XXXXXXXX-XXX-XXXX-xxxxx-xxxxxxxxxxxx"}
X-DocuSign-SDK: PHP
Accept: application/json
Content-Type: application/json
Content-Length: 3981
Expect: 100-continue
< HTTP/1.1 100 Continue
* We are completely uploaded and fine
< HTTP/1.1 400 Bad Request
< Cache-Control: no-cache
< Content-Length: 725
< Content-Type: application/json; charset=utf-8
< X-DocuSign-TraceToken: c227xxxx
< Date: Wed, 05 Apr 2017 00:13:16 GMT
< Strict-Transport-Security: max-age=31536000; includeSubDomains
<
* Curl_http_done: called premature == 0
* Connection #0 to host demo.docusign.net left intact
[DEBUG] HTTP Response body ~BEGIN~
{
"errorCode": "INVALID_REQUEST_BODY",
"message": "The request body is missing or improperly formatted. Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'API_REST.Models.v2.eventNotification' because the type requires a JSON object (e.g. {\"name\":\"value\"}) to deserialize correctly.\r\nTo fix this error either change the JSON to a JSON object (e.g. {\"name\":\"value\"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.\r\nPath 'eventNotification', line 1, position 3790."
}
So what's happening?
You are incorrectly using the eventNotification parameter as an array.
The following should work. I have removed the square braces []
"eventNotification": {
"url": "https:\/\/xxx.yyyy.zzz.com\/docusign\/webhook",
"loggingEnabled": "true"
}
Here is your complete request
{
"documents": [ { "documentId": 1, "name": "XXXXXXXXXX.pdf", "documentBase64": "XXXXXXXX=" } ],
"recipients": {
"signers": [
{
"tabs": {
"signHereTabs": [
{
"documentId": 1,
"recipientId": 1,
"pageNumber": 1,
"anchorString": "recipient_signature"
}
]
},
"name": "xxxxxxxxx",
"email": "xx#xxxxxxxx.com",
"recipientId": 1,
"clientUserId": XXXX
}
]
},
"eventNotification": {
"url": "https:\/\/xxx.yyyy.zzz.com\/docusign\/webhook",
"loggingEnabled": "true"
},
"status": "sent",
"emailSubject": "XXXXXX - XXXXXX Certification",
"brandId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
I have to make a HTTP call to send data compressed data. I'm developing in Symfony2. For HTTP calls I'm using Guzzle client (version 3.8.1). Also, I am using Guzzle Service Descriptions to decribe the operations allowed on each command.
I know that I have to add the header "Content-Encoding: gzip" in the request, but the request body is not compressed.
Is there a way to specify in the Guzzle client that the request needs to be compressed? (maybe specify this in the Service Description)
Thank you!
To tell the server to give you compressed version, you have to inform it that you understand how to decompress the data.
For that purpose, you send a header during request which is called Accept-Encoding.
Example of accept-encoding header and values (those are the compression schemes that your client knows to use):
accept-encoding:gzip, deflate, sdch, br
The RESPONSE header Content-Encoding is sent by the server. IF that header is set, then your client asserts that the content is compressed and uses the algorithm that the server sent as value of Content-Encoding.
The server doesn't have to respond with compressed page.
Therefore, these are the steps:
Tell the server you know how to deal with compressed pages. You send accept-encoding header and then you specify which compression algorithms your client knows how to deal with.
Inspect whether the server sent Content-Encoding header. If not, content isn't compressed
If yes, check the value of the header. That tells you which algorithm was used for compression, it doesn't have to be gzip, but usually is.
The server doesn't have to respond with compressed page. You are merely informing the server you understand how to deal with compressed pages.
So, for you, what you should do is verify that your server sends gzipped responses and then you should set the request header accept-encoding. You got it the wrong way around.
I found a solution to send data compressed using Guzzle client with Operation Command and Service Description.
In the JSON file containing the service description I have specified that data sent in body is a string:
{
...
"operations": {
"sendCompressedData": {
"httpMethod": "POST",
"uri": ...,
"parameters": {
"Content-Type": {
"location": "header",
"required": true,
"type": "string",
"default": "application/json"
},
"Content-Encoding": {
"location": "header",
"required": true,
"type": "string",
"default": "gzip"
},
"data": {
"location": "body",
"required": true,
"type": "string"
}
}
}
}
}
As mentioned by #Mjh, Guzzle doesn't compress data automatically if "Content-Encoding" header is set, so data needs to be compressed before sending it to the Guzzle client to execute the command. I have serialized the object and used "gzencode($string)" for compressions.
$serializedData = SerializerBuilder::create()->build()->serialize($request, 'json');
$compressedData = gzencode($serializedData);
...
$command = $this->client->getCommand('sendCompressedData', array('data' => $compressedData));
$result = $command->execute();
I'm trying to figure out how to send this kind of data, via PHP, to a RESTful service:
{
"api_version": 1.0,
"project_id" : 123,
"batch_id" : 111,
"accesskey" : "abc123",
"job": {
"file": file,
"word_count": 111,
"title": "FAQ",
"cms_id": "page_123_en_sp",
"url" : "http://original_post_url.com",
"is_update": false,
"translator_id": 123,
"note": "Translate these words",
"source_language": "en",
"target_language": "it"
}
}
First of all, I cannot use curl, as who's going to use this code might not have it installed or might be not allowed to install it.
That's not a 'normal' JSON object.
The job->file property is an actual file (not even an url to a file).
That's the actual code I'm using to send all requests and it worked, until I've met this specific case: http://pastebin.com/6pEjhAkg
The 'file' property is created as such:
$file = generate_file( $content );
protected static function generate_file($content) {
$file = fopen('php://temp','r+');
fwrite($file, $content);
rewind($file);
return $file;
}
Now, when sending data, with $params argument properly set on PHP side, the RESTful returns an error about missing 'api_version' and 'project_id', but they are present.
I'm pretty sure the problem is that he's not receiving data as JSON, but how can I convert to JSON an object that, in his properties, contains a file pointer resource?
The code that sends data and builds the file has been created by a former developer, and I can't get in touch with him.
I tried to understand what is wrong there and the only thing I managed to fix so far, for another unrelated issue, is to actually send JSON data (when $multipart==false), as you can see in lines 16-19 of the linked code, rather than sending urlencoded data.
Any hint?
JSON does not have a "file" concept. You can either load the file content, encode it using Base64 and then stuff it into a JSON string - or you can use multipart format for sending the file in one part and the complete JSON in another part. The multipart solution should be the best performing as it doesn't have to base64 encode the file content.
Here is a similar example message format from Mason that tries to formalize the json/multipart usage:
POST /projects/2/issues HTTP/1.1
Accept: application/vnd.mason+json
Content-Type: multipart/form-data; boundary=d636dfda-b79f-4f29-aaf6-4b6687baebeb
--d636dfda-b79f-4f29-aaf6-4b6687baebeb
Content-Disposition: form-data; name="attachment"; filename="hogweed.jpg"
... binary data for attached image ...
--d636dfda-b79f-4f29-aaf6-4b6687baebeb
Content-Disposition: form-data; name="args"; filename="args"
Content-Type: application/json
{
"Title": "Hogweeds on the plaza",
"Description": "Could you please remove the hogweeds growing at the plaza?",
"Severity": 5,
"Attachment":
{
"Title": "Hogweed",
"Description": "Photo of the hogweeds."
}
}