I have a Swift app that loads a timestamp and a number as a json file and sends it as with POST through Alamofire.
var newPostStamp = ["title": "\(stamp)", "body": string1]
Alamofire.request(.POST, "mywebsite.com/post", parameters: newPostStamp, encoding: .JSON)
.responseJSON { (request, response, data, error)}...
Can you tell me how I can handle the arguments in from the POST request in my server? I am using this tutorial (http://joelinoff.com/blog/?p=1658) but I don't know how to change the do_POST() method to handle my request. I just need it to show me a new page with all the timestamp:values that I have sent so far.
Thanks!
This worked for me.
// Add this to your class
import SystemConfiguration
import CoreData
func isConnectedToNetwork() -> Bool {
var zeroAddress = sockaddr_in(sin_len: 0, sin_family: 0, sin_port: 0, sin_addr: in_addr(s_addr: 0), sin_zero: (0, 0, 0, 0, 0, 0, 0, 0))
zeroAddress.sin_len = UInt8(sizeofValue(zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(&zeroAddress){
SCNetworkReachabilityCreateWithAddress(nil, UnsafePointer($0)).takeRetainedValue()
}
var flags: SCNetworkReachabilityFlags = 0
if SCNetworkReachabilityGetFlags(defaultRouteReachability, &flags) == 0 {
return false
}
let isReachable = (flags & UInt32(kSCNetworkFlagsReachable)) != 0
let needsConnection = (flags & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
return (isReachable && !needsConnection) ? true : false
}
func connectionService(jsonString:NSDictionary) -> NSDictionary
{
var request = NSMutableURLRequest(URL: NSURL(string: "https://example.com")!)
var response: NSURLResponse?
var error: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(jsonString, options: nil, error: &error)
request.timeoutInterval = 100
request.HTTPMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("gzip", forHTTPHeaderField: "Accept-encoding")
//Reconnnection 5 times
for (var i = 0; i < 5 ; i++)
{
let date1 = NSDate();
var formatter = NSDateFormatter();
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS";
let defaultTimeZoneStr1 = formatter.stringFromDate(date1);
var error: NSError?
println("Connecting to server : \(defaultTimeZoneStr1)")
if isConnectedToNetwork (){
let urlData = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error)
if error != nil || urlData!.length == 0
{
println("Error happend timeout======\(error?.code)!")
continue
}
else
{
let date = NSDate();
var formatter = NSDateFormatter();
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS";
let defaultTimeZoneStr = formatter.stringFromDate(date);
println("Response from server : \(defaultTimeZoneStr)")
if let httpResponse = response as? NSHTTPURLResponse
{
println("Status Code for successful------------------------------------>\(httpResponse.statusCode)")
if (httpResponse.statusCode == 502)
{
// Server is down
break
}
else
{
println(NSString(data: urlData!, encoding: NSUTF8StringEncoding)!)
var er: NSError?
let JSONresdata: AnyObject = (NSJSONSerialization.JSONObjectWithData(urlData!, options: .MutableContainers,error: &er)!)
println("JSON response : \(JSONresdata)")
JSONdata = JSONresdata as! NSDictionary
}
}
}
}
else
{
println("------------------------------------------------No network----------------------------------------------")
// You can add your code
break
}
}
return JSONdata as! NSDictionary;
}
Hope this might be helpful.
Related
I'm developing a Flask app and at the moment everything works fine, but I'm unable to redirect the browser to the desired page. I can't even redirect to an external URL.
In the page /proposals there's a button which calls a JavaScript login function:
let provider;
let accounts;
let accountAddress = "";
let signer;
function submit_proposal() {
console.log("oh hey there");
// signer.signMessage("hello");
rightnow = (Date.now() / 1000).toFixed(0);
sortanow = rightnow - (rightnow % 600);
signer
.signMessage(
"Signing in to transparency.smartindex.cash at " + sortanow,
accountAddress,
"test password!"
)
.then((signature) => {
handleAuth(accountAddress, signature);
});
}
function handleAuth(accountAddress, signature) {
console.log(accountAddress);
console.log(signature);
fetch("login", {
method: "post",
headers: { "Content-Type": "application/json" },
body: JSON.stringify([accountAddress, signature]),
})
.then((response) => {
return response.json();
})
.then((data) => {
console.log(data);
});
}
ethereum.enable().then(function () {
provider = new ethers.providers.Web3Provider(web3.currentProvider);
provider.getNetwork().then(function (result) {
if (result["chainId"] != 10000) {
document.getElementById("msg").textContent = "Switch to SmartBCH!";
} else {
// okay, confirmed we're on mainnet
provider.listAccounts().then(async function (result) {
console.log(result);
accountAddress = result[0]; // getting uesrs publickey
// contract address and contract abi is used to create the contract instance
const contractAddress = "0xF05bD3d7709980f60CD5206BddFFA8553176dd29";
const contractABI = [
// balanceOf
{
constant: true,
inputs: [{ name: "_owner", type: "address" }],
name: "balanceOf",
outputs: [{ name: "balance", type: "uint256" }],
type: "function",
},
// decimals
{
constant: true,
inputs: [],
name: "decimals",
outputs: [{ name: "", type: "uint8" }],
type: "function",
},
];
// creating contract instance
const contract = new ethers.Contract(
contractAddress,
contractABI,
provider
);
// getting the contract decimals and balance
const decimals = await contract.decimals();
let balance = await contract.balanceOf(accountAddress);
balance = parseFloat(ethers.utils.formatUnits(balance, decimals));
if (balance < 5000) {
// if SIDX balance < 5000, insufficient balance
document.getElementById("msg").textContent =
"You need at least 5000 SIDX tokens to submit a proposal";
} else {
// else allow user to submit proposal
const submitProposalButton =
document.getElementById("submit_proposal");
submitProposalButton.disabled = false;
signer = provider.getSigner();
}
});
}
});
})
This is the Flask function which handles the login and tries to redirect to /submit_proposal:
#app.route('/login', methods=['POST', 'GET'])
def login():
if current_user.is_authenticated:
return redirect(url_for('submit_proposal'))
w3 = Web3(Web3.HTTPProvider('https://smartbch.greyh.at'))
if not w3.isConnected():
w3 = Web3(Web3.HTTPProvider('https://smartbch.fountainhead.cash/mainnet'))
public_address = request.json[0]
signature = request.json[1]
domain = "transparency.smartindex.cash"
rightnow = int(time.time())
sortanow = rightnow - rightnow % 600
original_message = 'Signing in to {} at {}'.format(domain, sortanow)
message_hash = defunct_hash_message(text=original_message)
signer = w3.eth.account.recoverHash(message_hash, signature=signature)
if signer == public_address:
ABI = open("/home/administrador/Descargas/BCH/transparency_portal/ABIs/ERC20-ABI.json", "r") # Standard ABI for ERC20 tokens
abi = json.loads(ABI.read())
contract = w3.eth.contract(address="0xF05bD3d7709980f60CD5206BddFFA8553176dd29", abi=abi)
SIDX_balance = contract.functions.balanceOf(signer).call() / 10 ** 18
if SIDX_balance < 5000:
flash('You need at least 5000 SIDX token to submit a proposal')
return url_for('proposals')
else:
if db.session.query(Users).filter(Users.public_address == signer).first() is None:
user = Users(public_address=signer)
db.session.add(user)
db.session.commit()
user = Users.query.filter_by(public_address=signer).first()
login_user(user)
# return redirect(url_for('submit_proposal'))
else:
abort(401, 'Could not authenticate signature')
return redirect(url_for('submit_proposal'))
Despite the redirects fails, I get this message in the console:
127.0.0.1 - - [25/Dec/2021 15:47:09] "GET /submit_proposal HTTP/1.1" 200 -
The user is logged correctly (I've check it), so I can manually so to /submit_proposal.
This is the /submit_proposal view:
#app.route('/submit_proposal')
#login_required
def submit_proposal():
with open('data/SIDX_STATS.json') as sidx_stats_file:
sidx_stats = json.load(sidx_stats_file)
print(request)
return render_template("submit_proposal.html", title="Submit a proposal", sidx_stats=sidx_stats)
Request output is <Request 'http://127.0.0.1:5000/submit_proposal' [GET]>.
It seems to be correct, but the browser does nothing. Even I tried to just redirect to an external page, but again, browser does nothing. This is not the first time I cannot get redirect to work, so I guess that the error is not on the login function.
EDIT:
Please, someone with some JavaScript knowledge can guide me to do something like this?
function submit_proposal() {
console.log("oh hey there");
// signer.signMessage("hello");
rightnow = (Date.now() / 1000).toFixed(0);
sortanow = rightnow - (rightnow % 600);
signer
.signMessage(
"Signing in to transparency.smartindex.cash at " + sortanow,
accountAddress,
"test password!"
)
.then((signature) => {
handleAuth(accountAddress, signature);
})
.then((response)=>{
if(response.redirected){
window.location.href = response.url;
}
})
.catch(function(e){
})
}
What I'm trying to do is, once the function submit_proposal is called, wait for a server response with the redirection.
Code:
const WebSocket = require('ws');
const shaUtil = require('js-sha256');
String.prototype.hashCode = function() {
return shaUtil(String(this));
};
const server = new WebSocket.Server({port:2909}); // Change to another port if you like.
// Hashes of client keys. Generate them using getHash.js and place them here.
const passes = {
'86cec081a5288000ddb804c24ac70de62a5060e5b4f4068b01a01f9f29dddacc': 0, // Receiver's key.
'c01223ad2ba8cdd184ded788cf6d3469111229cbe6cb3939ce24f471e8f257ca': 1, // Buzzer #1's key.
'5476be1700a54be0572b0066b32b5905986641fa163c5eabd52369eb3a2685cf': 2 // Buzzer #2's key...
};
var receiver = null;
var senders = {1: null, 2: null, 3: null, 4: null}; // You can add more/remove buzzers if you want to.
const lockClients = true; // If it is true, a connected client will not be overriden by another client logging in until it disconnects.
if (lockClients) canConnect = function(id) {
if (id == 0) return receiver === null;
return senders[id] === null;
}
else canConnect = function(id) {
return true;
}
function processBuzzer(client) {
if (receiver == null) return;
receiver.send('BUZZER '+client.buzzerId);
//console.log('Buzzer #'+client.buzzerId+' is activated.');
}
function onDisconnect(id) {
if (id === 0) {
receiver = null;
console.log('Receiver has disconnected.');
} else {
senders[id] = null;
console.log('Sender #' + id + ' has disconnected.');
}
}
server.on('connection', function(client) {
client.sendBuzzer = function() {};
client.on('message', function(message) {
if (message.startsWith('PASSWORD: ')) {
let id = passes[message.substring(10).hashCode()];
if (id !== undefined && canConnect(id)) {
if (client.buzzerId !== undefined) onDisconnect(client.buzzerId);
client.buzzerId = id;
if (id === 0) {
receiver = client;
console.log('Receiver has connected.');
} else {
senders[id] = client;
console.log('Sender #' + id + ' has connected.');
client.sendBuzzer = function() { processBuzzer(this) };
client.send('CONNECTED SUCCESSFULLY');
}
}
}
if (message == 'BUZZER') client.sendBuzzer();
});
client.on('close', function() {
if (client.buzzerId !== undefined) onDisconnect(client.buzzerId);
});
});
console.log('Server is running.');
If i started this with nodeJS with "node server.js", it appears Server is running.....no mistakes.....and now, Iwill connect to this server with the receiver.py (Python-File):
serverAddress = 'ws://192.168.1.50:2909' # The server's address.
clientKey = 'receiver' # The client key corresponding to the receiver's hash.
buzzerSoundFile = 'buzzer.wav' # The name/path of the buzzer sound file.
import asyncio
import websockets
from win32com.client import Dispatch
import winsound
from threading import Thread
app = Dispatch('Powerpoint.Application')
def playBuzzerSound():
global buzzerSoundFile
winsound.PlaySound(buzzerSoundFile, winsound.SND_FILENAME+winsound.SND_ASYNC)
async def mainFunction():
global serverAddress, clientKey
async with websockets.connect(serverAddress) as ws:
await ws.send('PASSWORD: ' + clientKey)
while True:
msg = await ws.recv()
if msg.startswith('BUZZER '):
if app.Run('onBuzzerActivated', int(msg[7:])):
Thread(target=playBuzzerSound).start();
asyncio.get_event_loop().run_until_complete(mainFunction())
I got an error 200 like this:
websockets.exceptions.InvalidStatusCode: server rejected WebSocket connection: HTTP 200
What's wrong ??
Cannot to sign in, i run localy in docker my container, i can sign-in on my machine and docker no error, but on my remote server i cannot to login, it doesn't write cookie in reponse, have no error, just don't write response. It just redirect me on my page which i setted,and after that i got error, cause i have no my cookie authorization key inside cookie.
video
My SignIn method
#auth_router.post('/signin')
async def sign_in(response: Response, username: str = Form(...), password: str = Form(...), recaptchav3: str = Form(...)) -> dict:
is_human = await verify_recaptcha(recaptchav3)
if is_human['success']:
user = await authenticate_user(username, password)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail='Invalid username or password',
)
user_obj = await User_Pydantic.from_tortoise_orm(user)
user_token = await generate_token(user_obj)
response.set_cookie(key="Authorization", value=user_token, httponly=True, secure=True, expires=(8*60*60))
response.headers["Authorization"] = user_token
user.jwt_token = user_token
await user.save()
return {
'access_token': user_token,
'token_type': 'bearer'
}
else:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail='Invalid captcha',
)
How i submit my form js
const request = (method, url, data = null, redirectPage) => {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest()
xhr.open(method, url, true)
// xhr.setRequestHeader('Content-Type', 'multipart/form-data')
xhr.onerror = function (event) {
alert(event)
console.log(event);
};
xhr.onload = () => {
if (xhr.status === 200) {
return window.location.href = redirectPage;
return resolve(JSON.parse(xhr.responseText || '{}'))
} else {
alert(`Request failed with status ${xhr.status}`)
reject(new Error(`Request failed with status ${xhr.status}`))
return window.location.reload();
}
}
if (data) {
if (typeof data === 'string' || data instanceof String || typeof data.constructor == Object){
xhr.send(JSON.stringify(data))
} else {
xhr.send(data)
}
} else {
xhr.send()
}
})
}
signInForm = getElementById('signinform');
handleEvent(signInForm, 'submit', e => {
e.preventDefault();
if(!isEmpty(signInForm)){
signInUsername = getElement('input[name="username"]', signInForm).value;
signInPassword = getElement('input[name="password"]', signInForm).value;
recaptchaV3 = getElement('[name="g-recaptcha-response"]').value;
if(recaptchaV3){
signInData = new FormData();
signInData.append('username', signInUsername);
signInData.append('password', signInPassword);
signInData.append('recaptchav3', recaptchaV3);
isLogened = request('POST', '/signin', signInData, 'dashboard');
} else{
alert('Перезагрузите страницу');
}
}
})
I cannot understand why using the built-in method in fastapi it does not write on the remote server, it worked on the local one, but I solved the problem by writing. token via js.
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
var expires = "expires="+d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
function checkCookie(cookieValue) {
var user = getCookie("Authorization");
if (user == "") {
if (cookieValue != "" && cookieValue != null) {
setCookie("Authorization", cookieValue, 365);
}
}
}
signInForm = getElementById('signinform');
handleEvent(signInForm, 'submit', e => {
e.preventDefault();
if(!isEmpty(signInForm)){
signInUsername = getElement('input[name="username"]', signInForm).value;
signInPassword = getElement('input[name="password"]', signInForm).value;
recaptchaV3 = getElement('[name="g-recaptcha-response"]').value;
if(recaptchaV3){
signInData = new FormData();
signInData.append('username', signInUsername);
signInData.append('password', signInPassword);
signInData.append('recaptchav3', recaptchaV3);
isLogened = request('POST', '/signin', signInData);//, 'dashboard');
isLogened.then(result => {
checkCookie(result.access_token);
return window.location.href = 'dashboard';
}, result => {
log('Cant get response')
});
} else{
alert('Перезагрузите страницу');
}
}
})
I can't figure out the image data send error, not familiar with JSON.
Given this working Python code:
def uploadImage(image_name, folder_path, location):
path = folder_path + '\\' + image_name
with open(path, "rb") as image_file:
encoded_string = base64.b64encode(image_file.read())
req_body = {"filename": image_name, "location": location}
resp_post = requests.post( "myURL", json=req_body)
if resp_post.status_code == 200:
url = resp_post_json = resp_post.json()['url'] # facing c# problem here
resp_put = requests.put(url,data=encoded_string)
if resp_put.status_code != 200:
return "PUT request error : {}".format(resp_put.reason)
else:
retur
"POST request error : {}".format(resp_post.reason)
C# code:
internal void UploadImage(string strImagePathNName, string strImageName, string strLoaction)
{
try
{
// read file in base 64 string
string base64String = Convert.ToBase64String(File.ReadAllBytes(strImagePathNName));
if (base64String.Length > 0)
{
var webAddr = "myURL";
string json = "{\"filename\":\"" + strImageName + "\"," + "\"location\":\"" + strLoaction + "\"}";
HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(webAddr);
httpWebRequest.ContentType = "application/json; charset=utf-8";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(json);
streamWriter.Close();
}
bool bIsGotResponseFromServer = false;
var strResponseUri = string.Empty;
using (HttpWebResponse webResponse = (HttpWebResponse)httpWebRequest.GetResponse())
{
if (webResponse.StatusCode == HttpStatusCode.OK)
{
using (Stream respStream = webResponse.GetResponseStream())
{
StreamReader reader = new StreamReader(respStream, Encoding.UTF8);
strResponseUri = reader.ReadToEnd();
UrlFromJson myojb = (UrlFromJson)JsonConvert.DeserializeObject(strResponseUri, typeof(UrlFromJson));
strResponseUri = myojb.url; //retrieved the URl
bIsGotResponseFromServer = true;
}
}
}
if (bIsGotResponseFromServer)
{
httpWebRequest = (HttpWebRequest)WebRequest.Create(strResponseUri);
httpWebRequest.ContentType = "application/json; charset=utf-8";
httpWebRequest.Method = "post";
json = "{\"data\":\"" + base64String + "\"}";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
streamWriter.Write(json); /// not sure about this line
streamWriter.Close();
}
using (HttpWebResponse webResponse1 = (HttpWebResponse)httpWebRequest.GetResponse()) // received error here
{
if (webResponse1.StatusCode == HttpStatusCode.OK)
{
}
}
}
}
}
catch (WebException e)
{
}
}
Solution
Just using the base64 string instead of the httpWebRequest.GetRequestStream:
Stream.Write(base64String,0, base64String.Length);
and set:
httpWebRequest.Method = "PUT";
I use nodeJS and express as a server and use child_process.spawn to run a python script.
After running the script, I get the result and send it as a json response.
When I get correct post response, the server responses the right response.
When I post wrong parameters, the servers responses with the error message (as expected)
But when I post the wrong parameters after the correct parameter post, it gives the previous post's response and I don't know why. Maybe this is because of the spawn and should I use exec?
I want to know why this is happening.
Let me know if you need more details on this.
const { json } = require('body-parser')
const express = require('express')
const { setTimeout } = require('timers')
const router = express.Router()
let dataToSend;
router.post('/', (req, res) => {
// console.log(req.body)
let resol = req.body.Resolution;
let url1 = req.body.FirstImageURI;
let url2 = req.body.SecondImageURI;
let roi = req.body.DetectionArea;
let sens = req.body.Threshold;
if (isNaN(sens)) sens = "50";
console.log("start ai model");
console.log(`params : ${url1} ${url2} ${roi} ${sens}`);
const spawn = require("child_process").spawn;
const pythonProcess = spawn('python', ["img_diff.py", url1, url2, roi, sens]);
pythonProcess.stdout.on('data', function (data) {
console.log('Pipe data from python script ...');
dataToSend = data.toString();
console.log(`data in stdout : ${dataToSend}`)
});
// in close event we are sure that stream from child process is closed
pythonProcess.on('close', (code) => {
try {
jsonObject = {}
console.log(`child process close all stdio with code ${code}`);
// format json
dtList = dataToSend.split('\n');
ssim = Number(dtList[0].split(":")[1]);
detected = "UnDetected"
console.log(dtList[1])
let addInfo = dtList[1].trim().slice(1, -1)
addInfo = JSON.parse("[" + addInfo + "]");
jsonObject.AdditionalInfo = []
for (let i = 0; i < addInfo.length; i++) {
let thisObject = {}
thisObject.DetectedRegion = []
for (let j = 0; j < addInfo[i].length; j++) {
coordObject = {}
coordObject.XCoord = addInfo[i][j][0]
coordObject.YCoord = addInfo[i][j][1]
thisObject.DetectedRegion.push(coordObject)
}
jsonObject.AdditionalInfo.push(thisObject)
}
if (jsonObject.AdditionalInfo.length > 0) {
detected = "Detected"
}
jsonObject.Result = detected
console.log(detected)
res.json(jsonObject)
} catch (e) {
console.log(`error -> ${e}`)
jsonObject.AdditionalInfo = [];
let thisObject = {};
thisObject.DetectedRegion = [];
jsonObject.AdditionalInfo.push(thisObject);
jsonObject.detected = "UnDetected";
res.json(jsonObject);
}
});
})
module.exports = router
Still don't know why this happens,
but my guess is that as the process crashes,
Node just gives a response from the previous successful memory.
Will come back and update if I have a better answer.