Hi friends i am trying to send a post request. In wireshark body seems like that
------WebKitFormBoundaryPGENMvyXR2Vt226r
Content-Disposition: form-data; name="csrf_token"
csrf:MxLfAIgtghMohbOWeEwFv11Ou8eedDFQO0NXw6DGcZC1w1hTDo1umrysYcxho6bX
------WebKitFormBoundaryPGENMvyXR2Vt226r
Content-Disposition: form-data; name="imagefilename"; filename="myFilemain.bin"
Content-Type: application/octet-stream
...qz...OO.M..g...`.:...../o.up.........G............y......f;....&Il..*..A.........0. E.fP.P------------------here is my bin file bytes---------------
..C.x...Q..J.._+%.. bla bla
but when i post in code side it seems like that:
------WebKitFormBoundaryPGENMvyXR2Vt226r
Content-Disposition: form-data; name="csrf_token"
csrf:MxLfAIgtghMohbOWeEwFv11Ou8eedDFQO0NXw6DGcZC1w1hTDo1umrysYcxho6bX
------WebKitFormBoundaryPGENMvyXR2Vt226r
Content-Disposition: form-data; name="imagefilename"; filename="myFilemain.bin"
Content-Type: application/octet-stream
²qz‹ÁOOõMÓâg‘Ç`:Êëá‡/oåupˆéìŒÛ.Ó‰G²¹²ƒö‘•®yñúÇÌ°f;ª¥ŸÉ&Il³š*ÄAŞøØÄñŠ…¦0Ğ EfP½P
£¢CÓxÀQÃJ¥_+%ã—¢ÌGà¸,Öû¶a4ªW&Ú×zÇñg~5. ³%FÀìDëÀ²tñş)Aéåf>¥jÀƒã8 ±šeH™Íäi“ktÇ ‡0¢û³ımİp‘}à
------WebKitFormBoundaryPGENMvyXR2Vt226r--
how can i get bytes as an octetstream
here is my code:
FileInputStream fis = null;
try {
fis = new FileInputStream(uploadFile);
InputStreamReader inputStreamReader = new InputStreamReader(fis, "UTF-8");
BufferedReader br = new BufferedReader(inputStreamReader);
String line;
while ((line = br.readLine()) != null) {
builder.append(line.toCharArray());//stringBuilder
System.out.println(line.toCharArray());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
here is some information about multiPart file upload example.
Related
FedEx Address Validation API is returning encoded characters and a 400 bad request error. Here is my request body with the secret key blocked out for obvious reasons:
POST /address/v1/addresses/resolve HTTP/1.1
Content-Type: application/json
x-customer-transaction-id:
x-locale: en_US
authorization: Bearer {my secret key}
{
"addressesToValidate": [
{
"address":{
"streetLines":[
"1234 Example Rd.",
""
],
"city":"Morris",
"stateOrProvinceCode":"AL",
"postalCode":"35116",
"countryCode":"US"
}
}]
}
This is what the encoded response looks like:
HTTP/1.1 400 BadRequest
Content-Type: application/json;charset=UTF-8
Content-Encoding: gzip
Connection: close
Server-Timing: cdn-cache; desc=MISS,edge; dur=115,origin; dur=62
Content-Length: 175
Date: Tue, 28 Jun 2022 18:47:56 GMT
Server: Layer7-API-Gateway
�ʱ�0�_��l�a�Ƞ���p�6�6�#B�������;2�d���+�)�$�4�B%b�L�3
W"�%�N�L��9�<���U9n7��,���REY����{j�Z�=��í�A��Z�8�L���J�Lvp��=���M#
i������ϱ
Here is the API documentation for reference: https://developer.fedex.com/api/en-us/catalog/address-validation/v1/docs.html#operation/Validate%20Address
The answer was looking up how to decompress gzip in the language I was using. With Outsystems, I downloaded a forge component called gzip that compresses and decompresses binary to and from plaintext.
Sample syntax to decompress fedex api error messages in java
Public apiCall()
{
try{
// api call
}catch(Exception e)
{
String errorMessage = deCompress(e.getResponseBodyAsByteArray());
}
}
private static String deCompress(byte[] str) throws IOException{
String decodedString= null;
ByteArrayInputStream byteA = new ByteArrayInputStream(str);
final GZIPInputStream gzipInput = new GZIPInputStream(byteA);
InputStreamReader reader = new InputStreamReader(gzipInput);
BufferedReader in = new BufferedReader(reader);
String readed="";
String errormessage = "";
while ((readed = in.readLine()) != null) {
System.out.println(readed);
errormessage=readed;
}
return errormessage;
}
Using Spring WebFlux I would like to return Mixed-Replace HTTP Response that looks something like this:
HTTP/1.1 200 Ok
Content-Type: multipart/x-mixed-replace; boundary=--icecream
--icecream
Content-Type: image/jpeg
Content-Length: [length]
[data]
--icecream
Content-Type: image/jpeg
Content-Length: [length]
[data]
where data is streamed from Flux (think Flux.interval(1000).map(fetchImageFrame)), but I can't find a way how to stream raw HTTP response data, most of the examples gives me access to HTTP body only, but not whole response where I can control HTTP headers.
Have you tried wrapping your Flux response in a ResponseEntity and setting the required headers on the ResponseEntity?
Something like:
#GetMapping(value = "/stream")
ResponseEntity<Flux<byte[]>> streamObjects() {
Flux<byte[]> flux = Flux.fromStream(fetchImageFrame()).delayElements(Duration.ofSeconds(5));
HttpHeaders headers = HttpHeaders.writableHttpHeaders(HttpHeaders.EMPTY);
headers.add("Content-Type", "multipart/x-mixed-replace; boundary=--icecream");
return new ResponseEntity<>(flux, headers, HttpStatus.OK);
}
private Stream<byte[]> fetchImageFrame() {
return List.of(
load("image1.jpg"),
load("image2.jpg"),
load("image3.jpg"),
load("image4.jpg")
).stream();
}
private byte[] load(String name) {
try {
byte[] raw = Files.readAllBytes(Paths.get(name));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
String headers =
"--icecream\r\n" +
"Content-Type: image/jpeg\r\n" +
"Content-Length: " + raw.length + "\r\n\r\n";
bos.write(headers.getBytes());
bos.write(raw);
return bos.toByteArray();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
I have a problem with CORS from my WEB API 2 to Angular application.
Everything is working fine till now and all the response headers are receiving the following:
Access-Control-Allow-Origin:*
Cache-Control:no-cache
Content-Length:24
Content-Type:application/json; charset=utf-8
Date:Mon, 13 Nov 2017 08:15:32 GMT
Expires:-1
Pragma:no-cache
Server:Microsoft-IIS/10.0
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
X-SourceFiles:=?UTF-8?B?...
Now I created a custom IHttpActionResult like this:
public class ZipFileActionResult : IHttpActionResult
{
private const long BufferLength = 65536;
public ZipFileActionResult(string file)
{
this.Filepath = file;
}
public string Filepath { get; private set; }
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
HttpResponseMessage result = new HttpResponseMessage();
var zipf = new FilesStream(this.Filepath);
Action<Stream, HttpContent, TransportContext> writeToStream = zipf.WriteToStream;
result.Content = new PushStreamContent(writeToStream, new MediaTypeHeaderValue("application/" + "zip"));
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "filename.zip"
};
return Task.FromResult(result);
}
private async void OnStreamConnected(Stream outputStream, HttpContent content, TransportContext context)
{
try
{
var buffer = new byte[BufferLength];
using (var nypdVideo = File.Open(this.Filepath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var videoLength = (int)nypdVideo.Length;
var videoBytesRead = 1;
while (videoLength > 0 && videoBytesRead > 0)
{
videoBytesRead = nypdVideo.Read(buffer, 0, Math.Min(videoLength, buffer.Length));
await outputStream.WriteAsync(buffer, 0, videoBytesRead);
videoLength -= videoBytesRead;
}
}
}
catch (HttpException ex)
{
return;
}
finally
{
// Close output stream as we are done
outputStream.Close();
}
}
}
and I use this in my DownloadCOntroller like this:
[HttpPost]
[Route("PaperCuts")]
public IHttpActionResult PaperCuts(List<SelectionObject> selections)
{
try
{
string sFileName = <filename> + ".zip";
return new ZipFileActionResult(sFileName);
}
}
catch (Exception ex)
{
throw ex;
}
}
I'm receiving the following error when I call this function correctly:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
And I'm receiving this as response header:
HTTP/1.1 500 Internal Server Error
Cache-Control: private
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/10.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?RDpcUHJvamVjdHNcS25pcHNlbGtyYW50XEtuaXBzZWxrcmFudEFQSVxLbmlwc2Vsa3JhbnRBUElcYXBpXGRvd25sb2FkXFBhcGVyQ3V0cw==?=
X-Powered-By: ASP.NET
Date: Mon, 13 Nov 2017 08:35:33 GMT
I also have this stated in my WebApiConfig.cs (It works for all my other requests except for this one).
var corsAttr = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(corsAttr);
So the problem is that the Access-Control-Allow-Origin header etc are not same as in ALL the other requests. So how is this possible and how can I fix this?
I hope I provided enough information for my question.
Kind regards,
D.
I found the answer and got reminded by #ICantSeeSharp
I added following code in my global exception handler:
public override bool ShouldHandle(ExceptionHandlerContext context)
{
return true;
}
Hi I want to send(post/put) some data(containing string, int and Stream) from windows phone 8.1 using HttpClient to web api. what is the best way to do that.
public async void Put(string uri)
{
var httpClient = new System.Net.Http.HttpClient();
MultipartFormDataContent content = new MultipartFormDataContent();
var stringContent = new StringContent("FirstName=MUH&LastName=Test", Encoding.UTF8, "multipart/form-data");
var test = new StreamContent(new MemoryStream());
content.Add(test);
content.Add(stringContent);
var message = await httpClient.PutAsync(url+"/UpdateTest", content);
message.EnsureSuccessStatusCode();
string content1 = await message.Content.ReadAsStringAsync();
}
api method in my mvc app
[AllowAnonymous]
[Route("~/api/account/UpdateTest")]
[HttpPut]
public async Task<object> UpdateTest()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
try
{
var requestParts = await Request.Content.ReadAsMultipartAsync();
foreach (var part in requestParts.Contents)
{
//part is always StreamContent
var test = await part.ReadAsStreamAsync();
var test1 = await part.ReadAsStringAsync();
}
}
catch (Exception ex)
{ }
}
In my windows phone project I have passed 2 HttpContent, one is StreamContent where as other is StringContent. but in my web api put method both are StreamContent I do't know why.
and other problem is I have to parse the string key value in StingContnet. My question is what is the best way of sending/receiving multipart form data from windows phone 8.1 to web api,
Thanks
Following is an example(change this accordingly to your scenario):
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(baseAddress);
HttpRequestMessage request = new HttpRequestMessage();
MultipartFormDataContent mfdc = new MultipartFormDataContent();
mfdc.Add(new StringContent("Michael"), name: "FirstName");
mfdc.Add(new StringContent("Jordan"), name: "LastName");
mfdc.Add(new StreamContent(content: new MemoryStream(Encoding.UTF8.GetBytes("This is from a file"))),
name: "Data",
fileName: "File1.txt");
HttpResponseMessage response = await client.PostAsync(baseAddress + "/api/values", mfdc);
public async Task Post()
{
if (!Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.BadRequest);
}
MultipartFormDataStreamProvider prov = await Request.Content.ReadAsMultipartAsync<MultipartFormDataStreamProvider>(new MultipartFormDataStreamProvider(#"C:\uploadedfiles"));
// example of how you can read the form data
string firstName = prov.FormData["FirstName"];
// Get list of all files that have been uploaded and stored in the above provided root folder
Collection<MultipartFileData> files = prov.FileData;
}
Following is how request looks like in Fiddler tool:
POST http://localhost:9095/api/values HTTP/1.1
Content-Type: multipart/form-data; boundary="7560a854-a71a-4e55-9571-5c2de520f45f"
Host: kirandesktop:9095
Content-Length: 474
Expect: 100-continue
Connection: Keep-Alive
--7560a854-a71a-4e55-9571-5c2de520f45f
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=FirstName
Michael
--7560a854-a71a-4e55-9571-5c2de520f45f
Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name=LastName
Jordan
--7560a854-a71a-4e55-9571-5c2de520f45f
Content-Disposition: form-data; name=Data; filename=File1.txt; filename*=utf-8''File1.txt
This is from a file
--7560a854-a71a-4e55-9571-5c2de520f45f--
Also note that you can read the StreamContent anyway you want...in the following examples, I am simulating a request's body stream and reading it as a simple string or deserializing into an object of type Person.
StreamContent requestStream = new StreamContent(new MemoryStream(Encoding.UTF8.GetBytes("Hello World!")));
string data = await requestStream.ReadAsStringAsync();
//---------------------
StreamContent requestStream = new StreamContent(new MemoryStream(Encoding.UTF8.GetBytes("{ \"FirstName\" : \"Michael\" }")));
requestStream.Headers.ContentType = new MediaTypeHeaderValue("application/json");
Person person = await requestStream.ReadAsAsync<Person>();
I use a custom media type formatter that's based on the code in this article.
ASP.NET WebApi: MultipartDataMediaFormatter
One of the advantages over the MultipartFormDataStreamProvider is that I don't need to specify a folder to save the file data, so I can inspect the contents in memory. You might not want to do this with huge files though. There's alot a github repo for it too if you want to look at the code. Also, I get strongly typed objects for file and form data
I am trying to upload a file with additional form data and post to Web API via MVC but i couldn't accomplish.
MVC Side
Firstly i got the submitted form at MVC. Here is the action for this.
[HttpPost]
public async Task<ActionResult> Edit(BrandInfo entity) {
try {
byte[] logoData = null;
if(Request.Files.Count > 0) {
HttpPostedFileBase logo = Request.Files[0];
logoData = new byte[logo.ContentLength];
logo.InputStream.Read(logoData, 0, logo.ContentLength);
entity.Logo = logo.FileName;
entity = await _repo.Update(entity.BrandID, entity, logoData);
}
else
entity = await _repo.Update(entity,entity.BrandID);
return RedirectToAction("Index", "Brand");
}
catch(HttpApiRequestException e) {
// logging, etc
return RedirectToAction("Index", "Brand");
}
}
Below code post the Multipartform to Web API
string requestUri = UriUtil.BuildRequestUri(_baseUri, uriTemplate, uriParameters: uriParameters);
MultipartFormDataContent formData = new MultipartFormDataContent();
StreamContent streamContent = null;
streamContent = new StreamContent(new MemoryStream(byteData));
streamContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") {
FileName = "\"" + fileName + "\"",
Name = "\"filename\""
};
streamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
formData.Add(streamContent);
formData.Add(new ObjectContent<TRequestModel>(requestModel, _writerMediaTypeFormatter), "entity");
return _httpClient.PutAsync(requestUri, formData).GetHttpApiResponseAsync<TResult>(_formatters);
As you can see i am trying to send file data and object with same MultipartFormDataContent. I couldn't find better way to send my entity as ObjectContent. Also i am using JSON.Net Serializer
Regarding to fiddler, post seems successfull.
PUT http://localhost:12836/api/brand/updatewithlogo/13 HTTP/1.1
Content-Type: multipart/form-data; boundary="10255239-d2a3-449d-8fad-2f31b1d00d2a"
Host: localhost:12836
Content-Length: 4341
Expect: 100-continue
--10255239-d2a3-449d-8fad-2f31b1d00d2a
Content-Disposition: form-data; filename="web-host-logo.gif"; name="filename"
Content-Type: application/octet-stream
GIF89a��L������X�������wW����������xH�U�)�-�k6�������v6�������̥�v�J���������7����V:�=#�ի�I(�xf�$�������
// byte data
// byte data
'pf�Y��y�ؙ�ڹ�(�;
--10255239-d2a3-449d-8fad-2f31b1d00d2a
Content-Type: application/json; charset=utf-8
Content-Disposition: form-data; name=entity
{"BrandID":13,"AssetType":null,"AssetTypeID":2,"Logo":"web-host-logo.gif","Name":"Geçici Brand","Models":null,"SupplierBrands":null}
--10255239-d2a3-449d-8fad-2f31b1d00d2a--
Web API Side
Finally i am catching post at Web API side and trying to parse but i couldn't. Because MultipartFormDataStreamProvider's FileData and FormData collections are allways empty.
[HttpPut]
public void UpdateWithLogo(int id) {
if(Request.Content.IsMimeMultipartContent()) {
var x = 1; // this code has no sense, only here to check IsMimeMultipartContent
}
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
try {
// Read the form data.
Request.Content.ReadAsMultipartAsync(provider);
foreach(var key in provider.FormData.AllKeys) {
foreach(var val in provider.FormData.GetValues(key)) {
_logger.Info(string.Format("{0}: {1}", key, val));
}
}
// This illustrates how to get the file names.
foreach(MultipartFileData file in provider.FileData) {
_logger.Info(file.Headers.ContentDisposition.FileName);
_logger.Info("Server file path: " + file.LocalFileName);
}
}
catch(Exception e) {
throw new HttpApiRequestException("Error", HttpStatusCode.InternalServerError, null);
}
}
I hope you can help to find my mistake.
UPDATE
I also realized that, if i comment out StreamContent or ObjectContent and only add StringContent, still i can't get anything from MultipartFormDataStreamProvider.
Finally i resolved my problem and it was all about async :)
As you can see at API action method i had called ReadAsMultipartAsync method synchrously but this was a mistake. I had to call it with ContinueWith so after i changed my code like below my problem solved.
var files = Request.Content.ReadAsMultipartAsync(provider).ContinueWith<HttpResponseMessage>(task => {
if(task.IsFaulted)
throw task.Exception;
// do additional stuff
});