Sorry in advance for the newbie question.
I am using ASIHTTPRequest to send and receive packets.
However, when I send a packet from the client to the server, the packet has a header attached to it:
POST / HTTP/1.1
Host: 192.168.0.6:8080
Accept-Encoding: gzip
Content-Length: 64
User-Agent: ASIHTTPRequestTests 1.0 (iPod touch; iPhone OS 4.1; ko_KR)
Connection: close
PACKET_TESTM0001
The only information I want my client to send is: PACKET_TESTM0001
Is there a way to remove all the above header (All lines including POST to User-Agent)
Thanks in advance for your helpful response.
That header is required by the HTTP protocol, so better you don't remove it or your web server will not accept the request.
If you do no want to use the HTTP protocol (i.e., you do not want to talk to a web server), then you can use NSStreams with sockets.
There's some confusion here between "packet" and "HTTP request". Googling those two terms would probably be enlightening for you.
ASIHTTPRequest makes, as the name implies, HTTP requests. It wants to be talking to an HTTP server, and then probably to some sort of server-side code to process the request.
Have you rolled your own server, here? Because you're not doing what is expected when you're talking HTTP.
Related
I am making a banner grabber and have finally ironed out the HEAD / HTTP/1.1 request according to the guidelines, but some websites still give me '400 Bad Request'
why is that?
Here is my request:
"HEAD / HTTP/1.1\r\nHost: target:port\r\nConnection: close\r\n\r\n"
Should the Head: be Host: ? Apart from that, sites might block the HEAD request, i.e. there is no requirement that they must offer it. Also, the target you give in the Host header might not match a name setup on the server. Nevertheless you might get the servers banner (I.e. Server header I suppose) from the 400 response too, if the server sends such header at all (not required).
– Steffen Ullrich
What is the correct fallback if Content-Negotiation does not find a reasonable result due to a non 2xx status code? For example:
A client wants to download a PDF and sends following header Accept: application/pdf. Due to insufficient privileges the server would return a 403 Forbidden. You might want to explain the reason in more detail but it does not make much sense to return a PDF. How would you deal with that?
Should the server return an empty body? Should he ignore the Accept header and send some other representation like text/plain. Or is it the job of the client to provide alternatives per Accept: application/pdf, text/plain, */*.
Obviously if the user does not have permission to access the resource, there is no real alternative what a server can do. The server can however respond with content (even in an error case) which describes the error in more detail, if that response can be made using a media-type accepted by the client. The client should provide an Accept: header that describes all the media-types it can parse. So an automatic client would be able to do:
Accept: application/pdf, application/vnd.myapi.error
If content-negotiation fails, the returned code should be 406 Not Acceptable. The server can produce this if it can not provide any answer which would be acceptable to the client.
However, the specification states that the server may actually return an answer not explicitly acceptable by the client if it wants to, it is up to the client, to inspect the response headers to see what media-type the answer is.
Source: https://www.rfc-editor.org/rfc/rfc7231#section-3.4.1
I have used a proxy tool to capture a certain REST HttpRequest. The request is a HTTP PUT command followed by an extremely long REST link containing specific data that gets sent to the server.
In the proxy tool it looks something like this:
Header
PUT http://XXX.XXX.XXX.XXX:8080/rest/blah/blah/.../ HTTP/1.1
Host: XXX.XXX.XXX.XXX:8080
User-Agent: Mozilla/5.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-language: en-us, en:q=0.5
Proxy Connection:keep-alive
Content-Type:XMLHttpRequest
Referer: http://XXX.XXX.XXX.XXX:8080/plugins/blah/blah
Content-length: 11156
Cookie: JSESSIONID=<really long alpha numeric>
Body:
{"links":{"self":"/rest/plugins/1.0/blah/blah.....
...
... lots and lots of JSON text
}
}
So the proxy tool has been helpful in identifying what the request looks like.
But the only way to generate this request is by clicking a button on the webpage. I would like to send exact same request on my own (like creating a custom link that when clicked generates a similar request to the one shown above). How do I do this?
Also, anything I type in the web browser URL area automatically is a "GET". How do I force a PUT?
Cookie: JSESSIONID=
This clearly indicates that the API you want to use is not a REST API, because it violates the stateless constraint of REST.
How do I force a PUT?
Probably you don't have a way to do that. It depends on the security settings of the web API. If you want to do this with AJAX from the browser, and your domain is different from the APIs domain, then you need a CORS header from the API, which allows your domain to read cross origin responses. By PUT the browsers sends a preflight first, and if it cannot read the response, it will never send the real PUT. Security policy and other headers can block XSS in the browser, so you probably don't have a way to do this from browser.
You can do this from your server by copying the request details and catching the session id somehow.
If the API allows access to 3rd party clients, then I suggest you to contact with them. If not, then you 99% that you won't be able to do this.
I am building a web application which can accept resource representations via PUT, POST and PATCH in both x-www-form-urlencoded and JSON formats. If I receive a request body in another format, I would like to send a 415 response, plus some additional data declaring what formats I do accept (in a similar manner to the 405 response's mandatory Allow: header). I have seen on one answer at HTTP 406 and 415 error codes where the person answering did not know if there was such a mechanism defined, RFC 2616 mentions nothing in this regard, and some cursory Googling turns up nothing either.
I would like to just use Accept: even though that is defined as a request header. It seems most appropriate just to re-use it for this response. Do folks agree? Does anyone have a better suggestion?
Edit: I have since found Specify supported media types when sending "415 unsupported media type" which asks specifically if there is a standard for this. The correct and accepted answer was basically no, but the respondant there also had the same idea as me, that Accept would be a good header to use to provide this information. This prompted a message from Julian Reschke to the HTTP Working Group asking if it should be defined what sending an Accept: header in a response should mean. That email only received one response, which agreed that it was needed and that Accept seemed appropriate.
Note that I am not asking if I am permitted to send an Accept header, any header is allowed to be sent in either direction, but only those defined in the spec have meaning (semantics) to intermediaries, and also, any unexpected headers not prefixed with X- might clash with future versions of HTTP. This doesn't bother me.
As you said, Accept is a request-header. It is wrong to use it in a response.
To quote Wikipedia,
Content negotiation is a mechanism defined in the HTTP specification that makes it possible to serve different versions of a document (or more generally, a resource representation) at the same URI, so that user agents can specify which version fit their capabilities the best.
So it is the client who says in the request what media types he can Accept. If the server is not able to deliver this media type he responds with 406 Not Acceptable.
Since the client must be able to deal with the returned representation of the requested resource, it should specify which media types it can understand. It can specifiy multiple media types:
Accept: application/json, application/xml, x-www-form-urlencoded
If the client really wants to accept any media type, it can set
Accept: */*
The server will set a proper Content-Type response header even for such a request.
You receiving an unrecognized Content-Type will most probably be from a developer currently implementing a client to your service. Since there does not exist a mechanism for a server to advertise its supported content types, you might as well mention in the message body what types you do support.
I'm not aware of any standard mechanism to do this but you may be able to slightly re-purpose the Alternates header http://www.ietf.org/rfc/rfc2295.txt to do what you want.
Ok, I'm confused. I'm trying to send back the magic headers from my server that will prevent a client from hitting the server again until a resource is stale.
I understand how ETag or Last-Modified works (Validation) - the client will ALWAYS still hit the server, and the server needs to validate the date or etag against the current value to know whether to bother serving up a new one.
Cache-Control and Expires, however, I don't think I understand. I've set the following:
Cache-Control: max-age=86400, must-revalidate
No matter what I do, my client (my browser, curl, NSURLConnection) always hits the server again on the second request. Is this a client thing? What headers should I send back to get the client to use it's private cache for a certain length of time?
As Nathan hints at in his answer, clients can issue a subsequent request with an If-Modified-Since header to determine whether or not their cache is stale. If the client receives a 304 Not Modified response, it will serve the content out of the local cache.
According to RFC 2616 (the HTTP 1.1 specification), the presence of must-revalidate within the Cache-control header forces clients to re-check their cache's status with the originating server prior to serving out of the cache.
For future reference - Mark Nottingham has written a great guide to HTTP caching:
http://www.mnot.net/cache_docs/#CACHE-CONTROL
The server needs to check the If-Modified-Since header and return a 304 not modified header if it wants the browser to keep caching.