def testDefaultExceptionHandler(self): """Ensures exception handles swallows (retries)""" mock_http_content = 'content'.encode('utf8') for exception_arg in (http_client.BadStatusLine('line'), http_client.IncompleteRead('partial'), http_client.ResponseNotReady(), socket.error(), socket.gaierror(), httplib2.ServerNotFoundError(), ValueError(), oauth2client.client.HttpAccessTokenRefreshError( status=503), exceptions.RequestError(), exceptions.BadStatusCodeError({'status': 503}, mock_http_content, 'url'), exceptions.RetryAfterError({'status': 429}, mock_http_content, 'url', 0)): retry_args = http_wrapper.ExceptionRetryArgs( http={'connections': {}}, http_request=_MockHttpRequest(), exc=exception_arg, num_retries=0, max_retry_wait=0, total_wait_sec=0) # Disable time.sleep for this handler as it is called with # a minimum value of 1 second. with patch('time.sleep', return_value=None): http_wrapper.HandleExceptionsAndRebuildHttpConnections( retry_args)
def test__request(self, http_request_patched): ''' Test error handling. ''' url = 'www.testcase.com' handler = APIHandlerHTTP() resp = {'status': 200} content = '{}' http_request_patched.return_value = resp, content result = handler._request(url) self.assertEqual(result, {}) # Responded with invalid JSON. content = 'invalid JSON' http_request_patched.return_value = resp, content self.assertRaises(simplejson.JSONDecodeError, handler._request, url) content = "{error: 'Server error.'}" resp['status'] = 400 # Bad Request self.assertRaises(InvalidAPIInputError, handler._request, url) resp['status'] = 401 # Unauthorised self.assertRaises(APIConnectionError, handler._request, url) resp['status'] = 404 # Not Found self.assertRaises(NotFoundError, handler._request, url) resp['status'] = 500 # Internal Server Error self.assertRaises(UnknownAPIError, handler._request, url) resp['status'] = 200 http_request_patched.side_effect = socket.error() self.assertRaises(APIConnectionError, handler._request, url) http_request_patched.side_effect = httplib2.ServerNotFoundError() self.assertRaises(APIConnectionError, handler._request, url)
def _map_exception(e): """Maps an exception from urlib3 to httplib2.""" if isinstance(e, urllib3.exceptions.MaxRetryError): if not e.reason: return e e = e.reason message = e.args[0] if e.args else '' if isinstance(e, urllib3.exceptions.ResponseError): if 'too many redirects' in message: return httplib2.RedirectLimit(message) if isinstance(e, urllib3.exceptions.NewConnectionError): if ('Name or service not known' in message or 'nodename nor servname provided, or not known' in message): return httplib2.ServerNotFoundError('Unable to find hostname.') if 'Connection refused' in message: return socket.error((errno.ECONNREFUSED, 'Connection refused')) if isinstance(e, urllib3.exceptions.DecodeError): return httplib2.FailedToDecompressContent( 'Content purported as compressed but not uncompressable.', httplib2.Response({'status': 500}), '') if isinstance(e, urllib3.exceptions.TimeoutError): return socket.timeout('timed out') if isinstance(e, urllib3.exceptions.SSLError): return ssl.SSLError(*e.args) return e
def request(self, *args, **kwargs): if not self.num_errors: return httplib2.Response(self.success_json), self.success_data else: self.num_errors -= 1 if self.num_errors == 1: # initial == 2 raise ssl.SSLError() if self.num_errors == 3: # initial == 4 raise httplib2.ServerNotFoundError() else: # initial != 2,4 if self.num_errors == 2: # first try a broken pipe error (#218) ex = socket.error() ex.errno = socket.errno.EPIPE else: # Initialize the timeout error code to the platform's error code. try: # For Windows: ex = socket.error() ex.errno = socket.errno.WSAETIMEDOUT except AttributeError: # For Linux/Mac: if PY3: ex = socket.timeout() else: ex = socket.error() ex.errno = socket.errno.ETIMEDOUT # Now raise the correct error. raise ex
def testCantConnectBadURL(self): self.http_request_mock.side_effect = httplib2.ServerNotFoundError expected_result = CheckFailResult( ['https://badurl.badurl'], exception=httplib2.ServerNotFoundError()) actual_result, actual_fixer = self.reachability_checker.Check( ['https://badurl.badurl']) self.AssertResultEqual(expected_result, actual_result) self.assertEqual(CHANGE_PROXY, actual_fixer)
def test_googleapiclient_connection_error(self): error = httplib2.ServerNotFoundError('Test error') firebase_error = _gapic_utils.handle_googleapiclient_error(error) assert isinstance(firebase_error, exceptions.UnavailableError) assert str( firebase_error) == 'Failed to establish a connection: Test error' assert firebase_error.cause is error assert firebase_error.http_response is None
async def test_update_error(hass, google_service): """Test that the calendar handles a server error.""" google_service.return_value.get = Mock( side_effect=httplib2.ServerNotFoundError("unit test")) assert await async_setup_component(hass, "google", {"google": GOOGLE_CONFIG}) await hass.async_block_till_done() state = hass.states.get(TEST_ENTITY) assert state.name == TEST_ENTITY_NAME assert state.state == "off"
def confirm_account(self, token): """Verify that the provided token is for this user's id.""" s = Serializer(current_app.config['SECRET_KEY']) try: data = s.loads(token) except (BadSignature, SignatureExpired): return None # change compare with str if str(data.get('confirm')) != str(self.id): return None # TODO: send to backend for updating confirm field url = backend_url+'confirm' data = { 'token': token, 'id': data.get('confirm') } try: h = httplib2.Http(".cache") (resp, content) = h.request(url, "POST", body=urllib.parse.urlencode(data), headers=backend_headers) r = loads(content) logger.info(r) if resp.status in (404,405) or resp.status < 200: raise httplib2.ServerNotFoundError('restful api uri not found. {}'.format(r['message'])) else: if r['status'] == 'fail': return None else: # for login info user = User( id = r['data']['user_id'], username = r['data']['username'], # email = maked_email, email = r['data']['email'], token = r['data']['token'], is_active = r['data']['is_active'], is_authenticated = True, confirmed = r['data']['confirmed'] ) return user except Exception as e: logger.error(e) # flash('oops...'+'{'+str(e)+'}', 'form-error') return None """
def register(): """Register a new user, and send them a confirmation email.""" form = RegistrationForm() if form.validate_on_submit(): # add youngtip using Frest backend url = backend_url + 'users' data = { 'email': form.email.data, 'username': form.nickname.data, 'password': form.password.data } try: h = httplib2.Http(".cache") (resp, content) = h.request(url, "POST", body=urllib.parse.urlencode(data), headers=backend_headers) r = loads(content) logger.info(r) if resp.status in (404, 405) or resp.status < 200: raise httplib2.ServerNotFoundError('restful api uri not found') else: if r['status'] == 'fail': flash(r['field'] + ' ' + r['message'], 'form-error') else: # for send mail user = User(id=r['id'], username=form.nickname.data) confirm_token = user.generate_confirmation_token() confirm_link = url_for('account.confirm', token=confirm_token, _external=True) # TODO: RQ get_queue().enqueue(send_email, recipient=form.email.data, subject='Confirm Your Account', template='account/email/confirm', user=user, confirm_link=confirm_link) flash( 'A confirmation link has been sent to {}.'.format( form.email.data), 'warning') return redirect(url_for('main.index')) # except requests.exceptions.RequestException as e: except Exception as e: logger.error(e) flash('oops...' + '{' + str(e) + '}', 'form-error') return render_template('account/register.html', form=form)
async def test_http_event_api_failure(hass, hass_client, calendar_resource, component_setup): """Test the Rest API response during a calendar failure.""" assert await component_setup() client = await hass_client() calendar_resource.side_effect = httplib2.ServerNotFoundError("unit test") response = await client.get(upcoming_event_url()) assert response.status == HTTPStatus.OK # A failure to talk to the server results in an empty list of events events = await response.json() assert events == []
async def test_scan_calendar_error( hass, calendar_resource, component_setup, test_api_calendar, ): """Test that the calendar update handles a server error.""" with patch( "homeassistant.components.google.api.google_discovery.build", side_effect=httplib2.ServerNotFoundError("unit test"), ): assert await component_setup() assert not hass.states.get(TEST_ENTITY)
def reset_password_request(): """Respond to existing user's request to reset their password.""" form = RequestResetPasswordForm() if form.validate_on_submit(): # TODOO: call to restful url = backend_url + 'auth' data = {'email': form.email.data} try: h = httplib2.Http(".cache") (resp, content) = h.request(url, "PUT", body=urllib.parse.urlencode(data), headers=backend_headers) r = loads(content) logger.info(r) if resp.status in (404, 405) or resp.status < 200: raise httplib2.ServerNotFoundError('restful api uri not found') else: if r['status'] == 'fail': flash(r['message'], 'form-error') else: # for send mail user = User(id=r['data']['id'], username=r['data']['username']) token = user.generate_password_reset_token() # reset token reset_link = url_for('account.reset_password', token=token, _external=True) get_queue().enqueue( send_email, recipient=form.email.data, subject='Reset Your Password', template='account/email/reset_password', user=user, reset_link=reset_link, next=request.args.get('next')) flash( 'A password reset link has been sent to {}.'.format( form.email.data), 'warning') return redirect(url_for('account.login')) except Exception as e: logger.error(e) flash('oops...' + '{' + str(e) + '}', 'form-error') return render_template('account/reset_password.html', form=form)
def _conn_request(self, conn, request_uri, method, body, headers): for i in range(2): try: if conn.sock is None: conn.connect() conn.request(method, request_uri, body, headers) except socket.timeout: raise except socket.gaierror: conn.close() raise httplib2.ServerNotFoundError( "Unable to find the server at %s" % conn.host) except httplib2.ssl_SSLError: conn.close() raise except socket.error as e: conn.close() raise except http.client.HTTPException: conn.close() raise try: response = conn.getresponse() except http.client.BadStatusLine: print("retry bad line") conn.close() conn.connect() continue except (socket.error, http.client.HTTPException): raise else: content = "" if method == "HEAD": response.close() else: buf = StringIO() while 1: data = response.read(CHUNK_SIZE) if not data: break buf.write(data) runHook("httpRecv", len(data)) content = buf.getvalue() response = httplib2.Response(response) if method != "HEAD": content = httplib2._decompressContent(response, content) return (response, content)
async def test_http_event_api_failure(hass, hass_client, google_service): """Test the Rest API response during a calendar failure.""" google_service.return_value.get = Mock( side_effect=httplib2.ServerNotFoundError("unit test")) assert await async_setup_component(hass, "google", {"google": GOOGLE_CONFIG}) await hass.async_block_till_done() start = dt_util.now().isoformat() end = (dt_util.now() + dt_util.dt.timedelta(minutes=60)).isoformat() client = await hass_client() response = await client.get( f"/api/calendars/{TEST_ENTITY}?start={start}&end={end}") assert response.status == HTTPStatus.OK # A failure to talk to the server results in an empty list of events events = await response.json() assert events == []
def testAuthNoMetadataServer(self): desired_scopes = [ 'https://www.googleapis.com/auth/compute', 'https://www.googleapis.com/auth/devstorage.full_control', ] metadata = mock_metadata.MockMetadata() metadata.ExpectIsPresent(False) oauth2_multistore_file.get_credential_storage = ( self.MockGetCredentialStorage) gce_cred = AuthHelperTest.MockCred( httplib2.ServerNotFoundError('metadata server not found')) cred = auth_helper.GetCredentialFromStore( desired_scopes, metadata=metadata, oauth2_gce=AuthHelperTest.MockOauth2ClientGce(gce_cred)) self.assertNotEquals(gce_cred, cred) self.assertEquals(0, cred.calls)
def change_password(): """Change an existing user's password.""" form = ChangePasswordForm() if form.validate_on_submit(): url = backend_url + 'auth/reset_password' backend_authed_headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json', 'Authorization': 'bearer ' + current_user.token } data = { 'email': current_user.email, 'old_password': form.old_password.data, 'new_password': form.new_password.data } try: h = httplib2.Http(".cache") (resp, content) = h.request(url, "PUT", body=urllib.parse.urlencode(data), headers=backend_authed_headers) r = loads(content) logger.info(r) if resp.status in (404, 405) or resp.status < 200: raise httplib2.ServerNotFoundError('restful api uri not found') else: if r['status'] == 'fail': flash(r['message'], 'form-error') else: logout_user() flash('Your password has been updated.', 'form-success') flash( 'You have been logged out. relogin again with new email', 'info') return redirect(url_for('account.login')) except Exception as e: logger.error(e) flash('oops...' + '{' + str(e) + '}', 'form-error') return render_template('account/manage.html', form=form)
def _conn_request(self, conn, request_uri, method, body, headers): # pylint: disable=too-many-statements try: if hasattr(conn, 'sock') and conn.sock is None: conn.connect() conn.request(method, request_uri, body, headers) except socket.timeout: raise except socket.gaierror: conn.close() raise httplib2.ServerNotFoundError('Unable to find the server at %s' % conn.host) except httplib2.ssl.SSLError: conn.close() raise except socket.error as e: err = 0 if hasattr(e, 'args'): err = getattr(e, 'args')[0] else: err = e.errno if err == httplib2.errno.ECONNREFUSED: # Connection refused raise except http_client.HTTPException: conn.close() raise try: response = conn.getresponse() except (socket.error, http_client.HTTPException): conn.close() raise else: content = '' if method == 'HEAD': conn.close() else: content = response.read() response = httplib2.Response(response) if method != 'HEAD': # pylint: disable=protected-access content = httplib2._decompressContent(response, content) return (response, content)
def _conn_request(self, conn, request_uri, method, body, headers): i = 0 seen_bad_status_line = False while i < httplib2.RETRIES: i += 1 try: if hasattr(conn, 'sock') and conn.sock is None: conn.connect() conn.request(method, request_uri, body, headers) except socket.timeout: raise except socket.gaierror: conn.close() raise httplib2.ServerNotFoundError( 'Unable to find the server at %s' % conn.host) except httplib2.ssl_SSLError: conn.close() raise except socket.error, e: err = 0 if hasattr(e, 'args'): err = getattr(e, 'args')[0] else: err = e.errno if err == httplib2.errno.ECONNREFUSED: # Connection refused raise except httplib.HTTPException: # Just because the server closed the connection doesn't apparently mean # that the server didn't send a response. if hasattr(conn, 'sock') and conn.sock is None: if i < httplib2.RETRIES - 1: conn.close() conn.connect() continue else: conn.close() raise if i < httplib2.RETRIES - 1: conn.close() conn.connect() continue
def reset_password(token): """Reset an existing user's password.""" form = ResetPasswordForm() if form.validate_on_submit(): # TODOO: call to restful url = backend_url + 'auth/reset_password' data = { 'email': form.email.data, 'new_password': form.new_password.data } if check_reset_password_token(token) is None: flash('The password reset link is invalid or has expired.', 'form-error') # return redirect(url_for('main.index')) # not working, why? else: try: h = httplib2.Http(".cache") (resp, content) = h.request(url, "POST", body=urllib.parse.urlencode(data), headers=backend_headers) r = loads(content) logger.info(r) if resp.status in (404, 405) or resp.status < 200: raise httplib2.ServerNotFoundError( 'restful api uri not found') else: if r['status'] == 'fail': flash(r['message'], 'form-error') else: flash('Your password has been updated.', 'form-success') return redirect(url_for('account.login')) except Exception as e: logger.error(e) flash('oops...' + '{' + str(e) + '}', 'form-error') return render_template('account/reset_password.html', form=form)
def _conn_request(self, conn, request_uri, method, body, headers): try: if hasattr(conn, 'sock') and conn.sock is None: conn.connect() conn.request(method, request_uri, body, headers) except socket.timeout: raise except socket.gaierror: conn.close() raise httplib2.ServerNotFoundError( 'Unable to find the server at %s' % conn.host) except httplib2.ssl_SSLError: conn.close() raise except socket.error, e: err = 0 if hasattr(e, 'args'): err = getattr(e, 'args')[0] else: err = e.errno if err == httplib2.errno.ECONNREFUSED: # Connection refused raise
def _conn_request(self, conn, request_uri, method, body, headers): for i in range(2): try: if conn.sock is None: conn.connect() conn.request(method, request_uri, body, headers) except socket.timeout: raise except socket.gaierror: conn.close() raise httplib2.ServerNotFoundError( "Unable to find the server at %s" % conn.host) except httplib2.ssl_SSLError: conn.close() raise except socket.error, e: err = 0 if hasattr(e, 'args'): err = getattr(e, 'args')[0] else: err = e.errno if err == errno.ECONNREFUSED: # Connection refused raise except httplib.HTTPException: # Just because the server closed the connection doesn't apparently mean # that the server didn't send a response. if conn.sock is None: if i == 0: conn.close() conn.connect() continue else: conn.close() raise if i == 0: conn.close() conn.connect() continue pass
async def test_update_error(hass, calendar_resource, component_setup, test_api_calendar): """Test that the calendar update handles a server error.""" now = dt_util.now() with patch("homeassistant.components.google.api.google_discovery.build" ) as mock: mock.return_value.calendarList.return_value.list.return_value.execute.return_value = { "items": [test_api_calendar] } mock.return_value.events.return_value.list.return_value.execute.return_value = { "items": [{ **TEST_EVENT, "start": { "dateTime": (now + datetime.timedelta(minutes=-30)).isoformat() }, "end": { "dateTime": (now + datetime.timedelta(minutes=30)).isoformat() }, }] } assert await component_setup() state = hass.states.get(TEST_ENTITY) assert state.name == TEST_ENTITY_NAME assert state.state == "on" # Advance time to avoid throttling now += datetime.timedelta(minutes=30) with patch( "homeassistant.components.google.api.google_discovery.build", side_effect=httplib2.ServerNotFoundError("unit test"), ), patch("homeassistant.util.utcnow", return_value=now): async_fire_time_changed(hass, now) await hass.async_block_till_done() # No change state = hass.states.get(TEST_ENTITY) assert state.name == TEST_ENTITY_NAME assert state.state == "on" # Advance time beyond update/throttle point now += datetime.timedelta(minutes=30) with patch("homeassistant.components.google.api.google_discovery.build" ) as mock, patch("homeassistant.util.utcnow", return_value=now): mock.return_value.events.return_value.list.return_value.execute.return_value = { "items": [{ **TEST_EVENT, "start": { "dateTime": (now + datetime.timedelta(minutes=30)).isoformat() }, "end": { "dateTime": (now + datetime.timedelta(minutes=60)).isoformat() }, }] } async_fire_time_changed(hass, now) await hass.async_block_till_done() # State updated state = hass.states.get(TEST_ENTITY) assert state.name == TEST_ENTITY_NAME assert state.state == "off"
def login(): """Log in an existing user.""" form = LoginForm() if form.validate_on_submit(): # TODO: requests error handling url = backend_url + 'auth' data = {'email': form.email.data, 'password': form.password.data} try: #processing start start_time = time.time() h = httplib2.Http(".cache") (resp, content) = h.request(url, "POST", body=urllib.parse.urlencode(data), headers=backend_headers) r = loads(content) logger.info(r) end_time = time.time() logger.info('login time >> ' + str(end_time - start_time)) if resp.status in (404, 405) or resp.status < 200: raise httplib2.ServerNotFoundError( 'restful api uri not found. {}'.format(r['message'])) else: if r['status'] == 'fail': flash(r['message'], 'form-error') else: # more consider """ maked_email = '' index_email = str(r_user['email']).index('@') for i in range(0,index_email): if i ==0: maked_email = str(r_user['email'])[0:1] else: maked_email = maked_email+'*' maked_email = maked_email+str(r_user['email'])[index_email:] """ # for login info user = User( id=r['data']['user_id'], username=r['data']['username'], # email = maked_email, email=r['data']['email'], token=r['data']['token'], is_active=r['data']['is_active'], is_authenticated=True, confirmed=r['data']['confirmed']) # using redis """ redis_store.set(r.json()['data']['user_id'], pickle.dumps(user)) redis_store.expire(r.json()['data']['user_id'], redis_ttl) # set expire key, 6hr """ # using cookie """ resp = make_response(redirect(request.args.get('next') or url_for('main.index'))) resp.set_cookie('username', 'the username') return resp """ login_user(user, form.remember_me.data) flash('You are now logged in. Welcome back!', 'success') return redirect( request.args.get('next') or url_for('main.index')) except Exception as e: logger.error(e) flash('oops...' + '{' + str(e) + '}', 'form-error') return render_template('account/login.html', form=form)
def change_email_request(): """Respond to existing user's request to change their email.""" form = ChangeEmailForm() if form.validate_on_submit(): # TODO : call rest url = backend_url + 'users/me' backend_authed_headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json', 'Authorization': 'bearer ' + current_user.token } data = { 'change_email': form.change_email.data, 'changeEmailPassword': form.changeEmailPassword.data } try: start_time = time.time() h = httplib2.Http(".cache") (resp, content) = h.request(url, "PUT", body=urllib.parse.urlencode(data), headers=backend_authed_headers) r = loads(content) logger.info(r) end_time = time.time() logger.info('change email start time5 >> ' + str(end_time - start_time)) if resp.status in (404, 405) or resp.status < 200: raise httplib2.ServerNotFoundError( 'restful api uri not found. {}'.format(r['message'])) else: if r['status'] == 'fail': if r['field'] == 'changeEmailPassword': r['field'] = 'Password' flash(r['field'] + ' ' + r['message'], 'form-error') else: new_email = form.change_email.data token = current_user.generate_email_change_token(new_email) change_email_link = url_for('account.change_email', token=token, _external=True) get_queue().enqueue( send_email, recipient=new_email, subject='Confirm Your New Email', template='account/email/change_email', # current_user is a LocalProxy, we want the underlying user # object user=current_user._get_current_object(), change_email_link=change_email_link) logout_user() flash( 'A confirmation link has been sent to {}.'.format( new_email), 'warning') flash( 'You have been logged out. relogin again with new email', 'info') return redirect(url_for('main.index')) except Exception as e: flash('oops...' + '{' + str(e) + '}', 'form-error') return render_template('account/manage.html', form=form)
def testIsGCEServerNotFound(self): self.mock_http.request.side_effect = httplib2.ServerNotFoundError() self.assertFalse(oauth2_client._IsGCE()) self.mock_http.request.assert_called_once_with( oauth2_client.METADATA_SERVER)
def _conn_request(self, conn, request_uri, method, body, headers): try: if hasattr(conn, 'sock') and conn.sock is None: conn.connect() conn.request(method, request_uri, body, headers) except socket.timeout: raise except socket.gaierror: conn.close() raise httplib2.ServerNotFoundError('Unable to find the server at %s' % conn.host) except httplib2.ssl.SSLError: conn.close() raise except socket.error as e: err = 0 if hasattr(e, 'args'): err = getattr(e, 'args')[0] else: err = e.errno if err == httplib2.errno.ECONNREFUSED: # Connection refused raise except http_client.HTTPException: # Just because the server closed the connection doesn't apparently mean # that the server didn't send a response. conn.close() raise try: response = conn.getresponse() except (socket.error, http_client.HTTPException) as e: conn.close() raise else: content = '' if method == 'HEAD': conn.close() response = httplib2.Response(response) elif method == 'GET' and response.status in (http_client.OK, http_client.PARTIAL_CONTENT): content_length = None if hasattr(response, 'msg'): content_length = response.getheader('content-length') http_stream = response bytes_read = 0 while True: new_data = http_stream.read(TRANSFER_BUFFER_SIZE) if new_data: if self.stream is None: raise apitools_exceptions.InvalidUserInputError( 'Cannot exercise HttpWithDownloadStream with no stream') text_util.write_to_fd(self.stream, new_data) bytes_read += len(new_data) else: break if (content_length is not None and long(bytes_read) != long(content_length)): # The input stream terminated before we were able to read the # entire contents, possibly due to a network condition. Set # content-length to indicate how many bytes we actually read. self._logger.log( logging.DEBUG, 'Only got %s bytes out of content-length %s ' 'for request URI %s. Resetting content-length to match ' 'bytes read.', bytes_read, content_length, request_uri) # Failing to delete existing headers before setting new values results # in the header being set twice, see https://docs.python.org/3/library/email.compat32-message.html#email.message.Message.__setitem__. # This trips apitools up when executing a retry, so the line below is # essential: del response.msg['content-length'] response.msg['content-length'] = str(bytes_read) response = httplib2.Response(response) else: # We fall back to the current httplib2 behavior if we're # not processing download bytes, e.g., it's a redirect, an # oauth2client POST to refresh an access token, or any HTTP # status code that doesn't include object content. content = response.read() response = httplib2.Response(response) # pylint: disable=protected-access content = httplib2._decompressContent(response, content) return (response, content)