I'm having difficulty parsing a JSON string with nested arrays. here is an example of the JSON
const allHeaders = {"Strict-Transport-Security":"max-age=31536000","Timing-Allow-Origin":"*","s_ip":"1.5.295.221","Server":"Asia","Vary":"Accept-Encoding","x-application-context":"shop-buyer-s.7001","s_group":"buyer-sessio","Content-Language":"zh-CN","Access-Control-Allow-Headers":"Origin, x-ua, x-umidtoken, x-csrf-token, X-Requested-With, Content-Type, Accept","Set-Cookie":["hms_cid=80dcf576-a581-4d43-8302-1605fe36565c; Domain=.hms.zn; Expires=Sun, 09-Jul-2023 04:39:13 GMT; Path=/","hms_sid=112120422020a413958ddf33139b516b; Domain=.hms.zn; Path=/; HttpOnly","_tb_token_=e8eafb9bebe63; Domain=.hms.zn; Path=/; HttpOnly"],"Transfer-Encoding":"chunked","object-status":"ttl=2592000,age=42,gip=121.43.99.68","Connection":["keep-alive","Transfer-Encoding"],"s_tag":"285873024335988|0^|^^","s_tid":"21410a7016573415536295456ef332","eagleeye-traceid":"21410a7016573415536295456ef332","s_v":"4.0.2.0","Content-Encoding":"gzip","P3P":"CP='CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR'","Date":"Sat, 09 Jul 2022 04:39:13 GMT","Access-Control-Max-Age":"3600","s_ucode":"Asia:CENTER","Access-Control-Allow-Methods":"POST, GET, OPTIONS, DELETE","Content-Type":"text/html;charset=UTF-8","s_status":"STATUS_NOT_EXISTED"}
I need to get the number hms_sid=
exmple: 112120422020a413958ddf33139b516b
I'm trying
const sid = allHeaders['Set-Cookie']
It is unlikely that hms_sid would always appear as the second tuple in the cookie list. Use Array.filter() to locate it, then get the first matching cookie and extract the value with String.match(), testing for missing values, like this:
function test() {
console.log(getCookieTokenValue_(allHeaders, 'hms_sid'));
}
function getCookieTokenValue_(headers, token) {
const tokenRegex = new RegExp('\\b' + token + '=(\\w+)');
const cookies = headers['Set-Cookie'];
const tokens = cookies.filter(cookie => cookie.match(tokenRegex));
return tokens.length ? tokens[0].match(tokenRegex)[1] : null;
}
I'm pretty sure google apps script is just javascript so here's my code:
let cookie = allHeaders['Set-Cookie'][1];
let tokens = cookie.split(";");
let sidString = tokens[0].split("=");
let sid = sidString[1];
Here is how I did it:
Given:
const allHeaders = {
"Strict-Transport-Security": "max-age=31536000",
"Timing-Allow-Origin": "*",
"s_ip": "1.5.295.221",
"Server": "Asia",
"Vary": "Accept-Encoding",
"x-application-context": "shop-buyer-s.7001",
"s_group": "buyer-sessio",
"Content-Language": "zh-CN",
"Access-Control-Allow-Headers": "Origin, x-ua, x-umidtoken, x-csrf-token, X-Requested-With, Content-Type, Accept",
"Set-Cookie": ["hms_cid=80dcf576-a581-4d43-8302-1605fe36565c; Domain=.hms.zn; Expires=Sun, 09-Jul-2023 04:39:13 GMT; Path=/", "hms_sid=112120422020a413958ddf33139b516b; Domain=.hms.zn; Path=/; HttpOnly", "_tb_token_=e8eafb9bebe63; Domain=.hms.zn; Path=/; HttpOnly"],
"Transfer-Encoding": "chunked",
"object-status": "ttl=2592000,age=42,gip=121.43.99.68",
"Connection": ["keep-alive", "Transfer-Encoding"],
"s_tag": "285873024335988|0^|^^",
"s_tid": "21410a7016573415536295456ef332",
"eagleeye-traceid": "21410a7016573415536295456ef332",
"s_v": "4.0.2.0",
"Content-Encoding": "gzip",
"P3P": "CP='CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR'",
"Date": "Sat, 09 Jul 2022 04:39:13 GMT",
"Access-Control-Max-Age": "3600",
"s_ucode": "Asia:CENTER",
"Access-Control-Allow-Methods": "POST, GET, OPTIONS, DELETE",
"Content-Type": "text/html;charset=UTF-8",
"s_status": "STATUS_NOT_EXISTED"
}
I pulled the cookie the same that you did:
let cookie = allHeaders['Set-Cookie'];
The issue with this is that it returns:
[
'hms_cid=80dcf576-a581-4d43-8302-1605fe36565c; Domain=.hms.zn; Expires=Sun, 09-Jul-2023 04:39:13 GMT; Path=/',
'hms_sid=112120422020a413958ddf33139b516b; Domain=.hms.zn; Path=/; HttpOnly',
'_tb_token_=e8eafb9bebe63; Domain=.hms.zn; Path=/; HttpOnly'
]
Using typeof I was able to determine this is an Object type.
let cookie = allHeaders['Set-Cookie'];
console.log(typeof(cookie));
object
Since this is an Object I enumerated the keys:
console.log(Object.keys(cookie));
[ '0', '1', '2' ]
Now I'm able to match the comma separated values with an object key. This means I can get only the cookie value with the info I need:
let cookie = allHeaders['Set-Cookie'][1];
Which outputs:
hms_sid=112120422020a413958ddf33139b516b; Domain=.hms.zn; Path=/; HttpOnly
After that I checked the type of the object again with typeof to find out it's a String so I used .split(";") string function to tokenize the string:
[
'hms_sid=112120422020a413958ddf33139b516b',
' Domain=.hms.zn',
' Path=/',
' HttpOnly'
]
we only care about the first token and we want to tokenize that again by =:
let sidString = tokens[0].split("=");
[ 'hms_sid', '112120422020a413958ddf33139b516b' ]
And there we have it, we can get the value with sidString[1]
Related
Hi I need to remove parts of a response I'm getting from a REST call.
the call that's getting returned is:
URI: https://apiext.thisurl.com/ado/v1/listener
HTTP Version: 1.1
Headers:
{
Authorization: Basic ********
Content-Type: application/json; charset=utf-8
}
Content:
{
"subscriptionId": "5898cfds-aafds2223335-423004422e"
"notificationId": 13869
"id": "846714a-b461e-449e-9600-f68a9975d2f4"
"eventType": "workitem.updated"
"publisherId": "tfs"
"message": {
"text": "User Story #2202091 (0819 ado 2) update)"
"html": "<a href="https://dev.azure.com/zsETO/web/wi.aspx?pcguid=931ea459-abea-43db-9aed-eb489dee1e5e&id=22221">User Story #2202091 (0819 ado 2) updated by Darren"
"markdown": "User Story #2202091 (0819 ado 2) updated by Darre"
}
I need to remove the following parts of the call so I can use json slurper
URI: https://apiext.thisurl.com/ado/v1/listener
HTTP Version: 1.1
Headers:
{
Authorization: Basic ********
Content-Type: application/json; charset=utf-8
}
Content:
So the final result returns:
{
"subscriptionId": "5898cfds-aafds2223335-423004422e"
"notificationId": 13869
"id": "846714a-b461e-449e-9600-f68a9975d2f4"
"eventType": "workitem.updated"
"publisherId": "tfs"
"message": {
"text": "User Story #2202091 (0819 ado 2) update)"
"html": "<a href="https://dev.azure.com/zsETO/web/wi.aspx?pcguid=931ea459-abea-43db-9aed-eb489dee1e5e&id=22221">User Story #2202091 (0819 ado 2) updated by Darren"
"markdown": "User Story #2202091 (0819 ado 2) updated by Darre"
}
I've tried using drop as in
def removeParts = requestInfo.drop(70)
but some of the uri's in the response data vary in character length. Was hoping to remove the content based on a key such as "URI:"
Any help would be appreciated
The call I'm sending to get this data is:
public def getNotificatonsDetails(collection, subId, notificationId) {
projectManagmentService.getProject(collection, project)
def result = genericRestClient.get(
contentType: ContentType.JSON,
//requestContentType: ContentType.JSON,
uri: "${genericRestClient.getTfsUrl()}/${collection}/_apis/hooks/subscriptions/${subId}/notifications/${notificationId}?",
headers: ['Content-Type': 'application/json'],
query: ['api-version':'7.0']
)
return result;
}
I'm calling this method in another class as:
def notificationDetails = subscriptionService.getNotificatonsDetails(collection, subId, notificationId)
I then drill down into notificationDetails to to get the requestInfo
def requestInfo = "${notificationDetails.details.request}"
The result is what's mentioned above with the URI,HTTP, and Headers data that I need to remove
I am trying to send JSON data of python3 socket, but on the receiving end the double quotes get turned into single quotes so I can not read it
Sending
server_name = "One"
response_data = {"error": "false", "data": "Success", "Server": server_name}
response_request = "HTTP/1.1 200 OK\n\n" + response_data
sock.send(response_request.encode())
sock.close()
Receive
response = requests.get("http://localhost/")
print(response.text)
{'error': 'false', 'data': 'Success', 'Server': server_name}
The doubles quotes get changed to single quotes
But if I send
"""HTTP/1.1 200 OK\n\n{"error": "false", "data": "Success"}"""
It will not change the double quotes but I can not send the server_name variable
Your server doesn't work, but to make a working server you need to json.dumps the dictionary object into a string. Here's a minimal working JSON server that sets the content type header and can be read by the requests module:
server.py
from http.server import BaseHTTPRequestHandler, HTTPServer
import json
class Server(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
server_name = "One"
response_data = {"error": "false", "data": "Success", "Server": server_name}
self.wfile.write(json.dumps(response_data).encode())
httpd = HTTPServer(('', 8080), Server)
httpd.serve_forever()
client.py
import requests
response = requests.get("http://localhost:8080/")
print(response.text) # returns string
print(response.json()) # returns parsed JSON object (dict in this case)
Output (client):
{"error": "false", "data": "Success", "Server": "One"}
{'error': 'false', 'data': 'Success', 'Server': 'One'}
When I make the following call:
/beta/me/messages/{id}?$select=internetMessageHeaders
I get the following output:
{
"#odata.context": "https://graph.microsoft.com/beta/$metadata#users('...')/messages(internetMessageHeaders)/$entity",
"#odata.etag": "...",
"id": "AAMkAGY1Mz...",
"internetMessageHeaders": [
{
"name": "Received",
"value": "from CY1PR16MB0549.namprd16.prod.outlook.com (2603:10b6:903:13d::13) by DM3PR16MB0553.namprd16.prod.outlook.com with HTTPS via CY4PR06CA0051.NAMPRD06.PROD.OUTLOOK.COM; Fri, 16 Feb 2018 22:14:45 +0000"
},
...
]
}
And nowhere do I find 'To' or 'From' fields in the response. Why? Is there a way to retrieve this information?
From the documentation, this property holds:
A key-value pair that represents an Internet message header, as defined by RFC5322, that provides details of the network path taken by a message from the sender to the recipient.
Based on that description, your result looks correct to me:
from CY1PR16MB0549.namprd16.prod.outlook.com (2603:10b6:903:13d::13)
by DM3PR16MB0553.namprd16.prod.outlook.com
with HTTPS
via CY4PR06CA0051.NAMPRD06.PROD.OUTLOOK.COM;
Fri, 16 Feb 2018 22:14:45 +0000
For the To and From addresses, you need to add toRecipients and from to your $select clause.
/beta/me/messages/{id}?$select=toRecipients,from,internetMessageHeaders
I'm performing a request to a foreign API using luasec, lua-socket and converting the data, a JSON string, to a lua table with cjson. I've read the docs of said modules and unfortunately none of it helped me with my problem. Can't link more than 2 websites with current account, sorry.
Summary: I get the response and the appropiate string using the posted request function, when turning said string into a lua table via cjson.decode the output table isn't the desired one, it's a copy of my response header, which is not intentional.
The following code is how I do my request:
local function request (req_t)
local res_t = {}
resp = https.request {
url = const.API_URL .. req_t.url,
method = req_t.method,
headers = req_t.headers,
sink = ltn12.sink.table(res_t)
}
return table.concat(res_t), resp.headers, resp.code
end
Using the following call
local res, headers = request({ ... })
I receive the proper response as a string but my goal is to do data manipulation with it, so turning said response(string) to a lua table with
local resJson = cjson.decode(res)
Does not produce the correct output. It does produce a table which is exactly the same as my response header. Here is the following output from my terminal alongside the code
When out of function type is: string
Desired response in string:
{"total_photos":221926,"photo_downloads":"186029632.0"}
When out of function type is: string
Desired response in string:
{"total_photos":221926,"photo_downloads":"186029632.0"}
After decode, type is: table
server Cowboy
strict-transport-security max-age=31536000
access-control-allow-headers *
x-ratelimit-limit 50
x-ratelimit-remaining 46
x-cache-hits 0, 0
accept-ranges bytes
access-control-request-method *
x-request-id ee5a74fd-2b10-4f46-9c25-5cfc53aeac6c
access-control-expose-headers Link,X-Total,X-Per-Page,X-RateLimit-Limit,X-RateLimit-Remaining
content-type application/json
connection close
content-length 55
fastly-debug-digest f62d52c08b1ef74db89a66a0069f0a35c49e52230567905240dacf08c9ea1813
vary Origin
cache-control no-cache, no-store, must-revalidate
x-timer S1496524765.369880,VS0,VE111
x-cache MISS, MISS
x-served-by cache-iad2123-IAD, cache-mad9429-MAD
via 1.1 vegur, 1.1 varnish, 1.1 varnish
date Sat, 03 Jun 2017 21:19:25 GMT
age 0
access-control-allow-origin *
x-runtime 0.011667
Printing header
server Cowboy
strict-transport-security max-age=31536000
access-control-allow-headers *
x-ratelimit-limit 50
x-ratelimit-remaining 46
x-cache-hits 0, 0
accept-ranges bytes
access-control-request-method *
x-request-id ee5a74fd-2b10-4f46-9c25-5cfc53aeac6c
access-control-expose-headers Link,X-Total,X-Per-Page,X-RateLimit-Limit,X-RateLimit-Remaining
content-type application/json
connection close
content-length 55
fastly-debug-digest f62d52c08b1ef74db89a66a0069f0a35c49e52230567905240dacf08c9ea1813
vary Origin
cache-control no-cache, no-store, must-revalidate
x-timer S1496524765.369880,VS0,VE111
x-cache MISS, MISS
x-served-by cache-iad2123-IAD, cache-mad9429-MAD
via 1.1 vegur, 1.1 varnish, 1.1 varnish
date Sat, 03 Jun 2017 21:19:25 GMT
age 0
access-control-allow-origin *
x-runtime 0.011667
Function that produces said log
local res, headers = request({ ... })
print('When out of function type is: ' ..type(res) .. '\n')
print('Desired response in string:')
print(res .. '\n')
resJson = cjson.decode(res)
print('\nAfter decode, type is: ' .. type(resJson) .. '\n')
pTable(resJson)
print('\nPrinting header\n')
pTable(headers)
pTable is just a function to output a table to stdout.
Thanks in advance
Posted function and routines are correct. The problem was located in my print table function, which I somehow had hardcoded my headers.
[
["Sender", "service#mydomain.com"],
["Date", "Sat, 19 Dec 201520:41:31 +0000"],
["X-Mailgun-Sid", "WyI0ZjRjNyIsICJyYWplZXZrbXh4eddHh4eDMzMzMzQHlhaG9vLmNvbSIsICJjNGExZiJd"],
["Received", "by luna.mailgun.net with HTTP; Sat, 19 Dec 2015 20:41:31+0000"],
["Message-Id", "<201512192024131.73374.12565#mydomain.com>"],
["Reply-To", "junky01#hotmail.com"],
["X-Mailgun-Skip-Verification", "false"],
["To", "John Myers <testxxxxxx33333#yahoo.com>"], ["From", "\"Inc.\" <service#mydomain.com>"],
["Subject", "Test subject"],
["Mime-Version", "1.0"],
["Content-Type",
["multipart/mixed", { "boundary": "e43d638b70f04a40889d14f4c8422953" } ]
]
]
When using JObject (VB.net), JObject.parse throws this error:
Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray. Path '', line 2, position 2.---- at Newtonsoft.Json.Linq.JObject.Load(JsonReader reader) at Newtonsoft.Json.Linq.JObject.Parse(String json)
But when I copy the above string into online Json viewers, they all seem to be parsing it fine.
Your JSON does not represent an object; it is an array (of arrays). Therefore, you cannot use JObject.Parse(). Instead, use JArray.Parse(), which can handle arrays, or use JToken.Parse(), which can handle either arrays or objects.
string json = #"
[
[""Sender"", ""service#mydomain.com""],
[""Date"", ""Sat, 19 Dec 201520:41:31 +0000""],
[""X-Mailgun-Sid"", ""WyI0ZjRjNyIsICJyYWplZXZrbXh4eddHh4eDMzMzMzQHlhaG9vLmNvbSIsICJjNGExZiJd""],
[""Received"", ""by luna.mailgun.net with HTTP; Sat, 19 Dec 2015 20:41:31+0000""],
[""Message-Id"", ""<201512192024131.73374.12565#mydomain.com>""],
[""Reply-To"", ""junky01#hotmail.com""],
[""X-Mailgun-Skip-Verification"", ""false""],
[""To"", ""John Myers <testxxxxxx33333#yahoo.com>""],
[""From"", ""\""Inc.\"" <service#mydomain.com>""],
[""Subject"", ""Test subject""],
[""Mime-Version"", ""1.0""],
[""Content-Type"",
[""multipart/mixed"", { ""boundary"": ""e43d638b70f04a40889d14f4c8422953"" } ]
]
]";
JArray rows = JArray.Parse(json);
foreach (JArray row in rows)
{
Console.WriteLine(string.Join(": ", row.Select(r => r.ToString())));
}
Fiddle: https://dotnetfiddle.net/VRs47S