Simple Http Server Issue on Micropython (ESP8266) - python-3.x

I am sending same post to Simple Http Server(Micropython) installed on ESP8266 and BaseHTTPServer(Python) on PC from my mobile APP (iOS-Swift 4).
On PC, i am getting Payload successfully as seen below, However, when i post to ESP8266, i am not seeing any payload in the body and after 3-5 request, i am getting an following error; you can see the code in ESP8266 and request method in Swift below; (if i remove JSON data from my request in Swift, i am not getting following error, only header is successfully posted to ESP8266)
ERROR in SWIFT after 3-5 Post Request;
2018-02-06 15:58:48.381801+0300 Chroma[1655:40174] TIC TCP Conn Failed [49:0x60400016c6c0]: 1:61 Err(61)
2018-02-06 15:58:48.385161+0300 Chroma[1655:40174] Task <542713C7-815D-479B-A462-DBD6A6EBB795>.<49> HTTP load failed (error code: -1004 [1:61])
2018-02-06 15:58:48.386808+0300 Chroma[1655:40159] Task <542713C7-815D-479B-A462-DBD6A6EBB795>.<49> finished with error - code: -1004
Could not connect to the server.
PC-DEBUG (SUCCEED);
----- Request Start ----->
Request path: /
Content Length: 20
Request headers: Host: 0.0.0.0:10000
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Accept: application/json
User-Agent: Chroma
Accept-Language:
Content-Length: 20
Accept-Encoding: gzip, deflate
Request payload: {"COLOR":[0,255,95]}
<----- Request End -----
ESP8266-DEBUG(PAYLOAD NOT SEEN) ;
POST / HTTP/1.1
Host: 192.168.1.171:8080
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Accept: application/json
User-Agent: Chroma
Accept-Language:
Content-Length: 20
Accept-Encoding: gzip, deflate
CODE ON ESP8266
def webServer():
s = socket.socket()
ai = socket.getaddrinfo("192.168.1.171", 8080)
print("Bind address info:", ai)
addr = ai[0][-1]
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen(2)
while True:
res = s.accept()
client_sock = res[0]
client_addr = res[1]
# print("Client address:", client_addr)
# print("Client socket:", client_sock)
req = client_sock.recv(1024)
print("Request: %s" % req.decode())
client_sock.send("HTTP/1.0 200 OK\r\n\r\n'Color: JSON'\r\n")
client_sock.close()
print()
SWIFT REQUEST CODE
func sendPostToServer(color: [Int]) {
var json = [String(): [Int()]]
json = ["COLOR": color]
let jsonData = try? JSONSerialization.data(withJSONObject: json)
// create post request
let url = URL(string: "http://192.168.1.171:8080")!
// let url = URL(string: "http://0.0.0.0:10000")! //to pc server
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("", forHTTPHeaderField: "Accept-Language")
request.setValue("Chroma", forHTTPHeaderField: "User-Agent")
// insert json data to the request
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else {
print(error?.localizedDescription ?? "No data")
return
}
let dataString = String(data: data, encoding: .utf8) ?? ""
print("Response \(dataString)")
}
task.resume()
}

Related

How to write the correct recipe for an HTTP POST request on Groovy

I'm trying to write a recipe for an HTTP POST request in Groovy and the way I am doing it is by editing a previous recipe but adjusting it to my own needs:
Set two request properties (Content-Type: application/json, Authorization: Bearer xxxxx)
Set raw data (json) ({"var_1": "value 1", "var_2": "value 2"})
The recipe I'm trying to modify is
def baseUrl = new URL('http://some.url.com/')
def connection = baseUrl.openConnection()
connection.with {
doOutput = true
requestMethod = 'POST'
setRequestProperty = ['Content-Type': 'application/json', 'Authorization': 'Bearer xxxx']
outputStream.withWriter { writer ->
writer
}
println content.text
}
At first when executing the script I get the following error:
Exception thrown
java.io.IOException: Server returned HTTP response code: 401 for URL: http://some.url.com/
The other thing is that I don't know how to add the need (2) to the script.
Thanks in advance.
Based on Javadoc I would put the code like so:
def baseUrl = new URL('http://some.url.com/')
def connection = baseUrl.openConnection()
connection.with {
doOutput = true
requestMethod = 'POST'
addRequestProperty 'Content-Type', 'application/json'
addRequestProperty 'Authorization', 'Bearer xxxx'
outputStream.withWriter{ it << '{"var_1": "value 1", "var_2": "value 2"}' }
println content.text
}

Need to modify request payload in Azure APIM set body to send modified request body to BE

My APIM is receiving request payload in POST request -
and I have to format and send to backend --
Formatted payload for BE
I have to add the 2 parameters after every newreq line and append 2 new lines after GET request line. how to achive this in apim.
newreq
Content-Type: application/http--I have to append these parameter in payload
Accept: application/json
GET Abc?$format=json HTTP/1.1
newreq
Content-Type: application/http
Accept: application/json
GET Abc?$format=json HTTP/1.1
endnewreq
You can read request body first and then append the parameters to object.
<set-body>#{
var requestBody = context.Request.Body.As<JObject>(preserveContent:
true);
requestBody ["Content-Type"] = "Your Value";
requestBody ["Accept"] = "Your Value";
return requestBody.ToString();
}</set-body>

retrofit2 with 2 multiparts - JSON and File is failed

I'm trying to call an external ReST service.
retrofit_version = "2.9.0"
okhttp = "3.14.9"
This is the Retrofit interface as I define it:
#Multipart
#POST("orgs/{orgUuid}/patients/{patientId}/documents")
Call<DocUploadRes> uploadDocForPatient(#Header("Authorization") String authorization,
#Path("orgUuid") String orgUuid,
#Path("patientId") Integer patientId,
#Part("metadata") RequestBody metadata,
#Part MultipartBody.Part file);
My Client call is as follow:
RequestBody metadataBody = RequestBody.create(MediaType.parse("application/json"), content);
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file","Safereport", RequestBody.create(MediaType.parse("application/pdf"), file.getBytes()));
Response<DocUploadRes> response = pccPatientRestApi.uploadDocForPatient(getBearerAuthHeader(pccAccessToken), pccOrgUuid, patientId, jsonPart, filePart).execute();
When I'm running this code with retrofit I'm getting Bad Request from the server with:
status":"400","title":"Bad Request.","detail":"File type is not supported"
But when I run the same service from postman it working successfully with the following http request sent:
POST /api/public/preview1/orgs/E58A8604-38F2-4098-879E-C6BCC6D01EB8/patients/372842/documents HTTP/1.1
Host: connect2.pointclickcare.com
Authorization: Bearer iy8OUOVa46oxaYRMVYlRApqDW00m:2Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="/C:/Users/user/Desktop/RosieConnect-20-API-User-Manual-Ver-07172018.pdf"
Content-Type: application/pdf
(data)
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="metadata"
{"documentCategory":1,"documentName":"Safebeing Report","effectiveDate":"2020-05-26T08:03:49.895Z"}
----WebKitFormBoundary7MA4YWxkTrZu0gW
It seems to me that retrofit doesn't send the 'application/pdf' in the Content-Type header of the file #Part... how can it be fixed?
Any idea will be very much appreciated!
-- Update ---
It appears the the file extension is mandatory.
Problem solved by adding .pdf to the file name
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file","report.pdf", RequestBody.create(MediaType.parse("application/pdf"), file.getBytes()));

Encounter an issue when to send post request with cookie----urllib.error.HTTPError: HTTP Error 503: Service Unavailable

Check if the host allow to scrawl.
curl http://www.etnet.com.hk/robots.txt |grep warrants
Allow: /www/tc/warrants/
Allow: /www/tc/warrants/realtime/
Allow: /www/sc/warrants/
Allow: /www/sc/warrants/realtime/
Allow: /www/eng/warrants/
Allow: /www/eng/warrants/realtime/
Allow: /mobile/tc/warrants/
Target webpage to scrawl with urllib post method.
Encounter a issue when to send post request with cookie----urllib.error.HTTPError: HTTP Error 503: Service Unavailable
send post request with cookie
I have checked request header and parameters with firefox.
Now construct my post request with cookie.
import urllib.parse
import urllib.request as req
import http.cookiejar as cookie
cookie_jar = cookie.CookieJar()
opener = req.build_opener(req.HTTPCookieProcessor(cookie_jar))
req.install_opener(opener)
url = "http://www.etnet.com.hk/www/sc/warrants/search_warrant.php"
params = {
"underasset":"HSI",
"buttonsubmit":"搜寻",
"formaction":"submitted"
}
headers = {
'Accept':"text/htmlpplication/xhtml+xmlpplication/xml;q=0.mage/webp,*/*;q=0.8",
'Accept-Encoding':"gzip, deflate",
'Accept-Language':"en-US,en;q=0.5",
'Connection':'keep-alive',
'Content-Length':'500',
'Content-Type':'application/x-www-form-urlencoded',
"Host":"www.etnet.com.hk",
"Origin":"http://www.etnet.com.hk",
"Referer":"http://www.etnet.com.hk/www/sc/warrants/search_warrant.php",
"Upgrade-Insecure-Requests":"1",
"User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0"
}
query_string = urllib.parse.urlencode(params)
data = query_string.encode()
cookie_req = req.Request(url, headers=headers, data=data,method='POST')
page = req.urlopen(cookie_req).read()
I encounter a issue when to execute the above code:
urllib.error.HTTPError: HTTP Error 503: Service Unavailable
Please find out the bug in my code,and how to fix it?
#NicoNing,the last issue is to count how many bytes the headers contain.
>>> s="""'Accept':'text/htmlpplication/xhtml+xmlpplication/xml;q=0.mage/webp,*/*;q=0.8',\
... 'Accept-Encoding':'gzip, deflate',\
... 'Accept-Language':'en-US,en;q=0.5',\
... 'Connection':'keep-alive',\
... 'Content-Type':'application/x-www-form-urlencoded',\
... 'Content-Length':'495',\
... 'Host':'www.etnet.com.hk',\
... 'Origin':'http://www.etnet.com.hk',\
... 'Referer':'http://www.etnet.com.hk/www/sc/warrants/search_warrant.php',\
... 'Upgrade-Insecure-Requests':'1',\
... 'User-Agent':'Mozilla/5.0 (X11; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0'"""
>>> len(s)
495
It can't get proper request with the above headers,if i do write the content-length in request's headers,how to assign a value as Content-Length then?
Just remove the header : 'Content-Length':'500'
Actually, Your request content length is not equal to 500 , but you define it at the headers , it make the server unavailable.
read doc: HTTP > HTTP headers > Content-Length
The Content-Length entity header indicates the size of the
entity-body, in bytes, sent to the recipient.
In your case, if you insist on using header Content-Length, read the doc in font, get to know what it means. And then the answer is coming:
"Content-Length" : str(len(data))
import urllib.parse
import urllib.request as req
import http.cookiejar as cookie
cookie_jar = cookie.CookieJar()
opener = req.build_opener(req.HTTPCookieProcessor(cookie_jar))
req.install_opener(opener)
url = "http://www.etnet.com.hk/www/sc/warrants/search_warrant.php"
params = {
"underasset":"HSI",
"buttonsubmit":"搜寻",
"formaction":"submitted"
}
query_string = urllib.parse.urlencode(params)
data = query_string.encode()
headers = {
'Accept':"text/htmlpplication/xhtml+xmlpplication/xml;q=0.mage/webp,*/*;q=0.8",
'Accept-Encoding':"gzip, deflate",
'Accept-Language':"en-US,en;q=0.5",
'Connection':'keep-alive',
'Content-Type':'application/x-www-form-urlencoded',
# 'Content-Length': str(len(data)), ### optional
"Host":"www.etnet.com.hk",
"Origin":"http://www.etnet.com.hk",
"Referer":"http://www.etnet.com.hk/www/sc/warrants/search_warrant.php",
"Upgrade-Insecure-Requests":"1",
"User-Agent":"Mozilla/5.0 (X11; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0",
}
cookie_req = req.Request(url, headers=headers, data=data,method='POST')
resp = req.urlopen(cookie_req)
print(resp._method, resp.code) # POST 200
page = resp.read()
print(page)
suggest to know more about http , and take care of all the headers you set.
As explained in this answer , using python's requests module is more effective with http requests.
You can obtain your final output by following the below procedure.
import requests
url = "http://www.etnet.com.hk/www/sc/warrants/search_warrant.php"
params = {
"underasset":"HSI",
"buttonsubmit":"搜寻",
"formaction":"submitted"
}
out=requests.post(url,data=params)
print(out.text)
I hope this is the answer you are looking for.

How can I execute a simple request with an URL in Groovy/Java?

I have the following code in groovy:
def http = new HTTPBuilder( 'http://localhost:8080' )
http.post( path: '/this/is/my/path/'+variable) { resp ->
println "POST Success: ${resp.statusLine}"
assert resp.statusLine.statusCode == 200
}
I only want to execute that request. I have a method in another application that when there is a request in that url, I see a result. Problem is that I see nothing.
What might be the problem?
Most likely, your application only responds to GET request and not to POST requests. Try GET instead:
def http = new HTTPBuilder( 'http://localhost:8080' )
http.get( path: '/this/is/my/path/'+variable) { resp ->
println "GET Success: ${resp.statusLine}"
assert resp.statusLine.statusCode == 200
}
Also, are you sure that you expect a HTTP status 201 (Created) at this URL?
Could try just opening a simple HttpURLConnection like this:
URL url = new URL("http://localhost:8080/this/is/my/path/${variable}")
HttpURLConnection connection = url.openConnection()
println "responseCode: ${connection.responseCode}"
assert connection.responseCode == 200

Resources