HttpResponseMessage returns 403 in .NET - python

I have a async method which make a HttpClient call repeatedly in .Net. I simulate my code as a small console app below:
private static HttpClient req { get; set; } = new HttpClient();
static async Task Main(string[] args)
{
Console.WriteLine("Please press enter to start healthCheck");
Console.ReadLine();
healthCheck();
Console.ReadLine();
}
private static async Task healthCheck()
{
while (true)
{
req.DefaultRequestHeaders.Add("apikey", "myPassword");
string strUrl = "http://myUrl";
HttpResponseMessage hrm = await req.GetAsync(strUrl);
Console.WriteLine("=> statusCode:" + (int)hrm.StatusCode);
await Task.Delay(5000);
}
}
The output is:
The problem is when I use Postman or write this code with python as below, every time it responded 200 instead of 403.
import requests as req
import time as t
url = "http://adpsms.adpdigital.com/report/?date=2021-08-30"
customHeader = {"apikey": "sssrjdIiGisbViKA"}
i = 10
while (i > 0):
response = req.get(url, headers = customHeader)
print("statusCode: " + str(response.status_code))
i -= 1
t.sleep(5)
I supposed it is a server error but when I responded 200 every time with python I understand it would be a problem with my code or something client based.
Since my project is based on .NET I want to make it work on it.
Any suggestion would be appreciated.

On every iteration of your loop, you are adding DefaultRequestHeaders.
It means that they will be added again and again on each iteration of your cycle to the global instance of HttpClient
According to the official docs these headers will be sent with each request.
For your particular task you might add them only once(that's why the name contains prefix default.)
So if you slightly rewrite your code like this:
private static HttpClient req { get; set; } = new HttpClient();
static async Task Main(string[] args)
{
Console.WriteLine("Please press enter to start healthCheck");
Console.ReadLine();
AddDefaultHeaders();
healthCheck();
Console.ReadLine();
}
private static void AddDefaultHeaders()
{
req.DefaultRequestHeaders.Add("apiKey", "myPassword");
}
private static async Task healthCheck()
{
while (true)
{
string strUrl = "http://myUrl";
HttpResponseMessage hrm = await req.GetAsync(strUrl);
Console.WriteLine("=> statusCode:" + (int)hrm.StatusCode);
await Task.Delay(5000);
}
}
It should works fine.

Related

Constant communication between Python and Node

I'm making just for study, an API.
I want communicate one with other, my map for the problem is.
Using PyQt, develop a interface to instance a object with some attributes.
In the same time, open the navigator in the Node API(localhost:4100/ts)
I want communicate per example(1 letter typed on Python, change on the Node/client.
Node Api
class Server{
...
run(){
this.app.get("/ts",async(req,res) =>{
const user = await this.query()
res.render("ts",user)
})
this.app.use(express.static(__dirname))
const httpServer = http.createServer(this.app)
httpServer.listen(this.port, () =>{
console.log(`app listening on ${this.port}`);
})
}
async query(){
const b = 'user-signature'
const options = {
method: "POST",
body:JSON.stringify(b)
}
const uri = this.url+"mail"
try{
const postrequest = await fetch(uri,options)
const response = await postrequest.json()
return response
}
catch{
return new Mail('Name','LastName','Phone','Office','Sector','Email')
}
}
}
Python API
#app.route('/py/mail', methods=['POST'])
def mail():
print('initing')
data = request.get_data()
req = json.loads(data)
user = {
"first_name":input("Nome:"),
"last_name":input("Sobrenome:"),
"phone":input("Telefone:"),
"job_title":input("Cargo:"),
"en_job_title":input("Cargo em Inglês:"),
"mail":input('Email:'),
#"image_url":'https://www.ayrtonsenna.com.br/wp-content/uploads/2020/09/THUMBNAIL_SENNA_0420200903-3890-wlwakh.jpg'
}
The postrequest communicate with the python, but just one time, after that the callup end. It's possible make a constant communication between Node and Py? Like a listener?

websocket stops working after about 55 seconds

Sometimes it crashes after 54 seconds, sometimes 56 seconds. Output looks like:
Server started. Listening for incoming connections...
55 Received message: hello server
1/12/2023 7:38:25 AM|Fatal|WebSocket.<startReceiving>b__176_2|System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
at WebSocketSharp.Ext.<>c__DisplayClass48_0.<ReadBytesAsync>b__0(IAsyncResult ar)
I tried to add a try/catch block but I am not sure where the error is happening. I am running a websocketsharp server in c# and sending it sample data via python:
C# SERVER CODE:
using System;
using WebSocketSharp;
using WebSocketSharp.Server;
public class Echo : WebSocketBehavior
{
protected override void OnMessage(MessageEventArgs e)
{
try {
Console.WriteLine("Received message: " + e.Data);
Sessions.Broadcast(e.Data);
}
catch{
Console.WriteLine("bad happened");
}
}
}
public class Program
{
public static void Main(string[] args)
{
var wssv = new WebSocketServer(8081);
wssv.AddWebSocketService<Echo>("/Echo");
wssv.Start();
Console.WriteLine("Server started. Listening for incoming connections...");
Console.ReadLine();
wssv.Stop();
}
}
PYTHON CLIENT CODE:
import time
import websocket
def send_words(ws,words):
data = words
ws.send(data)
ws = websocket.create_connection("ws://localhost:8081/Echo")
while True:
time.sleep(1)
data = "hello server"
send_words(ws,data)
apparently its a websocket-sharp specific issue. You just have to add
wssv.KeepClean = false;
before
wssv.Start();

Swift HTTP session not sending actual Request

So I have some Swift code that send a request to my local host
//
// ContentView.swift
// Shared
//
// Created by Ulto4 on 10/23/21.
//
import SwiftUI
struct ContentView: View {
var body: some View {
VStack{
Text("Hello, world!")
.padding()
Button(action : {
self.fu()
}, label: {
Image(systemName: "pencil").resizable().aspectRatio(contentMode:.fit)
})
}
}
func fu(){
let url = URL(string: "http://127.0.0.1:5000/232")
guard let requestUrl = url else { fatalError() }
var request = URLRequest(url: requestUrl)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if let error = error {
print("Error took place \(error)")
return
}
if let response = response as? HTTPURLResponse {
print("Response HTTP Status code: \(response.statusCode)")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
}
However, on my Flask app there are no get requests coming in and the function isn't running. There also isn't anything printing to the console.
I am fairly new to swift so I don't really know how to fix this.
Is there any other way to send requests in swift, if not, How would I fix this?
You are creating the URLSessionDataTask, but you never start it. Call task.resume(), e.g.
func performRequest() {
guard let url = URL(string: "http://127.0.0.1:5000/232") else {
fatalError()
}
let task = URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
print("Error took place \(error)")
return
}
if let response = response as? HTTPURLResponse {
print("Response HTTP Status code: \(response.statusCode)")
}
}
task.resume() // you must call this to start the task
}
That having been said, a few caveats:
You are doing http rather than https. Make sure to temporarily enable insecure network requests with app transport settings, e.g.
You didn’t say if this was for macOS or iOS.
If running on physical iOS device, it will not find your macOS web server at 127.0.0.1 (i.e., it will not find a web server running on your iPhone). You will want to specify the IP number for your web server on your LAN.
If macOS, make sure to enable outbound network requests in the target’s “capabilities”:
You asked:
Is there any other way to send requests in swift?
It is probably beyond the scope of your question, but longer term, when using SwiftUI, you might consider using Combine, e.g., dataTaskPublisher. When running a simple “what was the status code” routine, the difference is immaterial, but when you get into more complicated scenarios where you have to parse and process the responses, Combine is more consistent with SwiftUI’s declarative patterns.
Let us consider a more complicated example where you need to parse JSON responses. For illustrative purposes, below I am testing with httpbin.org, which echos whatever parameters you send. And I illustrate the use of dataTaskPublisher and how it can be used with functional chaining patterns to get out of the mess of hairy imperative code:
struct SampleObject: Decodable {
let value: String
}
struct HttpBinResponse<T: Decodable>: Decodable {
let args: T
}
class RequestService: ObservableObject {
var request: AnyCancellable?
let decoder = JSONDecoder()
#Published var status: String = "Not started yet"
func startRequest() {
request = createRequest().sink { completion in
print("completed")
} receiveValue: { [weak self] object in
self?.status = "Received " + object.value
}
}
func createRequest() -> AnyPublisher<SampleObject, Error>{
var components = URLComponents(string: "https://httpbin.org/get")
components?.queryItems = [URLQueryItem(name: "value", value: "foo")]
guard let url = components?.url else {
fatalError("Unable to build URL")
}
return URLSession.shared.dataTaskPublisher(for: url)
.map(\.data)
.decode(type: HttpBinResponse<SampleObject>.self, decoder: decoder)
.map(\.args)
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
}
struct ContentView: View {
#ObservedObject var requestService = RequestService()
var body: some View {
VStack{
Text("Hello, world!")
.padding()
Button {
requestService.startRequest()
} label: {
Image(systemName: "pencil").resizable().aspectRatio(contentMode:.fit)
}
Text(requestService.status)
}
}
}
But, like I said, it is beyond the scope of this question. You might want to make sure you get comfortable with SwiftUI and basic URLSession programming patterns (e.g., making sure you resume any tasks you create). Once you have that mastered, you can come back to Combine to write elegant networking code.
FWIW, like workingdog said, you could also use the new async-await rendition of data(for:delegate:). But when in the declarative world of SwiftUI, I would suggest Combine.

node request vs python session

I have a working node.js script which written using the node.js request module.
I'm trying to convert this script to python with the session module.
I'm new to python and I followed the python docs as it mentioned. but I'm struggling to get my code works.
the problem I'm having is sending the cookie values in the subsequent requests with the session module.
as per the docs it is saving cookies and send them automatically in any requests after that. but
here is my working node.js script
const request = require('request');
const fs = require('fs');
const getOptions = {
jar:true,
followAllRedirects:true,
method:'GET',
url:'https://dummyurl.com'
};
request.get(getOptions,(err,response,html)=>{
if(err){
console.log('error in request');
console.log(err);
}
else {
const postOptions = {
jar:true,
followAllRedirects: true,
method:'POST',
url:'https://dummyurl.com',
form:{
'data':{
'page':2
}
}
};
request.post(postOptions,(err,response,html)=>{
if(err){
console.log('post err');
console.log(err);
}
else {
fs.writeFileSync('pyres.html',html,'utf8');
}
})
}
});
this is my python conversion of above script
s = requests.Session()
url= 'https://dummyurl.com'
response = s.get(url)
print(response.cookies)
data_url = 'https://dummyurl.com/'
postData = {
"data":{
"page":2
}
}
resultResponse = s.post(data_url,data=postData)
print(resultResponse.content)
Can anyone points me out any mistake in this code?
actually the problem was in data format.
in nodejs I post it like this
{'data':{'page':2} }
but in python it should be converted like this
{
'data[page]': '2'
}
not sure why it was not worked in normal json format in python

How do I correctly make consecutive calls to a child process in Node.js?

I have a Node.js application which is currently a web-based API. For one of my API functions, I make a call to a short Python script that I've written to achieve some extra functionality.
After reading up on communicating between Node and Python using the child_process module, I gave it a try and achieved my desired results. I call my Node function that takes in an email address, sends it to Python through std.in, my Python script performs the necessary external API call using the provided e-mail, and writes the output of the external API call to std.out and sends it back to my Node function.
Everything works properly until I fire off several requests consecutively. Despite Python correctly logging the changed e-mail address and also making the request to the external API with the updated e-mail address, after the first request I make to my API (returning the correct data), I keep receiving the same old data again and again.
My initial guess was that Python's input stream wasn't being flushed, but after testing the Python script I saw that I was correctly updating the e-mail address being received from Node and receiving the proper query results.
I think there's some underlying workings of the child_process module that I may not be understanding... since I'm fairly certain that the corresponding data is being correctly passed back and forth.
Below is the Node function:
exports.callPythonScript = (email)=>
{
let getPythonData = new Promise(function(success,fail){
const spawn = require('child_process').spawn;
const pythonProcess = spawn('python',['./util/emailage_query.py']);
pythonProcess.stdout.on('data', (data) =>{
let dataString = singleToDoubleQuote(data.toString());
let emailageResponse = JSON.parse(dataString);
success(emailageResponse);
})
pythonProcess.stdout.on('end', function(){
console.log("python script done");
})
pythonProcess.stderr.on('data', (data) => {
fail(data);
})
pythonProcess.stdin.write(email);
pythonProcess.stdin.end();
})
return getPythonData;
}
And here is the Python script:
import sys
from emailage.client import EmailageClient
def read_in():
lines = sys.stdin.readlines()
return lines[0]
def main():
client = EmailageClient('key','auth')
email = read_in()
json_response = client.query(email,user_email='authemail#mail.com')
print(json_response)
sys.stdout.flush()
if __name__ == '__main__':
main()
Again, upon making a single call to callPythonScript everything is returned perfectly. It is only upon making multiple calls that I'm stuck returning the same output over and over.
I'm hitting a wall here and any and all help would be appreciated. Thanks all!
I've used a Mutex lock for this kind of example. I can't seem to find the question the code comes from though, as I found it on SO when I had the same kind of issue:
class Lock {
constructor() {
this._locked = false;
this._waiting = [];
}
lock() {
const unlock = () => {
let nextResolve;
if (this._waiting.length > 0) {
nextResolve = this._waiting.pop(0);
nextResolve(unlock);
} else {
this._locked = false;
}
};
if (this._locked) {
return new Promise((resolve) => {
this._waiting.push(resolve);
});
} else {
this._locked = true;
return new Promise((resolve) => {
resolve(unlock);
});
}
}
}
module.exports = Lock;
Where I then call would implement it like this, with your code:
class Email {
constructor(Lock) {
this._lock = new Lock();
}
async callPythonScript(email) {
const unlock = await this._lock.lock();
let getPythonData = new Promise(function(success,fail){
const spawn = require('child_process').spawn;
const pythonProcess = spawn('python',['./util/emailage_query.py']);
pythonProcess.stdout.on('data', (data) =>{
let dataString = singleToDoubleQuote(data.toString());
let emailageResponse = JSON.parse(dataString);
success(emailageResponse);
})
pythonProcess.stdout.on('end', function(){
console.log("python script done");
})
pythonProcess.stderr.on('data', (data) => {
fail(data);
})
pythonProcess.stdin.write(email);
pythonProcess.stdin.end();
})
await unlock();
return getPythonData;
}
}
I haven't tested this code, and i've implemented where i'm dealing with arrays and each array value calling python... but this should at least give you a good start.

Categories

Resources