I'm having some issues retrieving cookies sent by the client on the server using the python module cherrypy.
In the web browser I can see the cookies in Chrome's Web Console by going to Resources -> Cookies -> localhost. And then I have 3 cookies with the following values.
And on the server side I have the following information from the Eclipse debugger:
My question is why don't foo and release_id show up in the keys? Is there something I'm doing wrong?
NOTE:
cookies = cherrypy.request.cookie
Javascript code for setting the cookies:
$(function() {
// Functions from W3C Schools: http://www.w3schools.com/js/js_cookies.asp
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var expires = "expires="+d.toUTCString() + ";";
var path = "path=/;" // Accessible to all.
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) != -1) return c.substring(name.length, c.length);
}
return "";
}
setCookie("foo", "bar", 1 );
setCookie("release_id", "2", 1 );
});
Are you sure that the cookies.keys is not cherrypy.response.cookie?
cherrypy.response.cookie != cherrypy.request.cookie
From the debugger print-screen perspective, seems ok to havecherrypy.response.cookie with just thesession_id key at this point.
Related
Hi I’m figuring out how to share Plex library in dart.
I'm helping myself with this working script in python ( it works)
https://gist.github.com/JonnyWong16/f8139216e2748cb367558070c1448636
unfortunately my code returns an http error 400, bad request
note: When I run the dart code there are no shared library.
maybe the payload is not correct :|
Thank for any help
import 'package:http/http.dart' as http;
class Server {
String token, ip, port;
Server(this.ip, this.port, this.token);
share() async {
var server_id = '00000000000000000000000000000000'; fake id
var library_section_ids = '97430074'; // right id , it works in python
var invited_id = '50819899'; // right id , it works in python
var headers = {
'Accept': 'application/json',
'X-Plex-Token': token,
};
var data =
'["server_id": $server_id,'
' "shared_server":["library_section_ids":[$library_section_ids],'
' "invited_id":$invited_id]';
var res = await http.post(
Uri.parse(
'https://plex.tv/api/servers/$server_id/shared_servers/'),
headers: headers,
body: data);
if (res.statusCode != 200) {
throw Exception('http.post error: statusCode= ${res.statusCode}');
}
print(res.body);
}
}
void main(List<String> arguments) async {
var srv = Server('xxx.yyy.xxx.yyy', '32400', '000000000-1111');
await srv.share();
}
The old code has a few bug and don't encode perfectly the data
I solved with 'dio' package and this link helped me a lot https://reqbin.com/
If the user has no shared library this code add a new one
import 'package:dio/dio.dart';
class Server {
String token;
Server(this.token);
test() async {
var serverId = '';
var librarySectionIds = ;
var invitedId = ;
var dio = Dio();
var data = {
"server_id": serverId,
"shared_server": {
"library_section_ids": librarySectionIds,
"invited_id": invitedId
}
};
dio.options.headers['Accept'] = 'application/json';
dio.options.headers["authorization"] = "Bearer $token";
var response = await dio.post(
'https://plex.tv/api/servers/$serverId/shared_servers/',
data: data);
print(response);
}
I have a web scraping application written completely in python. The information that I am web scraping is behind a login and I am using Request.session to save login sessions. I am trying to port the code to Node.js and wasn't able to find anything similar to request.session on Node.js. Please let me know if such a thing exists. Thank you.
Your best bet is using axios, which allows for extensive customization of request headers and types of authentication.
You can add axios-cookiejar for cookie management.
Simple example:
const axios = require('axios').default;
const axiosCookieJarSupport = require('axios-cookiejar-support').default;
axiosCookieJarSupport(axios);
// you can add an Authorization header to all requests:
// axios.defaults.headers.common['Authorization'] = 'Bearer token';
const cookie = 'lang=en; token=hello';
const body = {message: 'I\'m a message body'};
axios.post(url, body, {
auth: {
username: 'username',
password: 'mypassword',
},
headers: {
'Cookie': cookie,
'Content-Type': 'application/json',
},
})
.then(res => console.log(res))
.catch(err => console.error(err));
Old Answer:
I believe the Request object of the default HTTP server does not have what you are looking for.
But if you opted to use the Express framework, you could find similar functionalities in the express-session package.
To ilustrate it's capabilities and simplicity, here's a slightly tweaked version of the code example provided in their documentation:
const express = require('express')
const parseurl = require('parseurl')
const session = require('express-session')
const app = express()
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
}));
app.use((req, res, next) => {
if (!req.session.views) {
req.session.views = {}
}
// get the url pathname
const pathname = parseurl(req).pathname;
// count the views
req.session.views[pathname] = (req.session.views[pathname] || 0) + 1;
next();
});
app.get('/foo', (req, res, next) => {
res.send('you viewed this page ' + req.session.views['/foo'] + ' times');
});
app.get('/bar', (req, res, next) => {
res.send('you viewed this page ' + req.session.views['/bar'] + ' times');
});
app.use((req, res, next) => {
if (res.headersSent) {
return next();
} else {
console.error('Not found');
const err = new Error('Not Found');
err.status = 404;
return next(err);
}
});
app.use((err, req, res, next) => {
console.error(req.app.get('env') === 'production' ? err.message : err.stack);
if (res.headersSent) {
return next(err);
}
res.status(err.status || 500);
res.send(`${err.status} - ${err.message}`);
});
const http = require('http');
const server = http.createServer(app).listen(3000);
server.on('error', (e) => {
console.log('>>> Server error');
console.error(e);
});
console.log(`>>> Server running on localhost:3000`);
I am not able to redirect to the main.demo. Everything is working fine until data upload after that redirect is not happening. Why?
EDIT: app.py
from flask import Blueprint
main = Blueprint('main', __name__)
import json
import os
from flask import Flask, request,render_template,url_for,redirect
from werkzeug import secure_filename
import glob2
from uuid import uuid4
#main.route('/')
def index():
"""Main index page """
return render_template('index.html')
#main.route('/upload', methods=["GET","POST"])
def upload():
if request.method == 'POST':
form = request.form
# Create a unique "session ID" for this particular batch of uploads.
upload_key = str(uuid4())
# Is the upload using Ajax, or a direct POST by the form?
is_ajax = False
if form.get("__ajax", None) == "true":
is_ajax = True
# Target folder for these uploads.
target = "upload/{}".format(upload_key)
try:
os.mkdir(target)
except:
if is_ajax:
return ajax_response(False, "Couldn't create upload directory: {}".format(target))
else:
return "Couldn't create upload directory: {}".format(target)
print "=== Form Data ==="
for key, value in form.items():
print key, "=>", value
for upload in request.files.getlist("file"):
filename = upload.filename.rsplit("/")[0]
destination = "/".join([target, filename])
print "Accept incoming file:", filename
print "Save it to:", destination
upload.save(destination)
return redirect(url_for("main.demo"))
return render_template("upload.html")
#main.route('/demo',methods=["GET","POST"])
def demo():
if request.method == "GET":
return render_template("demo.html")
def ajax_response(status, msg):
status_code = "ok" if status else "error"
return json.dumps(dict(
status=status_code,
msg=msg,
))
def create_app():
global app
app = Flask(__name__,template_folder=os.path.join(os.path.dirname(os.path.abspath(__file__)),'templates'))
app.debug = True
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.register_blueprint(main)
#app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
return app
Following are some the logs which I am getting:
=== Form Data ===
__ajax => true
Accept incoming file: demo.txt
Save it to: upload/XXXXXXX-XXXXXX-XXXXX-XXXXXXX/demo.txt
"POST /upload HTTP/1.1" 302 231 "http://localhost:5000/upload"
"GET /demo HTTP/1.1" 200 3624 "http://localhost:5000/upload"
It's showing that it's going for demo, but the final url is wrong. Why is it like that?
EDIT 1:
Is it like I am unable to submit the form as the page doesn't gets refreshed ? But its getting redirected to demo() function execute it but doesn't but doesn't render_template. Or it does but somehow gets back to the same function ?
EDIT 2:
More to add this code is using following JavaScript in the background
// Constants
var MAX_UPLOAD_FILE_SIZE = 1024*1024; // 1 MB
var UPLOAD_URL = "/upload";
var NEXT_URL = "/demo";
// List of pending files to handle when the Upload button is finally clicked.
var PENDING_FILES = [];
$(document).ready(function() {
// Set up the drag/drop zone.
initDropbox();
// Set up the handler for the file input box.
$("#file-picker").on("change", function() {
handleFiles(this.files);
});
// Handle the submit button.
$("#upload-button").on("click", function(e) {
// If the user has JS disabled, none of this code is running but the
// file multi-upload input box should still work. In this case they'll
// just POST to the upload endpoint directly. However, with JS we'll do
// the POST using ajax and then redirect them ourself when done.
e.preventDefault();
doUpload();
})
});
function doUpload() {
$("#progress").show();
var $progressBar = $("#progress-bar");
// Gray out the form.
$("#upload-form :input").attr("disabled", "disabled");
// Initialize the progress bar.
$progressBar.css({"width": "0%"});
// Collect the form data.
fd = collectFormData();
// Attach the files.
for (var i = 0, ie = PENDING_FILES.length; i < ie; i++) {
// Collect the other form data.
fd.append("file", PENDING_FILES[i]);
}
// Inform the back-end that we're doing this over ajax.
fd.append("__ajax", "true");
var xhr = $.ajax({
xhr: function() {
var xhrobj = $.ajaxSettings.xhr();
if (xhrobj.upload) {
xhrobj.upload.addEventListener("progress", function(event) {
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
}
// Set the progress bar.
$progressBar.css({"width": percent + "%"});
$progressBar.text(percent + "%");
}, false)
}
return xhrobj;
},
url: UPLOAD_URL,
method: "POST",
contentType: false,
processData: false,
cache: false,
data: fd,
success: function(data) {
$progressBar.css({"width": "100%"});
data = JSON.parse(data);
// How'd it go?
if (data.status === "error") {
// Uh-oh.
window.alert(data.msg);
$("#upload-form :input").removeAttr("disabled");
return;
}
else {
// Ok! Get the UUID.
var uuid = data.msg;
//window.location = NEXT_URL + uuid;
window.location = NEXT_URL;
}
},
});
}
function collectFormData() {
// Go through all the form fields and collect their names/values.
var fd = new FormData();
$("#upload-form :input").each(function() {
var $this = $(this);
var name = $this.attr("name");
var type = $this.attr("type") || "";
var value = $this.val();
// No name = no care.
if (name === undefined) {
return;
}
// Skip the file upload box for now.
if (type === "file") {
return;
}
// Checkboxes? Only add their value if they're checked.
if (type === "checkbox" || type === "radio") {
if (!$this.is(":checked")) {
return;
}
}
fd.append(name, value);
});
return fd;
}
function handleFiles(files) {
// Add them to the pending files list.
for (var i = 0, ie = files.length; i < ie; i++) {
PENDING_FILES.push(files[i]);
}
}
function initDropbox() {
var $dropbox = $("#dropbox");
// On drag enter...
$dropbox.on("dragenter", function(e) {
e.stopPropagation();
e.preventDefault();
$(this).addClass("active");
});
// On drag over...
$dropbox.on("dragover", function(e) {
e.stopPropagation();
e.preventDefault();
});
// On drop...
$dropbox.on("drop", function(e) {
e.preventDefault();
$(this).removeClass("active");
// Get the files.
var files = e.originalEvent.dataTransfer.files;
handleFiles(files);
// Update the display to acknowledge the number of pending files.
$dropbox.text(PENDING_FILES.length + " files ready for upload!");
});
// If the files are dropped outside of the drop zone, the browser will
// redirect to show the files in the window. To avoid that we can prevent
// the 'drop' event on the document.
function stopDefault(e) {
e.stopPropagation();
e.preventDefault();
}
$(document).on("dragenter", stopDefault);
$(document).on("dragover", stopDefault);
$(document).on("drop", stopDefault);
}
I have tried to integrate the functionality from the following link: Flask Multiple Upload
Unable to understand that why its still going to /upload even after hitting the /demo
Can somebody help me with this that what is happening in the background ?
In short, my guess is that you are falsely expecting a response to XHR request to change browser's address.
Here's a more detailed explanation of what I think is happening:
A user clicks the upload button
doUpload() Javascript function is called
doUpload() makes an XHR (ajax) request to UPLOAD_URL (POST /upload)
upload() Python function is called and after successful upload generates a "302 Found" redirect response to /demo
browser receives this response and follows the provided URL, in this case it goes to /demo (note that this does not change the address, it happens in the background as part of the XHR request)
demo() Python function renders some HTML, which is returned as a "200 OK" response
the XHR call from step 3 receives this HTML from step 5 and checks whether the response indicates success
success function is triggered and tries to parse HTML as JSON JSON.parse(data), which should fail
I have made some assumptions about your browser, Javascript libraries, HTML templates, and user interaction, but I see this as the most likely explanation from the code you have provided.
My suggestion is to first try replacing return redirect(url_for("main.demo")) with something like this:
if is_ajax:
return ajax_response(True, upload_key)
else:
return redirect(url_for("main.demo"))
In this case, after a successful upload window.location = NEXT_URL will get executed inside your doUpload() and that will change the address in your browser.
Long story short.
Having some problems with some coding in python.
working on a program to spoof mac address and open new trial session on ap,
(this is for education only.)
the program works with ap that has free 1 hour pass.
the program works like this:
shuts off the wifi adapter
runs .bat script, which changes mac address to random mac address.
turns wifi back on.
opens browser and sends login through with new mac address.
repeats every 1 hour.
the problem:
I am able to shut dowm, change address and bring back up. but,
how do i get the new address in a var and pass it through a web browser to re auth myself.
and open a new session of the trial?
import urllib.parse
import urllib.request
import os
import time
def main():
wifidown()
changemac()
wifiup()
reauth()
time.sleep(3600)
def wifidown():
os.system("wmic path win32_networkadapter where index=7 call disable")
def changemac():
os.system("C:\Users\username\somewhere\theprogram\theprogram.bat")
def wifiup():
os.system("wmic path win32_networkadapter where index=7 call enable")
def reauth():
url = 'https://server.name.com/anothername/?client-mac=mymacaddress&ap-mac=addressofap&hash=somehasvaluethatpassesthrough'
values = {'plan' : 'trial',
'zip code' : '12345',
'e mail' : 'anemail#someemail' }
data = urllib.parse.urlencode(values)
data = data.encode('utf-8')
req = urllib.request.Request(url, data)
response = urllib.request.urlopen(req)
the_page = response.read()
while True:
main()
Thank you.
Update**
Yes it helps. I was trying to do this way.
macid = "01:02:03:04:05:06"
mac = "?client-mac=" + macid
apid = "01:02:03:04:05:06"
ap = "&ap-mac=" + apid
hashid = "8JTsXjOC7jcCppExAqbsBmFF4kNMePA6wgrMaMI6MLDUO6bZsc8tgQMfEfGY%2Bp9aLEdXfTZCapb%2B93DotAFLlQ%3D%3D"
thehash = "&hash=" + hashid
url = 'https://the.ap.server.website/' + mac + ap + thehash
def main():
wifidown()
changemac()
wifiup()
urlfunction()
time.sleep(3600)
def wifidown():
os.system("wmic path win32_networkadapter where index=7 call disable")
def changemac():
os.system("C:\Users\esc_fn\Desktop\macchanger\macchange.bat")
def urlfunction():
webbrowser.open_new(url)
def wifiup():
os.system("wmic path win32_networkadapter where index=7 call enable")
while True:
main()
the ap uses a script called purchase.js to get the form data and send it.
the code for that is.
var pdate = new Date();
var offerlink = basepath + 'terms/';
$(document).ready(function(){
// Hide Sponsored Access form
$('#complimentary_spn').hide();
$('#xsubad').hide();
$('a#inline').fancybox({
hideOnContentClick: false,
showCloseButton: false,
margin: 0,
padding: 0
});
$('a.iframe').fancybox({
hideOnContentClick: false,
showCloseButton: false,
scrolling: 'no',
margin: 0,
padding: 0,
height: 510
});
$('#triggerComplete').fancybox({
hideOnContentClick: false,
showCloseButton: false,
margin: 0,
padding: 0
});
$('#rateplanid').change(function(){
// Clear all errors
clear_all_errors('#messageBox');
var planid = $(this).val();
if (planid > 0)
{
$('#complimentary_spn').fadeOut('fast');
$('#xsubad').fadeOut('fast');
$('#paid').fadeIn('fast');
// Set offer and restrictions link
$('#offerlink').find('.pop').attr('href', offerlink+'ppu');
}
else
{
$('#paid').fadeOut('fast');
$('#complimentary_spn').fadeIn('fast');
if ($.inArray(planid, do_reg) < 0)
$('#xsubad').fadeIn('fast');
// Set offer and restrictions link
$('#offerlink').find('.pop').attr('href', offerlink+planid);
}
// Set plan cookie to expire in 10 minutes
pdate.setTime(pdate.getTime() + (10 * 60 * 1000));
setCookie('planid', planid, pdate, '/', '', '');
// Reset required fields
set_required_fields();
// Disable submit buttons
check_enable_submit();
$(this).blur();
});
// Set default plan
if (getCookie('planid'))
$('#rateplanid').val(getCookie('planid'));
else if (planid)
$('#rateplanid').val(planid);
// Trigger change to set required fields
$('#rateplanid').trigger('change');
$("#pwreset").click(function(){
$.post(
basepath + 'ajax/resetpw',
{
username: $('#resetuser').val()
},
function(data) {
if (data == '')
{
$.fancybox.close();
return;
}
set_error('resetuser', data);
}
);
});
$('input, select').not('#resetuser').change(function(){
$.post(
actionurl+'/validate',
$('#purchaseForm').serialize() + '&key=' + $(this).attr('name'),
function(data) { validate_done(data) }
);
});
$('input.submitOrderButton, input.startSessionButton').click(function(){
if ($(this).hasClass('opaque'))
return;
$.post(
actionurl+'/validate',
$('#purchaseForm').serialize(),
function(data) { validate_done(data) }
);
});
});
// Override validation error
validate_error = function(json_data)
{
//console.info('purchase.validate_error');
try
{
if (json_data.errors.nobilling)
{
// Pop payment form
$('.iframe').click()
return;
}
$.each(json_data.errors, function(key, msg) {
set_error(key, msg);
});
window.location.hash = '#messageBox';
}
catch (e)
{
console.error('purchase.validate_error - %s - %s', e.name, e.message);
}
};
// Override validation success
validate_success = function(json_data)
{
//console.info('purchase.validate_success');
try
{
var planid = $('#rateplanid').val();
// For Sponsored Access, perform login
if ($.inArray(planid, ['spn']) >= 0)
{
do_login();
return;
}
// For paid access, pop confirmation screen
$('#completePopup').html(json_data.data.pophtml);
$('#triggerComplete').click();
// Track with Omniture
var s = s_gi('comcastwificaptiveportalprod');
s.tl(this,'o','Payment Confirmation Desktop Page');
return;
}
catch (e)
{
console.error('purchase.validate_success - %s - %s', e.name, e.message);
}
};
var confirmed = function()
{
$.fancybox.close();
do_login();
};
var set_required_fields = function()
{
//console.info('purchase.set_required_fields');
// Clear required fields
$('.required').removeClass('required');
var planid = $('#rateplanid').val();
if (planid > 0)
{
// Set required fields
$('input#username, input#password, input#password1, input#password2').addClass('required');
$('input#firstname, input#lastname, input#email').addClass('required');
$('#paymentFormInputs1, #paymentFormInputs2').find(':input').each(function() {
$(this).not('#storeinfo').addClass('required');
});
}
else
{
// Set required fields
$('#complimentary_'+planid).find(':input').each(function() {
$(this).addClass('required');
});
}
};
My question is:
how do I get the new mac address in the variable called macid
how do I get the ap mac address in the variable apid
how do I get the hash it is asking for and put it in the variable hashid
how do I send the appropriate form data through. ie.. plan id.
You just need to auth yourself on the authentication server right? I think process of authentication and re-authentication is the same. Recommend using requests module. Here is link for you.
Try authentication code like this:
>>> from requests.auth import HTTPBasicAuth
>>> requests.get('https://api.github.com/user', auth=HTTPBasicAuth('user', 'pass'))
<Response [200]>
Hope it helps. :)
i just tested out a script i made. it is in python. i use ajax, to send a request and try and get the result.
function ajaxFunction(){
var ajaxRequest;
var e = document.getElementById("ktype");
var ktype = e.options[e.selectedIndex].value;
var acookie = document.getElementById("acookie").value;
alert (ktype +"\n" + acookie);
try{
ajaxRequest = new XMLHttpRequest();
} catch (e){
try{
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try{
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e){
return false;
}
}
}
ajaxRequest.onreadystatechange = function(){
if (ajaxRequest.readyState < 4){
document.getElementById("resp").innerHTML = "<center><img src='loading.gif' style='max-width:60px; max-height:60px;'></center>";
}
if(ajaxRequest.readyState == 4){
document.getElementById("resp").innerHTML = ajaxRequest.responseText;
}
}
ajaxRequest.open("POST", "kindle.py", true);
ajaxRequest.setRequestHeader("Content-type","application/x-www-form-urlencoded");
ajaxRequest.send("amzcookie=" + acookie + "&ktype=" + ktype);
}
the python script uses CGI. no web framework like django.
when i do this request it just prints the contents of the python file. no code is executed.
You should use JQuery for that ... instead of writing your own Ajax request, it can be written in a line:
$.post('link-to-my-python-script',{data},
function(answer){
// process your request here ..
});
You can read more about that here: JqueryPost