In python3 ,I was trying to see the header values sent in the request
>>from urllib.request import urlopen
>> url1='http://diveintopython3.org/examples/feed.xml'
>>from http.client import HTTPConnection as httpcon
>>httpcon.debuglevel = 1
>>resp1 = urlopen(url1)
this produced
send: b'GET /examples/feed.xml HTTP/1.1\r\nAccept-Encoding: identity\r\nHost: diveintopython3.org\r\nUser-Agent: Python-urllib/3.3\r\nConnection: close\r\n\r\n'
reply: 'HTTP/1.1 200 OK\r\n'
header: Cache-Control header: Pragma header: Content-Type header: Expires header: Server header: X-AspNet-Version header: X-Powered-By header: Date header: Content-Length header: Age header: Connection
whereas curl gives me the header values
$curl -I http://diveintopython3.org/examples/feed.xml
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 783
Content-Type: text/html; charset=utf-8
Expires: -1
Server: ATS/3.2.4
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Fri, 31 May 2013 02:48:12 GMT
Age: 0
Connection: keep-alive
what should I do to get the header values listed (as debug info) in python3 ?
The object returned by urllib.request.urlopen being an http.client.HTTPResponse object, you can use all of the methods it defines. There is one called getheaders which does what you want:
>>> from urllib.request import urlopen
>>> url1 = 'http://diveintopython3.org/examples/feed.xml'
>>> r = urlopen(url1)
>>> r.getheaders()
[('Cache-Control', 'no-cache'), ('Pragma', 'no-cache'), ('Content-Type', 'text/html; charset=utf-8'), ('Expires', '-1'), ('Server', 'ATS/3.2.4'), ('X-AspNet-Version', '4.0.30319'), ('X-Powered-By', 'ASP.NET'), ('Date', 'Fri, 31 May 2013 11:43:46 GMT'), ('Content-Length', '783'), ('Age', '0'), ('Connection', 'close')]
See the http.client documentation for more infos.
Related
I am working on a HTTPS POST request which contains two multipart/form-data entries.
But for whatever reason I can't get it working.
This is the request I am sending:
POST /my/api/endpoint HTTP/1.0
Host: myserver.de
Content-Type: multipart/form-data; boundary=123456
Content-Length: 147
Connection: close
X-API-KEY: 123
--123456
Content-Disposition: form-data; name="edf"
EDF
--123456
Content-Disposition: form-data; name="parameters"
PARAMETERS
--123456--
What is not shown above that the string is null-terminated ('\0' after --123456--).
But the response I get is:
HTTP/1.1 400 Bad Request
Server: nginx/1.21.3
Date: Wed, 04 May 2022 06:35:34 GMT
Content-Type: application/json; charset=utf-8
Connection: close
{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"00-0c7bdc085f3f2543aee5f677554f0568-3911d802790ef040-00","errors":{"":["Failed to read the request form. Form section has invalid Content-Disposition value: "]}}
Is someone able to determine what I am doing wrong here?
Edit:
If I remove the null termination I get
HTTP/1.1 400 Bad Request
Server: nginx/1.21.3
Date: Wed, 04 May 2022 06:44:43 GMT
Content-Type: application/json; charset=utf-8
Transfer-Encoding: chunked
Connection: close
122
{"type":"https://tools.ietf.org/html/rfc7231#section-6.5.1","title":"One or more validation errors occurred.","status":400,"traceId":"00-504d94c952c60246b96667d6a8c2e690-d160644f50acf14a-00","errors":{"edf":["The EDF field is required."],"parameters":["The Parameters field is required."]}}
0
Do you notice the 122 and 0 numbers - where are they comming from?
I had created simple server in terminal
#!/usr/bin/env python3
import sys, os, socket, ssl
import requests
import string
import time
from socketserver import ThreadingMixIn
from http.server import HTTPServer,BaseHTTPRequestHandler
from io import BytesIO
import json
import cgi
class ThreadingServer(ThreadingMixIn, HTTPServer):
pass
class RequestHandler(BaseHTTPRequestHandler):
def do_POST(self):
content_length = int(self.headers['Content-Length'])
body = self.rfile.read(content_length)
#self.send_header('Content-type', 'Application/json')
self.send_response(200)
self.end_headers()
response = BytesIO()
self.allow_reuse_address = True
self.wfile.write(b"""{"signingResponse": {"compactidentity": "..SdOwnT70ZZDAjgSmQVP-_0keB_pu4FjkBg5DZDyFf_V5k0EUAY0KCHr2g2a6wOSs-JhsehdYUnrYCfkYItzxLg;info=<http://52.23.250.93:8080/certs/shaken.crt>;alg=ES256;ppt=shaken\n", "TEST": "Nitish","identity": "eyJhbGciOiJFUzI1NiIsInBwdCI6InNoYWtlbiIsInR5cCI6InBhc3Nwb3J0IiwieDV1IjoiaHR0cDovLzUyLjIzLjI1MC45Mzo4MDgwL2NlcnRzL3NoYWtlbi5jcnQifQ.eyJhdHRlc3QiOiJBIiwiZGVzdCI6eyJ0biI6WyIxMjM1NTU1MTIxMiJdfSwiaWF0IjoxNDgzMjI4ODAwLCJvcmlnIjp7InRuIjoiMTIzNTU1NTEyMTIifSwib3JpZ2lkIjoiOGE4ZWM2MTgtYzZiOS0zMGFlLWI0MjctYWY0MTA0YjFjMDJjIn0.SdOwnT70ZZDAjgSmQVP-_0keB_pu4FjkBg5DZDyFf_V5k0EUAY0KCHr2g2a6wOSs-JhsehdYUnrYCfkYItzxLg;info=<http://52.23.250.93:8080/certs/shaken.crt>;alg=ES256;ppt=shaken\n", "requestid": "0"}} """)
httpd = ThreadingServer(('192.168.1.2', 8003), RequestHandler)
httpd.socket = ssl.wrap_socket(httpd.socket, keyfile='/home/nakumar/key.pem', certfile='/home/nakumar/certificate.pem', server_side=True)
httpd.serve_forever()
Using above code i am trying to simulated the server
now when server receives request from client , it send back the responses and closed the connection , as shown below
Request
> POST /stir/v1/signing HTTP/1.1
Host: 192.168.1.2:8003
Accept: application/json
Content-Type: application/json
Content-Length: 331
Reponse
upload completely sent off: 331 out of 331 bytes
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Server: BaseHTTP/0.6 Python/3.5.2
< Date: Tue, 09 Oct 2018 12:43:21 GMT
<
* Closing connection 0
So we can see the connection close is coming from server after response is served,
is there way possible ,not to close the connection after response is served .
Curl Was closing the connection since content length was not present in the response body
after adding the same it started working
> POST /stir/v1/signing HTTP/1.1
Host: [FD00:10:6B50:4510:0:0:0:53]:8101
Accept: application/json
Content-Type: application/json
Content-Length: 325
* upload completely sent off: 325 out of 325 bytes
< HTTP/1.1 200 OK
< Server: HTTP/1.1 Python/3.5.2
< Date: Thu, 18 Oct 2018 09:13:11 GMT
< Content-type: Application/json
< Content-length: 150
<
* Connection #1 to host FD00:10:6B50:4510:0:0:0:53 left intact
I have the following get:
#Get
public String represent(Variant variant) throws ResourceException
{
String text = "returntext";
text+="\r\n";
return text;
}
The response from invoking this service:
CFG - HTTP/1.1 200 OK
Accept-Ranges: bytes
Content-Type: text/plain;charset=UTF-8
Date: Mon, 29 Jul 2013 19:59:37 GMT
Server: Restlet-Framework/2.0.9
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Content-Length: 118
Connection: keep-alive
How do I change the connection header value to close ?
I think this maybe a restlet bug.
Whether the server closes the connection or not, depends on whether the client request asks for the connection to close or not.
Here is a sample Server code:
import org.restlet.data.Form;
import org.restlet.data.MediaType;
import org.restlet.data.Parameter;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;
import org.restlet.util.Series;
public class TestRestlet extends ServerResource {
#Get
public String getImpl(){
return "Sample Response Text\r\n";
}
}
And here is what i got on linux commmand line (using only telnet):
[Please note that the last line in request-header in each request is followed by 2 newlines] [To avoid any confusion, some of the requests do not contain request-body.]
[root#mylinuxserver]# telnet 172.16.101.34 6060
Trying 172.16.101.34...
Connected to win7comp01 (172.16.101.34).
Escape character is '^]'.
GET /TestRestlet HTTP/1.1
Host: 172.16.101.34:6060
HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=C2E77F4D0437E525A0FC66498EF09E8B; Path=/hotelSoft
Date: Wed, 31 Jul 2013 08:25:44 GMT
Accept-Ranges: bytes
Server: Restlet-Framework/2.0.15
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Content-Type: application/json;charset=UTF-8
Content-Length: 22
Sample Response Text
GET /TestRestlet HTTP/1.1
Host: 172.16.101.34:6060
Connection: Keep-Alive
HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=1873DE26443F5DF62379B895AEA0F004; Path=/hotelSoft
Date: Wed, 31 Jul 2013 08:25:48 GMT
Accept-Ranges: bytes
Server: Restlet-Framework/2.0.15
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Content-Type: application/json;charset=UTF-8
Content-Length: 22
Sample Response Text
GET /TestRestlet HTTP/1.1
Host: 172.16.101.34:6060
Connection: close
HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=43EC7C9AACC6C0CEF6FAC8F608B1D79C; Path=/hotelSoft
Date: Wed, 31 Jul 2013 08:25:57 GMT
Accept-Ranges: bytes
Server: Restlet-Framework/2.0.15
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Content-Type: application/json;charset=UTF-8
Content-Length: 22
Connection: close
Sample Response Text
Connection closed by foreign host.
[root#mylinuxserver]# telnet 172.16.101.34 6060
Trying 172.16.101.34...
Connected to win7comp01 (172.16.101.34).
Escape character is '^]'.
GET /TestRestlet HTTP/1.0
HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=2C879A91F2501DD9D3B39EF50C3F46CA; Path=/hotelSoft
Date: Wed, 31 Jul 2013 08:26:09 GMT
Accept-Ranges: bytes
Server: Restlet-Framework/2.0.15
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Content-Type: application/json;charset=UTF-8
Content-Length: 22
Connection: close
Sample Response Text
Connection closed by foreign host.
[root#mylinuxserver]# telnet 172.16.101.34 6060
Trying 172.16.101.34...
Connected to win7comp01 (172.16.101.34).
Escape character is '^]'.
GET /TestRestlet
Sample Response Text
Connection closed by foreign host.
[root#mylinuxserver]#
In the above examples, several types of HTTP connections are made.
The response to the 1st request:
GET /TestRestlet HTTP/1.1
Host: 172.16.101.34:6060
[Note: the line Host: 172.16.101.34:6060 is followed by 2 \r\n: \r\n\r\n]
is:
HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=C2E77F4D0437E525A0FC66498EF09E8B; Path=/hotelSoft
Date: Wed, 31 Jul 2013 08:25:44 GMT
Accept-Ranges: bytes
Server: Restlet-Framework/2.0.15
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Content-Type: application/json;charset=UTF-8
Content-Length: 22
Sample Response Text
The connection is not closed yet, and we send another request:
GET /TestRestlet HTTP/1.1
Host: 172.16.101.34:6060
Connection: Keep-Alive
That gets the response:
HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=1873DE26443F5DF62379B895AEA0F004; Path=/hotelSoft
Date: Wed, 31 Jul 2013 08:25:48 GMT
Accept-Ranges: bytes
Server: Restlet-Framework/2.0.15
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Content-Type: application/json;charset=UTF-8
Content-Length: 22
Still the connection is not closed.
However on the 3rd request:
GET /TestRestlet HTTP/1.1
Host: 172.16.101.34:6060
Connection: close
The connection is closed, because the request contains Connection: close header.
You can see the telnet exits after displaying a message: Connection closed by foreign host.
There are 2 more sample request-response in the above given examples:
1.An HTTP 1.0 request:
GET /TestRestlet HTTP/1.0
With response:
HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=2C879A91F2501DD9D3B39EF50C3F46CA; Path=/hotelSoft
Date: Wed, 31 Jul 2013 08:26:09 GMT
Accept-Ranges: bytes
Server: Restlet-Framework/2.0.15
Vary: Accept-Charset, Accept-Encoding, Accept-Language, Accept
Content-Type: application/json;charset=UTF-8
Content-Length: 22
Connection: close
Sample Response Text
And the telnet exits after displaying: Connection closed by foreign host.
2.A request without HTTP version mentioned:
GET /TestRestlet
And response is: (Without headers)
Sample Response Text
And the telnet exits with a message: Connection closed by foreign host.
Conclusion:
Whatever is your client / client-program , make it send an HTTP-1.0 request , or a HTTP-1.1 request with Connection: close header.
In Java, you achieve this by:
import java.net.HttpURLConnection;
import java.net.URL;
.
.
.
HttpURLConnection httpURLConnection = (HttpURLConnection) new URL("http://....").openConnection();
httpURLConnection.setRequestProperty("Connection","close");
// rest of the code here....
Also check if a statement like this:
httpURLConnection.disconnect();
can help you disconnect the connection.
The Zend\Mvc\Controller\AbstractRestfulController#requestHasContentType(...) checks the content using $request->getHeaders()->get('content-type');.
Now I'm sending a cURL request like this:
# curl -i http://project.dev/seminars/1 -H 'Accept: allication/xml'
HTTP/1.1 200 OK
Date: Fri, 14 Jun 2013 16:06:33 GMT
Server: Apache/2.2.16 (Debian)
X-Powered-By: PHP/5.3.3-7+squeeze15
Vary: Accept-Encoding
Content-Length: 1108
Content-Type: text/html
So, the content type is text/html. But the output, I'm getting is false:
$test = $this->getRequest()->getHeaders()->get('content-type');
var_dump($test);
// output: bool(false)
What I'm doing wrongly and how should I do, in order to get the contetn type of the REST request?
My bad -- I was expecting the Accept value from $request->getHeaders()->get('content-type'). Instead of it I should use $this->getRequest()->getHeaders()->get('Accept').
According to the documentation the Date response header should be sent by default.
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
Curling the sample above I get:
C:\Users\Hans>curl localhost:1337 -i
HTTP/1.1 200 OK
Content-Type: text/plain
Connection: keep-alive
Transfer-Encoding: chunked
Hello World
No Date header. Even when I set response.sendDate = true I get no Date header. What is wrong?
Upgraded from 0.8.1 to 0.8.2 and now it works
C:\Users\Hans>curl localhost:1337 -i
HTTP/1.1 200 OK
Content-Type: text/plain
Date: Fri, 13 Jul 2012 10:52:59 GMT
Connection: keep-alive
Transfer-Encoding: chunked
Hello World