How to handle string response in swift 3 using alamofire - swift3

I am trying to hit the url whose response is:
"dbdg96t7331e150600836bc5dc026cc1649a887fc8b921b6111172db399d03566a944946e3cd13246901128413c3c9673d4e806a4v7j2yxe".
So how can I handle this string from response? Here is my code:
temp = "Resident|" + user_uid
let url = "http://api.appname.my/encodedecode.php?text=\(temp)"
Alamofire.request(url).responseJSON { (responseObject) -> Void in
print(responseObject)
}
In response I am getting this:
FAILURE: invalidURL("http://api.appname.my/encodedecode.php?text=Resident|uP6zkPihw1MPleJQ44WV1rsH1dO2")

The pipe (|) needs to be escaped in an URL
temp = ("Resident|" + user_uid).addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!
and Alamofire.request might expect a real URL object
let url = URL(string: "http://api.appname.my/encodedecode.php?text=\(temp)")!

Related

How to get download file size before download using C/C++ in Linux environment [duplicate]

I want to get the size of an http:/.../file before I download it. The file can be a webpage, image, or a media file. Can this be done with HTTP headers? How do I download just the file HTTP header?
Yes, assuming the HTTP server you're talking to supports/allows this:
public long GetFileSize(string url)
{
long result = -1;
System.Net.WebRequest req = System.Net.WebRequest.Create(url);
req.Method = "HEAD";
using (System.Net.WebResponse resp = req.GetResponse())
{
if (long.TryParse(resp.Headers.Get("Content-Length"), out long ContentLength))
{
result = ContentLength;
}
}
return result;
}
If using the HEAD method is not allowed, or the Content-Length header is not present in the server reply, the only way to determine the size of the content on the server is to download it. Since this is not particularly reliable, most servers will include this information.
Can this be done with HTTP headers?
Yes, this is the way to go. If the information is provided, it's in the header as the Content-Length. Note, however, that this is not necessarily the case.
Downloading only the header can be done using a HEAD request instead of GET. Maybe the following code helps:
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://example.com/");
req.Method = "HEAD";
long len;
using(HttpWebResponse resp = (HttpWebResponse)(req.GetResponse()))
{
len = resp.ContentLength;
}
Notice the property for the content length on the HttpWebResponse object – no need to parse the Content-Length header manually.
Note that not every server accepts HTTP HEAD requests. One alternative approach to get the file size is to make an HTTP GET call to the server requesting only a portion of the file to keep the response small and retrieve the file size from the metadata that is returned as part of the response content header.
The standard System.Net.Http.HttpClient can be used to accomplish this. The partial content is requested by setting a byte range on the request message header as:
request.Headers.Range = new RangeHeaderValue(startByte, endByte)
The server responds with a message containing the requested range as well as the entire file size. This information is returned in the response content header (response.Content.Header) with the key "Content-Range".
Here's an example of the content range in the response message content header:
{
"Key": "Content-Range",
"Value": [
"bytes 0-15/2328372"
]
}
In this example the header value implies the response contains bytes 0 to 15 (i.e., 16 bytes total) and the file is 2,328,372 bytes in its entirety.
Here's a sample implementation of this method:
public static class HttpClientExtensions
{
public static async Task<long> GetContentSizeAsync(this System.Net.Http.HttpClient client, string url)
{
using (var request = new System.Net.Http.HttpRequestMessage(System.Net.Http.HttpMethod.Get, url))
{
// In order to keep the response as small as possible, set the requested byte range to [0,0] (i.e., only the first byte)
request.Headers.Range = new System.Net.Http.Headers.RangeHeaderValue(from: 0, to: 0);
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
if (response.StatusCode != System.Net.HttpStatusCode.PartialContent)
throw new System.Net.WebException($"expected partial content response ({System.Net.HttpStatusCode.PartialContent}), instead received: {response.StatusCode}");
var contentRange = response.Content.Headers.GetValues(#"Content-Range").Single();
var lengthString = System.Text.RegularExpressions.Regex.Match(contentRange, #"(?<=^bytes\s[0-9]+\-[0-9]+/)[0-9]+$").Value;
return long.Parse(lengthString);
}
}
}
}
WebClient webClient = new WebClient();
webClient.OpenRead("http://stackoverflow.com/robots.txt");
long totalSizeBytes= Convert.ToInt64(webClient.ResponseHeaders["Content-Length"]);
Console.WriteLine((totalSizeBytes));
HttpClient client = new HttpClient(
new HttpClientHandler() {
Proxy = null, UseProxy = false
} // removes the delay getting a response from the server, if you not use Proxy
);
public async Task<long?> GetContentSizeAsync(string url) {
using (HttpResponseMessage responce = await client.GetAsync(url))
return responce.Content.Headers.ContentLength;
}

Google Apps Script - find string and return the following characters

The output in the log should be " scripting" because these are the next 10 characters followed by the search criteria "general-purpose". Please visit www.php.net to see what I mean, you will find the search string "general-purpose" on top of www.php.net. I think that I have done some more mistakes in this piece of code, right?
function parse() {
// parse site and store html in response
var response = UrlFetchApp.fetch('www.php.net').getContentText();
// declare search string and new regex object
var str = "/general-purpose/+10-following-charcters";
var regExp = new RegExp("/general-purpose/.{0,10}", "gi");
// find the string "general-purpose" and store the next 10 characters in response
var response = regExp.exec(str[0]);
// expected result in logger output is " scripting"
Logger.log(response);
}
It should be general-purpose(.{0,10}) and not /general-purpose/.{0,10}.
Also regExp.exec(str[0]) should be regExp.exec(str)[1].
This code seems to work fine
var str = UrlFetchApp.fetch('www.php.net').getContentText();
var regExp = new RegExp("general-purpose(.{0,10})", "gi");
var response = regExp.exec(str)[1];
Logger.log(response);

Sending Multiple images from web service SPRINGBOOT+REST+MAVEN

I am writing a web service in spring boot restful web App using which i am sending a image to anyone who wants to consume it below is a code snippet which worked for me
#RequestMapping(value = "/photo_1",method = RequestMethod.GET )
public ResponseEntity<byte[]> greeting_image_1(#RequestParam(value="name", defaultValue="World") String name) throws IOException{
InputStream in = getClass().getResourceAsStream("/images/someimage.jpg");
byte[] a = IOUtils.toByteArray(in);
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_JPEG);
return new ResponseEntity<byte[]>(a,headers,HttpStatus.CREATED);
}
This web service works perfectly fine in case i want to return a single image from a web service
But what if in case i want to return array of images(i.e. more than 1 image)
Any help is highly appreciated.
Regards,
Here's the sample code that I wrote to generate a multipart response with multiple images in it. It's properly consumed by Firefox and it prompts to save each image in the response.
public ResponseEntity<byte[]> showImages () throws IOException {
String boundary="---------THIS_IS_THE_BOUNDARY";
List<String> imageNames = Arrays.asList(new String[]{"1.jpg","2.jpg"});
List<String> contentTypes = Arrays.asList(new String[]{MediaType.IMAGE_JPEG_VALUE,MediaType.IMAGE_JPEG_VALUE});
List<Byte[]> imagesData = new ArrayList<Byte[]>();
imagesData.add(ArrayUtils.toObject(IOUtils.toByteArray(getClass().getResourceAsStream("/images/1.jpg"))));
imagesData.add(ArrayUtils.toObject(IOUtils.toByteArray(getClass().getResourceAsStream("/images/2.jpg"))));
byte[] allImages = getMultipleImageResponse(boundary, imageNames,contentTypes, imagesData);
final HttpHeaders headers = new HttpHeaders();
headers.set("Content-Type","multipart/x-mixed-replace; boundary=" + boundary);
return new ResponseEntity<byte[]>(allImages,headers,HttpStatus.CREATED);
}
private static byte[] getMultipleImageResponse(String boundary, List<String> imageNames, List<String> contentTypes, List<Byte[]> imagesData){
byte[] finalByteArray = new byte[0];
Integer imagesCounter = -1;
for(String imageName : imageNames){
imagesCounter++;
String header="--" + boundary
+ "\r\nContent-Disposition: form-data; name=\"" + imageName
+ "\"; filename=\"" + imageName + "\"\r\n"
+ "Content-type: " + contentTypes.get(imagesCounter) + "\r\n\r\n";
byte[] currentImageByteArray=ArrayUtils.addAll(header.getBytes(), ArrayUtils.toPrimitive(imagesData.get(imagesCounter)));
finalByteArray = ArrayUtils.addAll(finalByteArray,ArrayUtils.addAll(currentImageByteArray, "\r\n\r\n".getBytes()));
if (imagesCounter == imageNames.size() - 1) {
String end = "--" + boundary + "--";
finalByteArray = ArrayUtils.addAll(finalByteArray, end.getBytes());
}
}
return finalByteArray;
}
You should implement this depending on the capability of the consumer. If the consumer can parse multipart response, please go ahead with this approach, else consider other options like
Sending a zipped file of all images
Returning a json/xml of image names along with URLs to download them
Returning a json/xml with all images in Base64 encoded string
You may also send a html response with all images embedded in it using the below code. This should work fine in all browsers as it is pure html.
public ResponseEntity<byte[]> getAllImages() throws IOException {
List<String> imageNames = Arrays.asList(new String[]{"1.jpg","2.jpg"});
List<String> contentTypes = Arrays.asList(new String[]{MediaType.IMAGE_JPEG_VALUE,MediaType.IMAGE_JPEG_VALUE});
List<Byte[]> imagesData = new ArrayList<Byte[]>();
imagesData.add(ArrayUtils.toObject(IOUtils.toByteArray(getClass().getResourceAsStream("/images/1.jpg"))));
imagesData.add(ArrayUtils.toObject(IOUtils.toByteArray(getClass().getResourceAsStream("/images/2.jpg"))));
byte[] htmlData=getHtmlData(imageNames,contentTypes, imagesData);
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_HTML);
return new ResponseEntity<byte[]>(htmlData,headers,HttpStatus.OK);
}
private static byte[] getHtmlData(List<String> imageNames, List<String> contentTypes, List<Byte[]> imagesData){
String htmlContent="<!DOCTYPE html><html><head><title>Images</title></head><body>";
Integer imagesCounter = -1;
for(String imageName : imageNames){
imagesCounter++;
htmlContent = htmlContent + "<br/><br/><b>" + imageName + "</b><br/></br/><img src='data:" + contentTypes.get(imagesCounter) + ";base64, " + org.apache.commons.codec.binary.StringUtils.newStringUtf8(Base64
.encodeBase64(ArrayUtils.toPrimitive(imagesData.get(imagesCounter)))) + "'/>";
}
htmlContent = htmlContent + "</body></html>";
return htmlContent.getBytes();
}
You should take a look to "Uploading Files" Spring Boot guide : https://spring.io/guides/gs/uploading-files/
There's a an example of upload and download.

JSON.parse error on simplejson return in Django

I have a view page that currently has two columns of data shown, soon to be expanded to four. Each column contains the result of a QuerySet for that particular model.
Here's what I have in my views.py method:
if request.REQUEST["type"] == "text":
client = Client.objects.get(client_name = request.REQUEST["search"])
peerList = ClientPeers.objects.prefetch_related().filter(client = client.client)
compList = ClientCompetitors.objects.prefetch_related().filter(client = client.client)
else:
peerList = ClientPeers.objects.prefetch_related().filter(client = request.REQUEST["search"])
compList = ClientCompetitors.objects.prefetch_related().filter(client = request.REQUEST["search"])
for peer in peerList:
peerlst.append({"pid" : peer.parentorg.parentorg, "pname" : peer.parentorg.parentorgname})
for comp in compList:
complst.append({"cid" : comp.parentorg.parentorg, "cname" : comp.parentorg.parentorgname})
lst.append(simplejson.dumps(peerlst))
lst.append(simplejson.dumps(complst))
return HttpResponse(simplejson.dumps(lst), mimetype = "text/json")
This allows me to send a 2D array of data to the browser in the format
[ { //JSON }, { //JSON } ]
In my jQuery.ajax success function, I have
function handler(results) {
var data = JSON.parse(results);
for (var i = 0; i < data[0].length; i++)
$("#available_peers").append("<li>" + data[0][i].pname + "</li>");
for (var i = 0; i < data[1].length; i++)
$("#available_competitors").append("<li>" + data[1][i].cname + "</li>");
Firebug shows that the GET request works and I can see the data in the response tab. However, the console prints out
SyntaxError: JSON.parse: unexpected non-whitespace character after JSON data
var data = JSON.parse(results)
This error disappears if I replace var data = JSON.parse(results) with
var peers = JSON.parse(data[0]);
var comps = JSON.parse(data[1]);
Why does one method work but another doesn't?
The jQuery ajax() call will make an intelligent guess as to the returned data type. In your example, function handler(results), the results variable will already be a decoded JSON object, containing two items in an array. The reason that JSON.parse(data[0]) works, is that you have returned JSON encoded data as a string.
Don't encode the individual list elements to JSON before placing in the output array:
lst.append(peerlst) # <-- Don't encode to JSON string here
lst.append(complst)
return HttpResponse(simplejson.dumps(lst), mimetype = "application/json") # <-- Single JSON encoding

Facebook notification encoding

When using Facebook Graph API to send some notification to my users, it delivers scrambled to them, like so:
Here is my code:
public void sendFBNotificationByUserID(Guid userID, string msg, string url)
{
try
{
// Facebook information from the user
FacebookUser fbUser = getFacebookUserByUserID(userID);
using (WebClient wc = new WebClient())
{
// Retrieve "App Access Token" from Facebook
string appAccessToken = wc.DownloadString("https://graph.facebook.com/oauth/access_token?client_id=" + Global.fbAppID + "&client_secret=" + Global.fbAppSecret + "&grant_type=client_credentials");
// Create POST parameters
string POSTparam = "template=" + msg + "&href=" + url + "&" + appAccessToken;
// POST to Facebook Graph API to send notification
wc.UploadString("https://graph.facebook.com/" + fbUser.facebookID + "/notifications/", POSTparam);
}
}
catch (Exception)
{
}
}
Any idea?
EDIT:
I did a little reading about URL Encoding and this code solved my problem:
msg = HttpUtility.UrlEncode(msg);
This could be because of the encoding of your page. Some characters get scrambled if they aren't encoded properly. Maybe try using UTF-8 or something else.
Best I could think of.