Showing posts with label Web Development. Show all posts
Showing posts with label Web Development. Show all posts

Tuesday, February 23, 2021

HTTP Error Codes and REST APIs



HTTP response status codes indicate whether a specific HTTP request has been successfully completed. Responses are grouped in five classes: 1. Informational responses (100–199) 2. Successful responses (200–299) 3. Redirects (300–399) 4. Client errors (400–499) 5. Server errors (500–599) If you receive a response that is not in this list, it is a non-standard response, possibly custom to the server's software. Ref: developer.mozilla.org All HTTP response status codes are separated into five classes or categories. The first digit of the status code defines the class of response, while the last two digits do not have any classifying or categorization role. There are five classes defined by the standard: 1xx informational response – the request was received, continuing process 2xx successful – the request was successfully received, understood, and accepted 3xx redirection – further action needs to be taken in order to complete the request 4xx client error – the request contains bad syntax or cannot be fulfilled 5xx server error – the server failed to fulfil an apparently valid request Ref: en.wikipedia.org Some common error codes one must know: 401 Unauthorized Although the HTTP standard specifies "unauthorized", semantically this response means "unauthenticated". That is, the client must authenticate itself to get the requested response. 403 Forbidden The client does not have access rights to the content; that is, it is unauthorized, so the server is refusing to give the requested resource. Unlike 401, the client's identity is known to the server. 405 Method Not Allowed The request method is known by the server but has been disabled and cannot be used. For example, an API may forbid DELETE-ing a resource. The two mandatory methods, GET and HEAD, must never be disabled and should not return this error code. 415 Unsupported Media Type The media format of the requested data is not supported by the server, so the server is rejecting the request.

RESTful API Response Codes (used by Amazon Drive API)

The HTTP Status Codes used by the RESTful Amazon Drive API. HTTP Status Code --- Description 200 OK --- Successful. 201 Created --- Created. Status code '201' is important for REST APIs that are performing some action such as raising a ticket or logging something. 400 Bad Request --- Bad input parameter. Error message should indicate which one and why. 401 Unauthorized --- The client passed in the invalid Auth token. Client should refresh the token and then try again. 403 Forbidden --- * Customer doesn’t exist. * Application not registered. * Application try to access to properties not belong to an App. * Application try to trash/purge root node. * Application try to update contentProperties. * Operation is blocked (for third-party apps). * Customer account over quota. 404 Not Found --- Resource not found. 405 Method Not Allowed --- The resource doesn't support the specified HTTP verb. 409 Conflict --- Conflict. 411 Length Required --- The Content-Length header was not specified. 412 Precondition Failed --- Precondition failed. 429 Too Many Requests --- Too many request for rate limiting. 500 Internal Server Error --- Servers are not working as expected. The request is probably valid but needs to be requested again later. 503 Service Unavailable --- Service Unavailable. Ref: developer.amazon.com (Dated: 24 Feb 2021) Additional Notes In Europe, the NotFound project, created by multiple European organizations including Missing Children Europe and Child Focus, encourages site operators to add a snippet of code to serve customized 404 error pages which provide data about missing children. Ref: HTTP 404
Tags: Technology,Web Development,Web Scraping,

Tuesday, February 16, 2021

Getting a Web Server's Response Header Using Python



We have a Python code that will get the response headers for a website:

from datetime import datetime 
import requests

url = 'http://survival8.blogspot.com/'

x = requests.get(url)

print(x.headers)

curr_time = datetime.now()

# We also write our main HTML output to a file.
with open("s8_" + str(curr_time).replace(":", "_") + ".log", mode='w') as f:
    f.write(x.text)

The output of this code looks like as shown below:

(base) ~/Desktop$ python response_header_info.py 

{'Content-Type': 'text/html; charset=UTF-8', 'Expires': 'Tue, 16 Feb 2021 10:13:29 GMT', 'Date': 'Tue, 16 Feb 2021 10:13:29 GMT', 'Cache-Control': 'private, max-age=0', 'Last-Modified': 'Tue, 16 Feb 2021 08:54:25 GMT', 'ETag': 'W/"047a2cb250a2ad10a53227bf4085727f97833f5235788c95f99a149e4d1afa68"', 'Content-Encoding': 'gzip', 'X-Content-Type-Options': 'nosniff', 'X-XSS-Protection': '1; mode=block', 'Content-Length': '135818', 'Server': 'GSE'} 

Next we discuss some important Response Headers:

1: Response header
Ref: developer.mozilla.org

A response header is an HTTP header that can be used in an HTTP response and that doesn't relate to the content of the message. Response headers, like Age, Location or Server are used to give a more detailed context of the response.

Not all headers appearing in a response are categorized as response headers by the specification. For example, the Content-Length header is an Representation metadata header indicating the size of the body of the response message (and as an entity header in older versions of the specification). However, "conversationally" all headers are usually referred to as response headers in a response message.

The following shows a few response headers after a GET request. Note that strictly speaking, the Content-Encoding and Content-Type headers are entity header:

200 OK
Access-Control-Allow-Origin: *
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Mon, 18 Jul 2016 16:06:00 GMT
Etag: "c561c68d0ba92bbeb8b0f612a9199f722e3a621a"
Keep-Alive: timeout=5, max=997
Last-Modified: Mon, 18 Jul 2016 02:36:04 GMT
Server: Apache
Set-Cookie: mykey=myvalue; expires=Mon, 17-Jul-2017 16:06:00 GMT; Max-Age=31449600; Path=/; secure
Transfer-Encoding: chunked
Vary: Cookie, Accept-Encoding
X-Backend-Server: developer2.webapp.scl3.mozilla.com
X-Cache-Info: not cacheable; meta data too large
X-kuma-revision: 1085259
x-frame-options: DENY

###

2: 'Cache-Control': 'private'

Ref: developer.mozilla.org

Cacheability

Directives that define whether a response/request can be cached, where it may be cached, and whether it must be validated with the origin server before caching.

public
    The response may be stored by any cache, even if the response is normally non-cacheable.

private
    The response may be stored only by a browser's cache, even if the response is normally non-cacheable. If you mean to not store the response in any cache, use no-store instead. This directive is not effective in preventing caches from storing your response.

no-cache
    The response may be stored by any cache, even if the response is normally non-cacheable. However, the stored response MUST always go through validation with the origin server first before using it, therefore, you cannot use no-cache in-conjunction with immutable. If you mean to not store the response in any cache, use no-store instead. This directive is not effective in preventing caches from storing your response.

no-store
    The response may not be stored in any cache. Note that this will not prevent a valid pre-existing cached response being returned. Clients can set max-age=0 to also clear existing cache responses, as this forces the cache to revalidate with the server (no other directives have an effect when used with no-store). 

###

'Transfer-Encoding': 'chunked'

The Transfer-Encoding header specifies the form of encoding used to safely transfer the payload body to the user.

chunked
    Data is sent in a series of chunks. The Content-Length header is omitted in this case and at the beginning of each chunk you need to add the length of the current chunk in hexadecimal format, followed by '\r\n' and then the chunk itself, followed by another '\r\n'. The terminating chunk is a regular chunk, with the exception that its length is zero. It is followed by the trailer, which consists of a (possibly empty) sequence of entity header fields.

### 

'Content-Type': 'application/json; charset=utf-8'

Content-type: application/json; charset=utf-8 designates the content to be in JSON format, encoded in the UTF-8 character encoding.

### 

'Server': 'Private Server', 

The Server header describes the software used by the origin server that handled the request — that is, the server that generated the response.

Examples: 
  Server: Apache/2.4.1 (Unix)

Ref: developer.mozilla.org

### 

'jsonerror': 'true'

Nothing found about it.

###

'X-Frame-Options': 'SAMEORIGIN'

The X-Frame-Options HTTP response header can be used to indicate whether or not a browser should be allowed to render a page in a <frame>, <iframe>, <embed> or <object>. Sites can use this to avoid click-jacking attacks, by ensuring that their content is not embedded into other sites.

The added security is provided only if the user accessing the document is using a browser that supports X-Frame-Options.

There are two possible directives for X-Frame-Options:

X-Frame-Options: DENY
X-Frame-Options: SAMEORIGIN


SAMEORIGIN
    The page can only be displayed in a frame on the same origin as the page itself. The spec leaves it up to browser vendors to decide whether this option applies to the top level, the parent, or the whole chain, although it is argued that the option is not very useful unless all ancestors are also in the same origin (see bug 725490). Also see Browser compatibility for support details.

Ref: developer.mozilla.org

###

'Strict-Transport-Security': 'max-age=31536000', 

The HTTP Strict-Transport-Security response header (often abbreviated as HSTS) lets a web site tell browsers that it should only be accessed using HTTPS, instead of using HTTP.

max-age=<expire-time>
    The time, in seconds, that the browser should remember that a site is only to be accessed using HTTPS.

###

'X-UA-Compatible': 'IE=EmulateIE7'

Ref: docs.microsoft.com

Web developers can also specify a document mode by including instructions in a meta element or HTTP response header:

    Webpages that include a meta element (see [HTML5:2014]) with an http-equivalent value of X-UA-Compatible.

    Webpages that are served with an HTTP header named "X-UA-Compatible".


IE=EmulateIE7 ::
IE7 mode (if a valid <!DOCTYPE> declaration is present)
Quirks Mode (otherwise)

###

'X-Contet-Type-Options': 'nosniff'

Ref: developer.mozilla.org

The X-Content-Type-Options response HTTP header is a marker used by the server to indicate that the MIME types advertised in the Content-Type headers should not be changed and be followed. This is a way to opt out of MIME type sniffing, or, in other words, to say that the MIME types are deliberately configured.

This header was introduced by Microsoft in IE 8 as a way for webmasters to block content sniffing that was happening and could transform non-executable MIME types into executable MIME types. Since then, other browsers have introduced it, even if their MIME sniffing algorithms were less aggressive.

Starting with Firefox 72, the opting out of MIME sniffing is also applied to top-level documents if a Content-type is provided. This can cause HTML web pages to be downloaded instead of being rendered when they are served with a MIME type other than text/html. Make sure to set both headers correctly.

Site security testers usually expect this header to be set.

X-Content-Type-Options: nosniff

nosniff
    Blocks a request if the request destination is of type:

        "style" and the MIME type is not text/css, or
        "script" and the MIME type is not a JavaScript MIME type

    Enables Cross-Origin Read Blocking (CORB) protection for the MIME-types:

        text/html
        text/plain
        text/json, application/json or any other type with a JSON extension: */*+json
        text/xml, application/xml or any other type with an XML extension: */*+xml (excluding image/svg+xml)

###


'X-XSS-Protection': '1; mode=block'

Ref: developer.mozilla.org

The HTTP X-XSS-Protection response header is a feature of Internet Explorer, Chrome and Safari that stops pages from loading when they detect reflected cross-site scripting (XSS) attacks. Although these protections are largely unnecessary in modern browsers when sites implement a strong Content-Security-Policy that disables the use of inline JavaScript ('unsafe-inline'), they can still provide protections for users of older web browsers that don't yet support CSP.

X-XSS-Protection: 0
X-XSS-Protection: 1
X-XSS-Protection: 1; mode=block
X-XSS-Protection: 1; report=<reporting-uri>


1; mode=block
    Enables XSS filtering. Rather than sanitizing the page, the browser will prevent rendering of the page if an attack is detected.

###

Date

The Date general HTTP header contains the date and time at which the message was originated.

Ref: developer.mozilla.org

fetch('https://httpbin.org/get', {
    'headers': {
        'Date': (new Date()).toUTCString()
    }
})

Header type: General header

Tags: Technology, Web Scraping, Web Development

Friday, February 12, 2021

Debugger statement in JavaScript



The debugger statement stops the execution of JavaScript, and calls (if available) the debugging function.

Using the debugger statement has the same function as setting a breakpoint in the code.

Normally, you activate debugging in your browser with the F12 key, and select "Console" in the debugger menu.

Note: If no debugging is available, the debugger statement has no effect.

- - -

We have written this JS code in an HTML file:


<script>
function outer(){
    console.log("From outer")
    inner()
} 

function inner(){
    debugger;
    console.log("From inner")
    alert("Bye")
}
</script>

<body onload="outer()"> </body>



- - -

Following are the screenshots of "Firefox Debugger" when we run this code:

When we would press on "Play" button in "Debugger", it will end on the last "alert()" statement.

Sunday, October 4, 2020

Set up Google OAuth 2.0 Authentication For Blogger and Retrieve Blog Posts


Installation 
Blogger APIs Client Library for Python
CMD> pip install --upgrade google-api-python-client 
Ref: developers.google.com

(base) C:\Users\ashish\Desktop>pip install oauth2client

(base) C:\Users\ashish\Desktop\blogger>pip show google-api-python-client
Name: google-api-python-client
Version: 1.12.3
Summary: Google API Client Library for Python
Home-page: https://github.com/googleapis/google-api-python-client/
Author: Google LLC
Author-email: googleapis-packages@google.com
License: Apache 2.0
Location: d:\programfiles\anaconda3\lib\site-packages
Requires: six, google-auth-httplib2, google-auth, google-api-core, uritemplate, httplib2
Required-by: 

(base) C:\Users\ashish\Desktop\blogger>pip show oauth2client
Name: oauth2client
Version: 4.1.3
Summary: OAuth 2.0 client library
Home-page: http://github.com/google/oauth2client/
Author: Google Inc.
Author-email: jonwayne+oauth2client@google.com
License: Apache 2.0
Location: d:\programfiles\anaconda3\lib\site-packages
Requires: pyasn1, six, rsa, pyasn1-modules, httplib2
Required-by: 

==  ==  ==  ==  ==

Basic structure of the "client_secrets.json" is as written below:

Ref: GitHub

{
  "web": {
    "client_id": "[[INSERT CLIENT ID HERE]]",
    "client_secret": "[[INSERT CLIENT SECRET HERE]]",
    "redirect_uris": [],
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://accounts.google.com/o/oauth2/token"
  }
} 

Our "client_secrets.json" file looks like this:

{
  "installed":
  {
    "client_id": "0...9-a...z.apps.googleusercontent.com",
    "project_id": "banded...",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_secret": "2.....v",
    "redirect_uris": ["urn:ietf:wg:oauth:2.0:oob", "http://localhost"]
  }
} 

==  ==  ==  ==  ==

About authorization protocols 
Your application must use OAuth 2.0 to authorize requests. No other authorization protocols are supported. If your application uses Google Sign-In, some aspects of authorization are handled for you.

You can create "OAuth Client ID" from here: developers.google.com

You can also create a new "Project". We will select already created "My Project". We will select the "OAuth Client" as "Desktop App":
== == == == == Error if the 'client_secrets.json' file is not present alongside "blogger.py": (base) C:\Users\ashish\Desktop>python blogger.py The client secrets were invalid: ('Error opening file', 'client_secrets.json', 'No such file or directory', 2) WARNING: Please configure OAuth 2.0 To make this sample run you will need to populate the client_secrets.json file found at: client_secrets.json with information from the APIs Console [ https://code.google.com/apis/console ]. == == == == == Error on placing "empty (0KB)" file named "client_secrets.json": (base) C:\Users\ashish\Desktop\blogger>python blogger_v2.py Traceback (most recent call last): File "blogger_v2.py", line 43, in [module] main(sys.argv) File "blogger_v2.py", line 12, in main scope='https://www.googleapis.com/auth/blogger') File "D:\programfiles\Anaconda3\lib\site-packages\googleapiclient\sample_tools.py", line 88, in init client_secrets, scope=scope, message=tools.message_if_missing(client_secrets) File "D:\programfiles\Anaconda3\lib\site-packages\oauth2client\_helpers.py", line 133, in positional_wrapper return wrapped(*args, **kwargs) File "D:\programfiles\Anaconda3\lib\site-packages\oauth2client\client.py", line 2135, in flow_from_clientsecrets cache=cache) File "D:\programfiles\Anaconda3\lib\site-packages\oauth2client\clientsecrets.py", line 165, in loadfile return _loadfile(filename) File "D:\programfiles\Anaconda3\lib\site-packages\oauth2client\clientsecrets.py", line 122, in _loadfile obj = json.load(fp) File "D:\programfiles\Anaconda3\lib\json\__init__.py", line 296, in load parse_constant=parse_constant, object_pairs_hook=object_pairs_hook, **kw) File "D:\programfiles\Anaconda3\lib\json\__init__.py", line 348, in loads return _default_decoder.decode(s) File "D:\programfiles\Anaconda3\lib\json\decoder.py", line 337, in decode obj, end = self.raw_decode(s, idx=_w(s, 0).end()) File "D:\programfiles\Anaconda3\lib\json\decoder.py", line 355, in raw_decode raise JSONDecodeError("Expecting value", s, err.value) from None json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0) == == == == == Before authentication: C:\Users\ashish\Desktop\blogger>tree /f C:. blogger_v1.py client_secrets.json No subfolders exist After authentication (the authentication steps are shown below), a 'blogger.dat' file is created: C:\Users\ashish\Desktop\blogger>tree /f C:. blogger.dat blogger_v1.py client_secrets.json No subfolders exist == == == == == When we run the application the application the first time, it opens the "Google's User Authentication" window to give access to the application to the Blogger for a Google account by logging into the respective Google Account.
Last prompt will ask you to confirm your choice:
Once the sign-in is complete it opens a Broswer Window (our browser is Chrome) as shown below:
Message: Application flow has been completed == == == == == CODE V1 #!/usr/bin/env python # -*- coding: utf-8 -*- """Simple command-line sample for Blogger. Command-line application that retrieves the users blogs and posts. Usage: $ python blogger.py You can also get help on all the command-line flags the program understands by running: $ python blogger.py --help To get detailed log output run: $ python blogger.py --logging_level=DEBUG """ from __future__ import print_function import sys from oauth2client import client from googleapiclient import sample_tools def main(argv): # Authenticate and construct service. service, flags = sample_tools.init( argv, 'blogger', 'v3', __doc__, __file__, scope='https://www.googleapis.com/auth/blogger') try: users = service.users() # Retrieve this user's profile information thisuser = users.get(userId='self').execute() print('This user\'s display name is: %s' % thisuser['displayName']) blogs = service.blogs() # Retrieve the list of Blogs this user has write privileges on thisusersblogs = blogs.listByUser(userId='self').execute() for blog in thisusersblogs['items']: print('The blog named \'%s\' is at: %s' % (blog['name'], blog['url'])) posts = service.posts() # List the posts for each blog this user has for blog in thisusersblogs['items']: print('The posts for %s:' % blog['name']) request = posts.list(blogId=blog['id']) while request != None: posts_doc = request.execute() if 'items' in posts_doc and not (posts_doc['items'] is None): for post in posts_doc['items']: print(' %s (%s)' % (post['title'], post['url'])) request = posts.list_next(request, posts_doc) except client.AccessTokenRefreshError: print ('The credentials have been revoked or expired, please re-run' 'the application to re-authorize') if __name__ == '__main__': main(sys.argv) == == == == == (base) CMD>python blogger_v1.py D:\programfiles\Anaconda3\lib\site-packages\oauth2client\_helpers.py:255: UserWarning: Cannot access blogger.dat: No such file or directory warnings.warn(_MISSING_FILE_MESSAGE.format(filename)) Your browser has been opened to visit: https://accounts.google.com/o/oauth2/auth?client_id=1... If your browser is on a different machine then exit and re-run this application with the command-line parameter --noauth_local_webserver Authentication successful. This user's display name is: Ashish Jain The blog named 'survival8' is at: http://survival8.blogspot.com/ The blog named 'ashish' is at: http://ashish.blogspot.com/ The posts for survival8: Difficult Conversations. How to Discuss What Matters Most (D. Stone, B. Patton, S. Heen, 2010) (http://survival8.blogspot.com/2020/09/douglas-stone-b-patton-s-heen-difficult.html) ... Is having a water fountain a sensible thing to do? (http://survival8.blogspot.com/2016/11/is-having-water-fountain-sensible-thing_21.html) The posts for ashish: ... == == == == == 'Cloud Resource Manager' Screenshot Showing Our Usage
== == == == == References GitHub % Blogger: google-api-python-client % blogger.py Google API Console % Google API Console % Dashboard % Cloud Resource Manager Documentation % Blogger APIs Client Library for Python % Blogger API: Using the API % Blogger API v3 (Instance Methods) % Blogger API v3 . posts (Instance Methods)

Monday, September 21, 2020

12 'ECMAScript 6' Tips (Sep 2020)


1. clear() This function clears the 'output pane' in 'JS console'. 2. You can define an array as follows: var arr = [ 'elem a', 'elem b', 'elem c' ] 'Shift + Enter' lets you add a line-feed in the code in Firefox JS Console. 3. "arr.length" Will return you '3'. 4. Get unique elements from an Array: With ES6: var a = ['a', 'b', 'c', 'c'] console.log([...new Set(a)]) Out: ["a", "b", "c"] OR Array.from(new Set(a)); OR list = list.filter((x, i, a) => a.indexOf(x) === i) 5. To concatenate two arrays: a = ['a', 'b', 'c', 'c'] b = ['d', 'e'] console.log(a.concat(b)) Out: ["a", "b", "c", "c", "d", "e"] 6. ES6 based counter: var cntr = 0; function myFunction() { console.log(arr[cntr]); cntr++; } 7. Add an element to "DOM body" before other child elements. b = document.querySelector("body") theKid = document.createElement("p"); theKid.innerHTML = '<button onclick="myFunction(chatroom_names_kenya)" style="position: sticky !important;top: 0;z-index: 999;">Submit</button>'; b.insertBefore(theKid, b.firstChild) 8. Ways to access an element of HTML DOM using JavaScript: Gets Selector Syntax Method ID #demo getElementById() Class .demo getElementsByClassName() Tag demo getElementsByTagName() Selector (single) querySelector() Selector (all) querySelectorAll() About Query Selectors: It is JavaScript's method of accessing the DOM with CSS selectors. 9. Finding HTML Elements by HTML Object Collections: var x = document.forms["frm1"]; var text = ""; var i; for (i = 0; i < x.length; i++) { text += x.elements[i].value + "<br>"; } document.getElementById("demo").innerHTML = text; The following HTML objects (and object collections) are also accessible: 1. document.anchors 2. document.body 3. document.documentElement 4. document.embeds 5. document.forms 6. document.head 7. document.images 8. document.links 9. document.scripts 10. document.title 10. Identifying type of a variable: The typeof operator returns the type of a variable, object, function or expression: typeof "John" // Returns string typeof 3.14 // Returns number typeof NaN // Returns number typeof false // Returns boolean typeof [1, 2, 3, 4] // Returns object typeof {name:'John', age:34} // Returns object typeof new Date() // Returns object typeof function () {} // Returns function typeof myCar // Returns undefined (if myCar is not declared) typeof null // Returns object Please observe: The data type of NaN is number The data type of an array is object The data type of a date is object The data type of null is object The data type of an undefined variable is undefined 11. The instanceof Operator The instanceof operator returns true if the specified object is an instance of the specified object: var cars = ["Saab", "Volvo", "BMW"]; cars instanceof Array; // Returns true cars instanceof Object; // Returns true cars instanceof String; // Returns false cars instanceof Number; // Returns false 12. Spread Operator Spread operator allows an iterable to expand in places where 0+ arguments are expected. It is mostly used in the variable array where there is more than 1 values are expected. It allows us the privilege to obtain a list of parameters from an array. Syntax of Spread operator is same as "Rest parameter" but it works completely opposite of it. 12.1 // spread operator doing the concat job let arr = [1,2,3]; let arr2 = [4,5]; arr = [...arr,...arr2]; console.log(arr); // [ 1, 2, 3, 4, 5 ] 12.2 // spread operator for copying let arr = ['a','b','c']; let arr2 = [...arr]; console.log(arr); // [ 'a', 'b', 'c' ] arr2.push('d'); //inserting an element at the end of arr2 console.log(arr2); // [ 'a', 'b', 'c', 'd' ] console.log(arr); // [ 'a', 'b', 'c' ]

Sunday, September 20, 2020

Web Security - Prevent Website from opening in an IFrame


For Web Security, prevent website from opening in an IFrame as 'WhatsApp Web' does.

<div>
    <p>WhatsApp Error: Prevention from opening WhatsApp Web in an IFrame.</p>
</div>
<iframe src="https://web.whatsapp.com/" title="My WhatsApp" width=900 height=400></iframe> 

View in Mozilla Firefox: