upload small thumbnail images from iPhone app to Amazon S3 - iphone

I noticed couple thread on this already and they even provided sample code.
http://brunofuster.wordpress.com/2010/11/03/uploading-an-image-from-iphone-with-uiimagepicker-and-asihttprequests3/
But what baffled me is that - there was no response to get handled? is it because that s3 doesn't return any response? I am expecting to receive at least an URL to the image on S3, how could I get that?

If you look at the S3 REST object PUT documentation you will see the response that is returned from S3.
When you post to S3 you know the bucket name you are putting the image into plus you know the filename. These two pieces of information should be all you need to get a url to the image.
The documentation states that in addition to the PUT response header(s) you can see some of the common headers too.
This implementation of the operation
can include the following response
headers in addition to the response
headers common to all responses. For
more information, see Common Response
Headers.
If you look at the ASIHTTPRequest Amazon Simple Storage Service (S3) support you will see how to get a response from the ASIS3ObjectRequest object.

Tom,
If you wish to just get your S3 image url, you don't need the response information considering you already know the image name and the bucket (if there was no error).
Anyway, you can get the response from a sync request by using [request responseString|responseData].
But the right thing to do is an async call using operation queues and delegates to get the response success or error. My blog post just provided a minimal sample. I will look into that and improve the post itself.
Thanks!

In addition to the answers already provided, you might also want to look at Amazon's recently released AWS SDK for iOS, which includes sample code for uploading images, etc. to S3.

Related

Is adding an image to a GET request a bad design pattern?

Let me set up a very specific use case...
Let's say that you're creating a facial recognition API using Python. When you upload an image to the API at an unspecified route, you get back a list of identities that match that image... the return object is an array: ['tom', 'brad', 'john'].
You're not uploading any data to be created or kept on the server.
You're not updating or creating anything.
What kind of request should this be? I'd assume a GET request because you're GETting the identities of the people in the uploaded image regardless of the fact that you're sending an image for processing.
I'd assume a GET request because you're GETting the identities of the people in the uploaded image regardless of the fact that you're sending an image for processing
Sadly, no. The problem here is that GET, in HTTP, does describe the semantics of a message body on the request.
A payload within a GET request message has no defined semantics; sending a payload body on a GET request might cause some existing implementations to reject the request.
You've got the right idea - the request should be safe, so you can look at the HTTP Method Registry to see if there is a match. That might lead you to SEARCH or REPORT. These methods are extensions defined by WebDAV, and may or may not be suitable for your problem.
If it is acceptable to include the representation of the image in the query string, you could pair that with GET. I suspect you'll run into problems with components complaining that the identifier is too long.
The TL;DR? use the POST method to deliver the image payload to the server.

REST Api - Created resource redirect

I'm building REST API, and when resource is created normally I return HTTP 201 Created along with Location header to specify where that resource is located. But from some reason http client is not redirecting.
I'm using Postman for this. Does anyone have idea on this problem?
In short, a Location header is not sufficient to trigger a client redirect. It must be used in conjunction with a 3xx HTTP status code.
References:
https://en.m.wikipedia.org/wiki/HTTP_location
Redirecting with a 201 created
This is one of those things where the expectation does not meet what actually happens, and the first thing people think is "well that doesn't work properly", as has been suggested in other comments.
The Location is just a random header, and clients, such as Postman or curl or anything else need to be instructed to follow them. Most won't do this by default, as that is an unreasonable default.
YouTube for example returns a body for some responses and a Location tag too. One example would be video uploads. They respond to your original meta-data for the video is sent with a POST, and they shove a Location URL which is the endpoint to upload the video too. If clients just randomly redirected to that you'd be having a bad time.
You can use Paw to make a "sequence", which I believe will let you take values from headers to reuse. This is also possible with Runscope Ghostinspector.

Google Cloud Storage: Setting incorrect MIME-type

I have a Node.js server running on a Google Compute Engine virtual instance. The server streams incoming files to Google Cloud Storage GCS. My code is here: Node.js stream upload directly to Google Cloud Storage
I'm passing Content-Type in the XML headers and it's working just fine for image/jpeg MIME-types, but for video/mp4 GCS is writing files as application/octet-stream.
There's not much to this, so I'm totally at a loss for what could be wrong ... any ideas are welcome!
Update/Solution
The problem was due to the fact that the multiparty module was creating content-type: octet-stream headers on the 'part' object that I was passing into the pipe to GCS. This caused GCS to receive two content-types, of which the octet part was last. As a result, GCS was using this for the inbound file.
Ok, looking at your HTTP request and response it seems like content-type is specified in the URL returned as part of the initial HTTP request. The initial HTTP request should return the endpoint which can be used to upload the file. I'm not sure why that is specified there but looking at the documentation (https://developers.google.com/storage/docs/json_api/v1/how-tos/upload - start a resumable session) it says that X-Upload-Content-Type needs to be specified, along some other headers. This doesn't seem to be specified in HTTP requests that were mentioned above. There might be an issue with the library used but the returned endpoint does not look as what is specified in the documentation.
Have a look at https://developers.google.com/storage/docs/json_api/v1/how-tos/upload, "Example: Resumable session initiation request" and see if you still have the same issue if you specify the same headers as suggested there.
Google Cloud Storage is content-type agnostic, i.e., it treats any kind of content in the same way (videos, music, zip files, documents, you name it).
But just to give some idea,
First I believe that the video () you are uploading is more or less size after it being uploded. so , it falls in application/<sub type>. (similar to section 3.3 of RFC 4337)
To make this correct, I believe you need to fight with storing mp4 metadata before and after the file being uploaded.
please let us know of your solution.
A solution that worked for me in a similar situation is below. TLDR: Save video from web app to GCS with content type video/mp4 instead of application/stream.
Here is the situation. You want to record video in the browser and save it to Google Cloud Storage with a content type set to video/mp4 instead of application/octet-stream. User records video and clicks button to send video file to your server for saving. After sending the video file from the client to your server, the server sends the video file to Google Cloud Storage for saving.
You successfully save the video to Google Cloud Storage and by default GCS assigns a content type of application/octet-stream to the video.
To assign a content type video/mp4 instead of application/octet-stream, here is some server-side Python code that works.
storage_client = storage.Client()
bucket = storage_client.bucket(bucket_name)
blob = bucket.blob(destination_blob_name)
blob.upload_from_file(file_obj, rewind=True)
blob.content_type = 'video/mp4'
blob.patch()
Here are some links that might help.
https://cloud.google.com/storage/docs/uploading-objects#storage-upload-object-python
https://stackoverflow.com/a/33320634/19829260
https://stackoverflow.com/a/64274097/19829260
NOTE: at the time of this writing, the Google Docs about editing metadata don't work for me because they say to set metadata but metadata seems to be read-only (see SO post https://stackoverflow.com/a/33320634/19829260)
https://cloud.google.com/storage/docs/viewing-editing-metadata#edit

Post JSON data to Facebook

In the app, I want to post a photo, and some text. I am able to post if I am using local stored data in resources but when data (in JSON format) is coming from server at the run time, I am not able to post that image and text which is coming from server in the JSON format.
Is there any way to post data at the runtime or I have to store the data at the client side, but in that case, the app will be bulky because data could be different at different locations?
I am not sure but you may be asking about posting an image using a URL instead of assuming data is local. If so, see this blog post - https://developers.facebook.com/blog/post/526/ and it introduced the ability to post an image by passing in a "url" parameter through the Graph API.

How Do I Upload Multiple Files Using the iPhone

I am posting (HTTP POST) various values to the posterous api. I am successfully able to upload the title, body, and ONE media file, but when I try to add in a second media file I get a server 500.
They do allow media and media[] as parameters.
How do I upload multiple files with the iPhone SDK?
The 500 your getting is probably based on one of two things:
An incorrect request
An error on the server
Now, if its an incorrect, the HTTP server would be more helpful responding back with like a 415 (unsupported media type) or something. A 500 insists that something went wrong on the server and that your request was valid.
You'll have to dig into the server API or code (if you wrote it), or read the docs and figure out what's wrong with your second request ... seems like maybe your not setting the appropriate media type?
EDIT: Ok, so I looked at the API. It appears your posting XML, so your request content-type should be
Content-Type: application/xml
The API doc didn't specifically say, but that would be the correct type.
EDIT: Actually on second glance, are you just POSTing w/URI params? Their API doc isn't clear (I'm also looking rather quickly)